blob: a537653e801c3496a46c4aae3297434d26827d5b [file] [log] [blame]
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.1.2, mkdocs-material-7.1.5">
<title>Picto - Epsilon</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.bde7dde4.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.ef6f36e2.min.css">
<meta name="theme-color" content="#000000">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
<style>:root{--md-text-font-family:"Roboto";--md-code-font-family:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../assets/stylesheets/mermaid.css">
<link rel="stylesheet" href="../../assets/javascript/google-code-prettify/prettify.css">
<link rel="stylesheet" href="https://unpkg.com/mermaid@8.5.1/dist/mermaid.css">
<link rel="stylesheet" href="../../assets/stylesheets/slick.css">
<link rel="stylesheet" href="../../assets/stylesheets/slick-theme.css">
<link rel="stylesheet" href="../../assets/stylesheets/extra.css">
<script>
window.ga = window.ga || function() {
(ga.q = ga.q || []).push(arguments)
}
ga.l = +new Date
/* Setup integration and send page view */
ga("create", "UA-184785655-1", "auto")
ga("set", "anonymizeIp", true)
ga("send", "pageview")
/* Register handler to log search on blur */
document.addEventListener("DOMContentLoaded", () => {
if (document.forms.search) {
var query = document.forms.search.query
query.addEventListener("blur", function() {
if (this.value) {
var path = document.location.pathname;
ga("send", "pageview", path + "?q=" + this.value)
}
})
}
})
</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
</head>
<body dir="ltr" data-md-color-scheme="" data-md-color-primary="black" data-md-color-accent="orange">
<script>function __prefix(e){return new URL("../..",location).pathname+"."+e}function __get(e,t=localStorage){return JSON.parse(t.getItem(__prefix(e)))}</script>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#visualising-models-with-picto" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="Epsilon" class="md-header__button md-logo" aria-label="Epsilon" data-md-component="logo">
<img src="../../assets/images/epsilon-white-background.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Epsilon
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Picto
</span>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
</label>
<button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
Git repository @ Eclipse
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Epsilon" class="md-nav__button md-logo" aria-label="Epsilon" data-md-component="logo">
<img src="../../assets/images/epsilon-white-background.png" alt="logo">
</a>
Epsilon
</label>
<div class="md-nav__source">
<a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
Git repository @ Eclipse
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../../download/" class="md-nav__link">
Download
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../live" class="md-nav__link">
Playground
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5" type="checkbox" id="__nav_5" checked>
<label class="md-nav__link" for="__nav_5">
Documentation
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Documentation" data-md-level="1">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Documentation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../" class="md-nav__link">
Overview
</a>
</li>
<li class="md-nav__item">
<a href="../emc/" class="md-nav__link">
Model Connectivity
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_3" type="checkbox" id="__nav_5_3" >
<label class="md-nav__link" for="__nav_5_3">
Languages
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Languages" data-md-level="2">
<label class="md-nav__title" for="__nav_5_3">
<span class="md-nav__icon md-icon"></span>
Languages
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../eol/" class="md-nav__link">
Object Language (EOL)
</a>
</li>
<li class="md-nav__item">
<a href="../egl/" class="md-nav__link">
Code Generation (EGL)
</a>
</li>
<li class="md-nav__item">
<a href="../evl/" class="md-nav__link">
Model Validation (EVL)
</a>
</li>
<li class="md-nav__item">
<a href="../etl/" class="md-nav__link">
Model Transformation (ETL)
</a>
</li>
<li class="md-nav__item">
<a href="../ecl/" class="md-nav__link">
Model Comparison (ECL)
</a>
</li>
<li class="md-nav__item">
<a href="../eml/" class="md-nav__link">
Model Merging (EML)
</a>
</li>
<li class="md-nav__item">
<a href="../epl/" class="md-nav__link">
Pattern Matching (EPL)
</a>
</li>
<li class="md-nav__item">
<a href="../flock/" class="md-nav__link">
Model Migration (Flock)
</a>
</li>
<li class="md-nav__item">
<a href="../emg/" class="md-nav__link">
Model Generation (EMG)
</a>
</li>
<li class="md-nav__item">
<a href="../eunit/" class="md-nav__link">
Unit Testing (EUnit)
</a>
</li>
<li class="md-nav__item">
<a href="../pinset/" class="md-nav__link">
Dataset Extraction (Pinset)
</a>
</li>
<li class="md-nav__item">
<a href="../ewl/" class="md-nav__link">
Wizard Language (EWL)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_4" type="checkbox" id="__nav_5_4" checked>
<label class="md-nav__link" for="__nav_5_4">
Tools
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Tools" data-md-level="2">
<label class="md-nav__title" for="__nav_5_4">
<span class="md-nav__icon md-icon"></span>
Tools
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Picto
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
Picto
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#metamodel" class="md-nav__link">
Metamodel
</a>
</li>
<li class="md-nav__item">
<a href="#model" class="md-nav__link">
Model
</a>
</li>
<li class="md-nav__item">
<a href="#model-to-text-transformation" class="md-nav__link">
Model-to-Text Transformation
</a>
</li>
<li class="md-nav__item">
<a href="#result" class="md-nav__link">
Result
</a>
</li>
<li class="md-nav__item">
<a href="#layers" class="md-nav__link">
Layers
</a>
</li>
<li class="md-nav__item">
<a href="#scalability" class="md-nav__link">
Scalability
</a>
</li>
<li class="md-nav__item">
<a href="#interactive-diagrams" class="md-nav__link">
Interactive Diagrams
</a>
</li>
<li class="md-nav__item">
<a href="#editors-supported-by-picto" class="md-nav__link">
Editors supported by Picto
</a>
</li>
<li class="md-nav__item">
<a href="#extending-picto" class="md-nav__link">
Extending Picto
</a>
</li>
<li class="md-nav__item">
<a href="#using-picto-in-standalone-mode-with-many-models" class="md-nav__link">
Using Picto in standalone mode / with many models
</a>
</li>
<li class="md-nav__item">
<a href="#troubleshooting" class="md-nav__link">
Troubleshooting
</a>
</li>
<li class="md-nav__item">
<a href="#philosophy" class="md-nav__link">
Philosophy
</a>
</li>
<li class="md-nav__item">
<a href="#gallery" class="md-nav__link">
Gallery
</a>
</li>
<li class="md-nav__item">
<a href="#additional-resources" class="md-nav__link">
Additional Resources
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../flexmi/" class="md-nav__link">
Flexmi
</a>
</li>
<li class="md-nav__item">
<a href="../eugenia/" class="md-nav__link">
Eugenia
</a>
</li>
<li class="md-nav__item">
<a href="../exeed/" class="md-nav__link">
Exeed
</a>
</li>
<li class="md-nav__item">
<a href="../modelink/" class="md-nav__link">
Modelink
</a>
</li>
<li class="md-nav__item">
<a href="../hutn/" class="md-nav__link">
HUTN
</a>
</li>
<li class="md-nav__item">
<a href="../workflow/" class="md-nav__link">
Workflow (Ant tasks)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../articles/" class="md-nav__link">
Articles
</a>
</li>
<li class="md-nav__item">
<a href="../../examples/" class="md-nav__link">
Examples
</a>
</li>
<li class="md-nav__item">
<a href="https://www.youtube.com/epsilondevs" class="md-nav__link">
Screencasts
</a>
</li>
<li class="md-nav__item">
<a href="https://www.youtube.com/playlist?list=PLRwHao6Ue0YUecg7vEUQTrtySIWwrd_mI" class="md-nav__link">
Lectures
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_9" type="checkbox" id="__nav_5_9" >
<label class="md-nav__link" for="__nav_5_9">
Javadoc
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Javadoc" data-md-level="2">
<label class="md-nav__title" for="__nav_5_9">
<span class="md-nav__icon md-icon"></span>
Javadoc
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://download.eclipse.org/epsilon/stable-javadoc/" class="md-nav__link">
Stable
</a>
</li>
<li class="md-nav__item">
<a href="https://download.eclipse.org/epsilon/interim-javadoc/" class="md-nav__link">
Interim
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6" type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6">
Issues
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Issues" data-md-level="1">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Issues
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/enter_bug.cgi?product=epsilon" class="md-nav__link">
Report a new issue
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=blocker&bug_severity=critical&bug_severity=major&bug_severity=normal&bug_severity=minor&bug_severity=trivial" class="md-nav__link">
View open bugs
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=enhancement" class="md-nav__link">
View enhancement requests
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=RESOLVED&list_id=17694438&product=epsilon&query_format=advanced" class="md-nav__link">
View issues resolved since the last stable release
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time" class="md-nav__link">
View all issues
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7" type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7">
Community
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Community" data-md-level="1">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Community
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7_1" type="checkbox" id="__nav_7_1" >
<label class="md-nav__link" for="__nav_7_1">
Who is using Epsilon?
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Who is using Epsilon?" data-md-level="2">
<label class="md-nav__title" for="__nav_7_1">
<span class="md-nav__icon md-icon"></span>
Who is using Epsilon?
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../users/" class="md-nav__link">
Industry
</a>
</li>
<li class="md-nav__item">
<a href="../../users/education/" class="md-nav__link">
Education
</a>
</li>
<li class="md-nav__item">
<a href="../../users/open-source/" class="md-nav__link">
Open-source Projects
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="https://projects.eclipse.org/projects/modeling.epsilon/who" class="md-nav__link">
Who is developing Epsilon?
</a>
</li>
<li class="md-nav__item">
<a href="https://www.eclipse.org/forums/index.php/f/22/" class="md-nav__link">
Forum
</a>
</li>
<li class="md-nav__item">
<a href="../../professional-services" class="md-nav__link">
Professional Services
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7_5" type="checkbox" id="__nav_7_5" >
<label class="md-nav__link" for="__nav_7_5">
Social Media
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Social Media" data-md-level="2">
<label class="md-nav__title" for="__nav_7_5">
<span class="md-nav__icon md-icon"></span>
Social Media
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://twitter.com/eclipseepsilon" class="md-nav__link">
Twitter
</a>
</li>
<li class="md-nav__item">
<a href="https://youtube.com/epsilondevs" class="md-nav__link">
YouTube
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../labs/" class="md-nav__link">
Epsilon Labs
</a>
</li>
<li class="md-nav__item">
<a href="../../faq/" class="md-nav__link">
Frequently Asked Questions
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../branding/" class="md-nav__link">
Branding
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#metamodel" class="md-nav__link">
Metamodel
</a>
</li>
<li class="md-nav__item">
<a href="#model" class="md-nav__link">
Model
</a>
</li>
<li class="md-nav__item">
<a href="#model-to-text-transformation" class="md-nav__link">
Model-to-Text Transformation
</a>
</li>
<li class="md-nav__item">
<a href="#result" class="md-nav__link">
Result
</a>
</li>
<li class="md-nav__item">
<a href="#layers" class="md-nav__link">
Layers
</a>
</li>
<li class="md-nav__item">
<a href="#scalability" class="md-nav__link">
Scalability
</a>
</li>
<li class="md-nav__item">
<a href="#interactive-diagrams" class="md-nav__link">
Interactive Diagrams
</a>
</li>
<li class="md-nav__item">
<a href="#editors-supported-by-picto" class="md-nav__link">
Editors supported by Picto
</a>
</li>
<li class="md-nav__item">
<a href="#extending-picto" class="md-nav__link">
Extending Picto
</a>
</li>
<li class="md-nav__item">
<a href="#using-picto-in-standalone-mode-with-many-models" class="md-nav__link">
Using Picto in standalone mode / with many models
</a>
</li>
<li class="md-nav__item">
<a href="#troubleshooting" class="md-nav__link">
Troubleshooting
</a>
</li>
<li class="md-nav__item">
<a href="#philosophy" class="md-nav__link">
Philosophy
</a>
</li>
<li class="md-nav__item">
<a href="#gallery" class="md-nav__link">
Gallery
</a>
</li>
<li class="md-nav__item">
<a href="#additional-resources" class="md-nav__link">
Additional Resources
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="visualising-models-with-picto">Visualising Models with Picto<a class="headerlink" href="#visualising-models-with-picto" title="Permanent link">&para;</a></h1>
<p>Picto is an Eclipse view for <strong>visualising models via model-to-text transformation</strong> to SVG/HTML. Compared to existing graphical modelling frameworks such as <a href="https://eclipse.org/sirius">Sirius</a> and <a href="../articles/eugenia-gmf-tutorial">GMF/Eugenia</a>, the main appeal of Picto is that model visualisation takes place in an embedded browser and therefore you can leverage any HTML/SVG/JavaScript-based technology such as <a href="https://d3js.org/">D3.js</a>, <a href="https://github.com/jgraph/mxgraph">mxGraph</a> and <a href="https://www.jointjs.com/">JointJS</a>. Picto also provides built-in support for the powerful <a href="https://www.graphviz.org/">Graphviz</a> and <a href="https://plantuml.com/">PlantUML</a> textual syntaxes (which are transformed to SVG via the respective tools). A distinguishing feature of Picto is that it does not require running multiple Eclipse instances as the metamodels, models and visualisation transformations can all reside in the same workspace.</p>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>As Picto uses <a href="../egl">EGL</a> for model-to-text transformation, it is <a href="#using-picto-in-standalone-mode-with-many-models">not limited to EMF-based models</a> and can be used to visualise the contents of Simulink models, XML documents, spreadsheets, and any other type of artefact supported by an <a href="../emc">Epsilon EMC driver</a>.</p>
</div>
<details class="info"><summary>Citing Picto in a publication?</summary><p>If you are referring to Picto in a publication, please cite <a href="https://dl.acm.org/doi/10.1145/3365438.3410943">this paper</a> instead of the website URL. A pre-print of the paper is available <a href="http://eprints.whiterose.ac.uk/164209/">here</a>.</p>
</details>
<p>On the flip side, Picto displays read-only views of models and as such it is not a good fit if diagram-based model editing capabilities are required. In this article we demonstrate Picto through a small social network example. The complete source code of the example is available <a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/plain/examples/org.eclipse.epsilon.examples.picto.socialnetwork/">here</a>.</p>
<p><img alt="" src="picto-eclipse.png" /></p>
<h2 id="metamodel">Metamodel<a class="headerlink" href="#metamodel" title="Permanent link">&para;</a></h2>
<p>We start with the metamodel of our social network DSL expressed in <a href="https://www.eclipse.org/emfatic/">Emfatic</a> (the <code>.ecore</code> version of the metamodel is also provided in the repository). The DSL allows modelling people in a network and likes/dislikes relationships between them.</p>
<pre class="prettyprint lang-emf"><code>@namespace(uri="socialnetwork", prefix="")
package socialnetwork;
class SocialNetwork {
val Person[*] people;
}
class Person {
attr String name;
ref Person[*] likes;
ref Person[*] dislikes;
}</code></pre>
<h2 id="model">Model<a class="headerlink" href="#model" title="Permanent link">&para;</a></h2>
<p>Below is a model that conforms to the social network metamodel. The model is defined for convenience in <a href="../flexmi">Flexmi</a>, however Picto also works with XMI-based models (see below).</p>
<div class="highlight"><pre><span></span><code><span class="cp">&lt;?nsuri socialnetwork?&gt;</span>
<span class="cp">&lt;?render-egx picto/socialnetwork.egx?&gt;</span>
<span class="nt">&lt;socialnetwork&gt;</span>
<span class="nt">&lt;person</span> <span class="na">name=</span><span class="s">&quot;Alice&quot;</span> <span class="na">likes=</span><span class="s">&quot;Bob, Charlie&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;person</span> <span class="na">name=</span><span class="s">&quot;Bob&quot;</span> <span class="na">likes=</span><span class="s">&quot;Enid, Alice&quot;</span> <span class="na">dislikes=</span><span class="s">&quot;Fred, Charlie&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;person</span> <span class="na">name=</span><span class="s">&quot;Charlie&quot;</span> <span class="na">likes=</span><span class="s">&quot;Fred, Alice&quot;</span> <span class="na">dislikes=</span><span class="s">&quot;Dawn, Enid&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;person</span> <span class="na">name=</span><span class="s">&quot;Dawn&quot;</span> <span class="na">likes=</span><span class="s">&quot;Bob&quot;</span> <span class="na">dislikes=</span><span class="s">&quot;Fred&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;person</span> <span class="na">name=</span><span class="s">&quot;Enid&quot;</span> <span class="na">likes=</span><span class="s">&quot;Charlie&quot;</span> <span class="na">dislikes=</span><span class="s">&quot;Alice&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;person</span> <span class="na">name=</span><span class="s">&quot;Fred&quot;</span> <span class="na">dislikes=</span><span class="s">&quot;Bob&quot;</span> <span class="na">likes=</span><span class="s">&quot;Enid, Alice&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/socialnetwork&gt;</span>
</code></pre></div>
<p>In line 2 of the model, notice the <code>render-egx</code> processing instruction, which specifies a model-to-text transformation written in <a href="../egx/">EGX/EGL</a>, that Picto should use to visualise this model.</p>
<h2 id="model-to-text-transformation">Model-to-Text Transformation<a class="headerlink" href="#model-to-text-transformation" title="Permanent link">&para;</a></h2>
<p>The <code>socialnetwork.egx</code> EGX model-to-text transformation is as follows:</p>
<pre class="prettyprint lang-egx"><code>rule Network2Graphviz
transform n : socialnetwork::SocialNetwork {
template : "socialnetwork2graphviz.egl"
parameters : Map{
"path" = Sequence{"Social Network"},
"icon" = "diagram-ffffff",
"format" = "graphviz-circo",
"layers" = Sequence {
Map {"id"="likes", "title"="Likes", "active"=true},
Map {"id"="dislikes", "title"="Dislikes", "active"=true}
},
"people" = n.people
}
}
rule Person2Graphviz
transform p : socialnetwork::Person {
template : "socialnetwork2graphviz.egl"
parameters : Map{
"path" = Sequence{"Social Network", p.name},
"icon" = "diagram-c0c0c0",
"format" = "graphviz-dot",
"layers" = Sequence {
Map {"id"="likes", "title"="Likes", "active"=true},
Map {"id"="dislikes", "title"="Dislikes", "active"=true}
},
"people" = Sequence{p}
}
}</code></pre>
<p>The transformation consists of two rules:</p>
<ul>
<li><code>Network2Graphviz</code> which will be executed once and will produce a Graphviz graph for the entire network</li>
<li><code>Person2Graphviz</code> which will be executed for every person in the network and produce the person's own local likes/dislikes graph</li>
</ul>
<p>Each rule specifies the EGL template that it will invoke (<code>socialnetwork2graphviz.egl</code> in both cases here) as well as a set of parameters that Picto needs. The parameters are as follows:</p>
<ul>
<li><code>path</code>: A collection of strings that specify the path of the produced view in the Picto tree</li>
<li><code>icon</code>: The icon of the view on the Picto tree. Allowed values at the moment are file names (without the extension) of all icon files under <a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/tree/plugins/org.eclipse.epsilon.picto/icons">this folder</a>, as well as <code>diagram-rrggbb</code> values where <code>rrggbb</code> is a hex colour</li>
<li><code>format</code>: The format of the view that the EGL transformation will produce. Built-in formats currently supported are <code>graphviz-dot</code>, <code>graphviz-circo</code>, <code>graphviz-neato</code>, <code>graphviz-fdp</code>, <code>plantuml</code>, <code>text</code>, <code>html</code> and <code>svg</code></li>
<li><code>layers</code>: A sequence of maps, each of which represents a layer of the view. Each layer needs to define an <code>id</code>, a <code>title</code> and (optionally), whether it is <code>active</code> by default</li>
</ul>
<p>The EGL template <code>socialnetwork2graphviz.egl</code> is as follows:</p>
<pre class="prettyprint lang-egl"><code>digraph G {
node[shape=rectangle, fontname=Tahoma, fontsize=10, style="filled",
gradientangle="270", fillcolor="bisque:floralwhite"]
edge[penwidth=3, style=tapered, arrowhead=none]
[%for (p in people){%]
[%=p.name%] [%if (people.size()==1){%][fillcolor="azure2:ghostwhite"][%}%]
[%if (isLayerActive("likes")){%]
[%for (l in p.likes){%]
[%=p.name%] -&gt; [%=l.name%] [color="#2A6C41"]
[%}%]
[%}%]
[%if (isLayerActive("dislikes")){%]
[%for (l in p.dislikes){%]
[%=p.name%] -&gt; [%=l.name%] [color="#B43431"]
[%}%]
[%}%]
[%}%]
}
[%
operation isLayerActive(id : String) {
var layer = layers.selectOne(l|l.id = id);
if (layer.isDefined()) {
return layer.active;
}
else {
return true;
}
}
%]</code></pre>
<h2 id="result">Result<a class="headerlink" href="#result" title="Permanent link">&para;</a></h2>
<p>Every time <code>socialnetwork.flexmi</code> is saved, Picto will run the EGX/EGL transformation and display the results in a view that consists of a tree viewer and a browser. For this model, Picto produces 7 diagrams; one for the network as a whole through the application of the <code>Network2Graphviz</code> rule and one for each person in the network through the application of the <code>Person2Graphviz</code> rule. Screenshots of the populated Picto view appear below.</p>
<p><img alt="" src="picto.png" /></p>
<p><img alt="" src="picto-bob.png" /></p>
<h2 id="layers">Layers<a class="headerlink" href="#layers" title="Permanent link">&para;</a></h2>
<p>Picto supports the concept of layers to allow users to show/hide information on a diagram. Both EGX rules specify a "likes" and a "dislikes" layer (lines 11-12 and 29-30) which the user can turn on/off to show/hide like/dislike relationships in the current diagram. Hiding the "dislikes" layer, makes the network-level diagram look like this.</p>
<p><img alt="" src="picto-layers.png" /></p>
<h2 id="scalability">Scalability<a class="headerlink" href="#scalability" title="Permanent link">&para;</a></h2>
<p>Picto works in a lazy way and initially computes only the details needed to show the tree of views (view paths and icons) on its left-hand side. The content of individual views is computed on demand when a user clicks on a view in the Picto tree. We have used Picto with models and visualisation transformations that produce hundreds of deeply nested views without performance issues. Having said that, as models grow in size, the time it takes the underlying modelling framework (e.g. EMF) to load them into memory and the time it takes EGL to process them are also bound to grow. In such cases, consider fragmenting your models across many files. It is also important to try and do as little work as possible at the EGX level and carry out any expensive computations within the EGL templates instead.</p>
<p>When targeting Graphviz or PlantUML it is also advisable to keep your generated diagrams relatively small as auto-layout is computationally expensive (particularly routing edges) and rendering your views can take a long time. For example, generating the Graphviz representation of the full UML metamodel class diagram (260+ classes/650+ references) is instantaneous but getting Graphviz's dot program to render it takes hours. In any event, such a diagram would have been unreadable, and hence pointless (see the 20-class/50-references diagram of Ecore.ecore below, which is generated and rendered instantaneously).</p>
<p><img alt="" src="picto-all-ecore.png" /></p>
<p>To "protect" your visualisation rules from input that is bound to generate meaningless output you can use guards as shown below.</p>
<pre class="prettyprint lang-egx"><code>rule ClassDiagram {
guard : EClass.all.size() &lt; 30
parameters : Map {
"classes" = EClass.all,
"format" = "graphviz-dot",
"path" = List{"Model", "(All Classes)"},
"icon" = "diagram-ff0000"
}
template: "ecore2dot.egl"
}</code></pre>
<p>In such cases, it is preferable to generate many smaller diagrams; for this example, a class diagram for each class of the metamodel, surrounded by its super/sub/referenced types. </p>
<h2 id="interactive-diagrams">Interactive Diagrams<a class="headerlink" href="#interactive-diagrams" title="Permanent link">&para;</a></h2>
<p>Diagrams can also be linked to each other and link back to the models from which they were generated. For example, clicking any of the yellow classes in the diagram below takes you to the respective diagram and clicking on the green EClassifer class, takes you to the class definition in the Ecore editor. This is achieved through two built-in JavaScript functions below, which are showcased <a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/plain/examples/org.eclipse.epsilon.examples.picto.ecore/ecore2vis/classdiagram.egl">here</a>.</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>showView(String[] path)</td>
<td>Shows the view with the specified path - e.g. <code>top.showView(['Model', 'Classes', 'EClassifier'])</code></td>
</tr>
<tr>
<td>showElement(String elementId, String resourceUri)</td>
<td>Selects the specified element in its Eclipse-based editor (e.g. the EMF tree-based editor)</td>
</tr>
</tbody>
</table>
<p><img alt="" src="picto-eclassifier.png" /></p>
<h2 id="editors-supported-by-picto">Editors supported by Picto<a class="headerlink" href="#editors-supported-by-picto" title="Permanent link">&para;</a></h2>
<ul>
<li>Any editor that implements EMF's <code>IEditingDomainProvider</code> interface (e.g. the reflective Ecore editor, Exeed) as long as next to the edited file there is a file with the same name and a <code>.picto</code> suffix providing the format of the visualisation and the EGL template to be used (see the XMI-based <code>socialnetwork.model</code> and <code>socialnetwork.model.picto</code> files in the example directory)</li>
<li>Flexmi editor: as long as the Flexmi model contains a <code>&lt;?render-xxx ?&gt;</code> processing instruction</li>
<li>Emfatic editor</li>
<li>Default text editor editing files with <code>.html</code>, <code>.svg</code>, <code>.dot</code>, <code>.neato</code> file extensions (mainly for debugging)</li>
</ul>
<h2 id="extending-picto">Extending Picto<a class="headerlink" href="#extending-picto" title="Permanent link">&para;</a></h2>
<p>Picto provides the following extension points that can be used to extend its functionality. </p>
<table>
<thead>
<tr>
<th>Extension Point</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>org.eclipse.epsilon.picto.pictoSource</td>
<td>Bind Picto to a type of Eclipse-based editors so that Picto auto-refreshes every time a file in an editor of this type is saved</td>
</tr>
<tr>
<td>org.eclipse.epsilon.picto.browserFunction</td>
<td>Add a custom Javascript function that generated diagrams can call (much like the <code>showView</code> and <code>showElement</code> functions above)</td>
</tr>
<tr>
<td>org.eclipse.epsilon.picto.browserScript</td>
<td>Add a Javascript that executes when the Picto browser loads</td>
</tr>
<tr>
<td>org.eclipse.epsilon.picto.viewContentTransformer</td>
<td>Transform a custom content type to HTML, or to a content type that another <a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/plain/plugins/org.eclipse.epsilon.picto/src/org/eclipse/epsilon/picto/transformers/ViewContentTransformer.java">ViewContentTransformer</a> can transform. See <a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/plain/plugins/org.eclipse.epsilon.picto/src/org/eclipse/epsilon/picto/transformers/MarkdownContentTransformer.java">MarkdownContentTransformer</a> as an example.</td>
</tr>
<tr>
<td>org.eclipse.epsilon.picto.htmlElementTransformer</td>
<td>Add support for custom HTML elements to Picto. See <a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/plain/plugins/org.eclipse.epsilon.picto/src/org/eclipse/epsilon/picto/transformers/elements/PictoViewElementTransformer.java">PictoViewElementTransformer</a> as an example, which adds a new <code>&lt;picto-view path="..."/&gt;</code> HTML tag to Picto, that supports embedding Picto views <a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/plain/examples/org.eclipse.epsilon.examples.picto.ecore/comps/readme.html">within other Picto views</a>.</td>
</tr>
</tbody>
</table>
<p>Please see this <a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/plain/plugins/org.eclipse.epsilon.picto/plugin.xml">plugin.xml</a>, which shows how some of these extension points were used to integrate Picto with different technologies, such as <a href="https://plantuml.com/">PlantUML</a> or <a href="https://github.com/mermaid-js/mermaid">Mermaid</a>.</p>
<h2 id="using-picto-in-standalone-mode-with-many-models">Using Picto in standalone mode / with many models<a class="headerlink" href="#using-picto-in-standalone-mode-with-many-models" title="Permanent link">&para;</a></h2>
<p>Picto also suports a standalone mode, where the details of the models to be visualised are provided within the <code>.picto</code> file itself. An example of visualising <code>socialnetwork.model</code> in standalone mode (without the model being open in a tree editor) is below and in <code>socialnetwork-standalone.picto</code> in the example folder.</p>
<div class="highlight"><pre><span></span><code><span class="cp">&lt;?nsuri picto?&gt;</span>
<span class="nt">&lt;picto</span> <span class="na">format=</span><span class="s">&quot;egx&quot;</span> <span class="na">transformation=</span><span class="s">&quot;picto/socialnetwork.egx&quot;</span> <span class="na">standalone=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;model</span> <span class="na">type=</span><span class="s">&quot;EMF&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;parameter</span> <span class="na">name=</span><span class="s">&quot;name&quot;</span> <span class="na">value=</span><span class="s">&quot;M&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;parameter</span> <span class="na">name=</span><span class="s">&quot;metamodelUri&quot;</span> <span class="na">value=</span><span class="s">&quot;socialnetwork&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;parameter</span> <span class="na">name=</span><span class="s">&quot;modelFile&quot;</span> <span class="na">file=</span><span class="s">&quot;socialnetwork.model&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/model&gt;</span>
<span class="nt">&lt;/picto&gt;</span>
</code></pre></div>
<h2 id="troubleshooting">Troubleshooting<a class="headerlink" href="#troubleshooting" title="Permanent link">&para;</a></h2>
<ul>
<li>If you can't find the Picto view, you will need to upgrade to a version of Epsilon &gt;= 2.0</li>
<li>Graphviz (on which the PlantUML integration also depends) does not ship as part of Picto. You will need to install it manually on your computer.</li>
</ul>
<h2 id="philosophy">Philosophy<a class="headerlink" href="#philosophy" title="Permanent link">&para;</a></h2>
<p>While EMF provides support for <a href="../articles/reflective-emf-tutorial">reflective model instantiation</a> within the same Eclipse workspace, graphical and textual modelling frameworks that sit on top of it such as GMF, Sirius and Xtext involve code generation and/or contributing to Eclipse extension points and hence require spawning a new Eclipse instance. While this inconvenience can pay off for large DSLs, it feels like an overkill when one needs to throw together a small DSL in situ. The original aim of Picto was to complement Flexmi in this respect by contributing model visualisation capabilities where creating a new dedicated graphical editor is considered to be an overkill.</p>
<h2 id="gallery">Gallery<a class="headerlink" href="#gallery" title="Permanent link">&para;</a></h2>
<p><img alt="" src="picto-minisd.png" /></p>
<p><img alt="" src="picto-risks.png" /></p>
<p><img alt="" src="picto-gsn.png" /></p>
<h2 id="additional-resources">Additional Resources<a class="headerlink" href="#additional-resources" title="Permanent link">&para;</a></h2>
<p>Additional resources about Picto are available <a href="../articles/#picto">here</a>.</p>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../ewl/" title="Wizard Language (EWL)" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Wizard Language (EWL)
</span>
</div>
</a>
<a href="../flexmi/" title="Flexmi" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Flexmi
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright © Eclipse Foundation, Inc. All Rights Reserved.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">Material for MkDocs</a>
</div>
<div class="md-footer-copyright epsilon-eclipse-links">
<ul>
<li><a href="https://www.eclipse.org/legal/privacy.php">Privacy Policy</a></li>
<li><a href="https://www.eclipse.org/legal/termsofuse.php">Terms of Use</a></li>
<li><a href="https://www.eclipse.org/legal/copyright.php">Copyright Agent</a></li>
</ul>
</div>
<div class="md-footer-social">
<a href="https://twitter.com/eclipseepsilon" target="_blank" rel="noopener" title="twitter.com" class="md-footer-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
</a>
<a href="https://youtube.com/epsilondevs" target="_blank" rel="noopener" title="youtube.com" class="md-footer-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": [], "translations": {"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}, "search": "../../assets/javascripts/workers/search.d351de03.min.js", "version": null}</script>
<script src="../../assets/javascripts/bundle.a1609d9a.min.js"></script>
<script src="https://unpkg.com/mermaid@8.5.1/dist/mermaid.min.js"></script>
<script src="../../assets/javascript/mermaid.js"></script>
<script src="../../assets/javascript/jquery.js"></script>
<script src="../../assets/javascript/slick.min.js"></script>
<script src="../../assets/javascript/google-code-prettify/prettify.js"></script>
<script src="../../assets/javascript/google-code-prettify/lang-emfatic.js"></script>
<script src="../../assets/javascript/google-code-prettify/lang-epsilon.js"></script>
<script src="../../assets/javascript/google-code-prettify/prettyprint.js"></script>
<script src="../../assets/javascript/extra.js"></script>
<script src="https://w.appzi.io/w.js?token=jlv6W"></script>
</body>
</html>