GUI -- separated glyph data from glyph code.
- moved _sdh/* and _bripc/* to _dev
Change-Id: Iaeb5c416e1566aeb920b9c5b8692151305efcfca
diff --git a/web/gui/src/main/webapp/_dev/big-icon.html b/web/gui/src/main/webapp/_dev/big-icon.html
new file mode 100644
index 0000000..f6b43f0
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/big-icon.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright 2016 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+ ONOS -- Display a glyph with Angular test page
+ -->
+
+<html>
+<head lang="en">
+ <meta charset="UTF-8">
+ <title>Show Icons Angular</title>
+
+ <script type="text/javascript" src="../tp/angular.js"></script>
+ <script type="text/javascript" src="../tp/angular-route.js"></script>
+
+ <script type="text/javascript" src="../tp/d3.js"></script>
+
+ <script type="text/javascript" src="../app/fw/util/util.js"></script>
+ <script type="text/javascript" src="../app/fw/util/fn.js"></script>
+
+ <script type="text/javascript" src="../app/fw/svg/svg.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/svgUtil.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/glyph.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/glyphData.js"></script>
+
+ <script type="text/javascript" src="big-icon.js"></script>
+
+ <link rel="stylesheet" href="../app/common.css">
+ <link rel="stylesheet" href="../app/fw/svg/icon.css">
+
+ <style>
+ html,
+ body {
+ background-color: #ddf;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 9pt;
+ }
+
+ h2 {
+ color: darkred;
+ }
+
+ /* foreground color */
+ svg .glyph {
+ stroke: none;
+ fill: #246;
+ fill-rule: evenodd;
+ }
+
+ /* background color */
+ svg.embeddedGlyph .glyph rect {
+ fill: #fff
+ }
+
+ </style>
+
+</head>
+<!-- outline for using a controller in Angular -->
+<body class="light" ng-app="showGlyph" ng-controller="OvShowGlyph as ctrl">
+ <h2>Display a Glyph</h2>
+ <div id="showGlyphs"></div>
+ <svg><defs></defs></svg>
+</body>
+</html>
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/_dev/big-icon.js b/web/gui/src/main/webapp/_dev/big-icon.js
new file mode 100644
index 0000000..9548f98
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/big-icon.js
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Test code for displaying custom glyphs
+ */
+
+(function () {
+ 'use strict';
+
+ // assuming the glyph is a square
+ // div is a D3 selection of the <DIV> element into which icon should load
+ // size is the size of the glyph
+ // id is the symbol id
+ function createGlyph(div, size, id) {
+ var dim = size || 20,
+ texty = 30,
+ gid = id || 'unknown',
+ rx = 4,
+ svgCls = 'embeddedGlyph',
+ svg, g;
+
+ svg = div.append('svg').attr({
+ 'class': svgCls,
+ width: dim,
+ height: dim + texty,
+ viewBox: '0 0 ' + dim + ' ' + dim
+ });
+
+ g = svg.append('g').attr({
+ 'class': 'glyph'
+ });
+
+ g.append('rect').attr({
+ width: dim,
+ height: dim,
+ rx: rx
+ });
+
+ g.append('use').attr({
+ width: dim,
+ height: dim,
+ 'class': 'glyph',
+ 'xlink:href': '#' + gid
+ });
+
+ g.append('text')
+ .attr({
+ 'text-anchor': 'left',
+ y: '1em',
+ x: 0,
+ transform: 'translate(0, ' + dim + ')'
+ })
+ .style('fill', '#800')
+ .text(id);
+ }
+
+ var clock = 'M92.9,61.3a39,39,0,1,1-39-39,39,39,0,0,1,39,39h0Z' +
+ 'M44,19.3c-4.4-7.4-14.8-9.3-23.2-4.2S9.1,30.2,13.5,37.6m80.8,0' +
+ 'c4.4-7.4,1.2-17.5-7.3-22.5s-18.8-3.2-23.3,4.2m-8.4,1.8V16.5h4.4' +
+ 'V11.9H48.2v4.6h4.6v4.6M51.6,56.4H51.5' +
+ 'a5.4,5.4,0,0,0,2.4,10.3,4.7,4.7,0,0,0,4.9-3.1H74.5' +
+ 'a2.2,2.2,0,0,0,2.4-2.2,2.4,2.4,0,0,0-2.4-2.3H58.8' +
+ 'a5.3,5.3,0,0,0-2.5-2.6H56.2V32.9' +
+ 'a2.3,2.3,0,0,0-.6-1.7,2.2,2.2,0,0,0-1.6-.7,2.4,2.4,0,0,0-2.4,2.4' +
+ 'h0V56.4M82.2,91.1l-7.1,5.3-0.2.2-1.2,2.1a0.6,0.6,0,0,0,.2.8' +
+ 'h0.2c2.6,0.4,10.7.9,10.3-1.2m-60.8,0c-0.4,2.1,7.7,1.6,10.3,1.2' +
+ 'h0.2a0.6,0.6,0,0,0,.2-0.8l-1.2-2.1-0.2-.2-7.1-5.3';
+
+ var clocks = "M65.7,26.6A34.7,34.7,0,0,0,31,61.5c0,19,16,35.2,35.5,34.8" +
+ "a35.1,35.1,0,0,0,34-35.1A34.7,34.7,0,0,0,65.7,26.6Z" +
+ "m8.6-2.7,27.4,16.4a31.3,31.3,0,0,0,1.2-3.1c1.3-5,0-9.4-3.2-13.2" +
+ "a16.9,16.9,0,0,0-16-6.2A12.8,12.8,0,0,0,74.3,23.9Z" +
+ "M57,23.9L56.4,23a12.9,12.9,0,0,0-10.7-5.5,16.9,16.9,0,0,0-15.1,8," +
+ "14.1,14.1,0,0,0-2.3,11.2,10.4,10.4,0,0,0,1.4,3.5Z" +
+ "M26.9,31.6A33.7,33.7,0,0,0,9.7,59.3C9.2,72.8,14.9,83.1,26,90.7l1-1.9" +
+ "a0.6,0.6,0,0,0-.2-1A34.2,34.2,0,0,1,15.5,50.4" +
+ "a33.8,33.8,0,0,1,10.8-16,1.2,1.2,0,0,0,.5-0.6" +
+ "C26.9,33.1,26.9,32.4,26.9,31.6Z" +
+ "m1,8.1C14.6,55.9,19.2,81,37.6,91.1l1-2.3-2.8-2.4" +
+ "C26.4,77.6,22.9,66.7,25.1,54" +
+ "a31.6,31.6,0,0,1,4.2-10.8,0.8,0.8,0,0,0,.1-0.6Z" +
+ "M12,38.4a11.2,11.2,0,0,1-1.4-5.8A13.7,13.7,0,0,1,14.3,24" +
+ "a17.3,17.3,0,0,1,10.5-5.7h0.4C19,18,13.7,20,9.9,25.2" +
+ "a14.5,14.5,0,0,0-3,11,11.2,11.2,0,0,0,1.6,4.3Z" +
+ "m5.5-2.7L21,33" +
+ "a1,1,0,0,0,.3-0.7,14,14,0,0,1,3.9-8.6,17.3,17.3,0,0,1,10.2-5.4" +
+ "l0.6-.2C24.4,17.3,16.4,27,17.4,35.7Z" +
+ "M70.9,17.2H60.7v4.1h4v4.2H67V21.3h3.9V17.2Z" +
+ "M90.9,87.9l-0.5.3L86,91.5a7.9,7.9,0,0,0-2.6,3.1" +
+ "c-0.3.6-.2,0.8,0.5,0.9a27.9,27.9,0,0,0,6.8.2l1.6-.4" +
+ "a0.8,0.8,0,0,0,.6-1.2l-0.4-1.4Z" +
+ "m-50.2,0-1.8,6c-0.3,1.1-.1,1.4.9,1.7h0.7a26.3,26.3,0,0,0,7.2-.1" +
+ "c0.8-.1.9-0.4,0.5-1.1a8.2,8.2,0,0,0-2.7-3.1Z" +
+ "m-10.8-.4-0.2.6L28,93.5a0.9,0.9,0,0,0,.7,1.3,7.7,7.7,0,0,0,2.2.4" +
+ "l5.9-.2c0.5,0,.7-0.3.5-0.8a7.6,7.6,0,0,0-2.2-2.9Z" +
+ "m-11.3,0-0.2.7-1.6,5.4c-0.2.8-.1,1.2,0.7,1.4a8,8,0,0,0,2.2.4l6-.2" +
+ "c0.4,0,.7-0.3.5-0.6a7.1,7.1,0,0,0-1.9-2.7l-2.8-2.1Z" +
+ "M65.7,26.6m-2,30.3a4.4,4.4,0,0,0-2.2,2,4.8,4.8,0,0,0,4,7.2," +
+ "4.1,4.1,0,0,0,4.3-2.3,0.8,0.8,0,0,1,.8-0.5H84.1" +
+ "a1.9,1.9,0,0,0,2-1.7,2.1,2.1,0,0,0-1.7-2.2H70.8" +
+ "a1,1,0,0,1-1-.5,6.4,6.4,0,0,0-1.5-1.6,1.1,1.1,0,0,1-.5-1" +
+ "q0-10.1,0-20.3a1.9,1.9,0,0,0-2.2-2.1,2.1,2.1,0,0,0-1.8,2.2" +
+ "q0,6.1,0,12.2C63.7,51.2,63.7,54,63.7,56.9Z";
+
+ var smiley = "M97,20.3A9.3,9.3,0,0,0,87.7,11H24.3A9.3,9.3,0,0,0,15,20.3" +
+ "V64.7A9.3,9.3,0,0,0,24.3,74H87.7A9.3,9.3,0,0,0,97,64.7V20.3Z" +
+ "M54.5,19.1A24.3,24.3,0,1,1,30.2,43.3,24.3,24.3,0,0,1,54.5,19.1Z" +
+ "M104.7,94.9L97.6,82.8c-0.9-1.6-3.7-2.8-6.1-2.8H18.9" +
+ "c-2.5,0-5.2,1.3-6.1,2.8L5.6,94.9C4.3,97.1,5.7,99,8.9,99h92.6" +
+ "C104.6,99,106.1,97.1,104.7,94.9ZM54.5,56.5" +
+ "c-7.3,0-17.2-8.6-13.3-7.4,13,3.9,13.7,3.9,26.5,0" +
+ "C71.7,48,61.9,56.6,54.5,56.6Z" +
+ "M38,33.9C38,32,40.2,31,42.1,31h7.3" +
+ "a3.2,3.2,0,0,1,3.1,1.7,13.1,13.1,0,0,1,2.1-.3,12.9,12.9,0,0,1,2.1.4" +
+ "A3.3,3.3,0,0,1,59.7,31H67c1.9,0,4,1,4,2.9v3.2A4.4,4.4,0,0,1,67,41" +
+ "H59.7A4,4,0,0,1,56,37.1V33.9h0a4.4,4.4,0,0,0-1.6-.2l-1.5.2H53v3.2" +
+ "A4,4,0,0,1,49.4,41H42.1A4.4,4.4,0,0,1,38,37.1V33.9Z";
+
+ var glyphData = {
+ _viewbox: "0 0 110 110",
+ alarm: clock,
+ alarms: clocks,
+ smiley: smiley
+ };
+
+ angular.module('showGlyph', ['onosSvg'])
+ .controller('OvShowGlyph', ['$log', 'GlyphService',
+
+ function ($log, gs) {
+ var gDiv = d3.select('#showGlyphs'),
+ defs = d3.select('defs');
+
+ // register out-of-the-box glyphs
+ gs.init();
+
+ // register our custom glyphs
+ gs.registerGlyphSet(glyphData);
+
+ // load all defined glyphs into our <defs> element
+ gs.loadDefs(defs);
+
+ // choose a glyph to render
+ createGlyph(gDiv, 400, 'switch');
+ }]);
+}());
diff --git a/web/gui/src/main/webapp/_dev/checkmark-xmark-icon.html b/web/gui/src/main/webapp/_dev/checkmark-xmark-icon.html
new file mode 100644
index 0000000..4c726fe
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/checkmark-xmark-icon.html
@@ -0,0 +1,145 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+ ONOS -- Embedded checkmarks and xmarks in table page
+ -->
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Embedded Check and X Marks</title>
+
+ <script src="../tp/d3.js"></script>
+
+ <link rel="stylesheet" href="../app/common.css">
+
+ <style>
+ html,
+ body {
+ background-color: #fff;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 9pt;
+ }
+
+ svg .icon .glyph {
+ stroke: none;
+ fill: white;
+ fill-rule: evenodd;
+ }
+
+ svg .icon.active {
+ fill: green;
+ }
+
+ svg .icon.inactive {
+ fill: darkred;
+ }
+
+ svg .icon rect {
+ stroke: white;
+ stroke-width: 3px;
+ }
+
+ </style>
+</head>
+<body class="light">
+<!-- minimal framework to access glyphs library module -->
+<script>
+ var libs = {};
+ var ONOS = { ui: { addLib: function (id, things) { libs[id] = things; }}};
+
+
+</script>
+
+<!-- Test HTML -->
+
+<div>
+ <table class="summary-list">
+ <tr> <th></th> <th>Two</th> <th>Three</th> </tr>
+ <tr>
+ <td>
+ <div icon icon-id="active">
+
+ <!-- icon directive needs to inject the following structure -->
+ <!-- ------------------------------------------------ -->
+ <svg width="20" height="20" viewBox="0 0 50 50">
+ <g class="icon active">
+ <rect width="50" height="50" rx="10"></rect>
+ <use class="glyph" xlink:href="#checkmark" width="50" height="50"></use>
+ </g>
+ </svg>
+ <!-- ------------------------------------------------ -->
+
+ </div>
+ </td>
+ <td>Some text</td>
+ <td>Some text</td>
+ </tr>
+ <tr>
+ <td>
+ <div icon icon-id="inactive">
+
+ <!-- icon directive needs to inject the following structure -->
+ <!-- ------------------------------------------------ -->
+ <svg width="20" height="20" viewBox="0 0 50 50">
+ <g class="icon inactive">
+ <rect width="50" height="50" rx="10"></rect>
+ <use class="glyph" xlink:href="#xmark" width="50" height="50"></use>
+ </g>
+ </svg>
+ <!-- ------------------------------------------------ -->
+
+
+ </div>
+ </td>
+ <td>Some text</td>
+ <td>Some Other text</td>
+ </tr>
+ </table>
+</div>
+
+<!-- common definitions for other SVG elements to use -->
+<svg width="0" height="0">
+ <defs>
+ <symbol id="checkmark" viewBox="0 0 10 10">
+ <path d="M2.644,4.531c0,0,0.719-0.422,1.172,0.281l1.047,1.797c0,0,
+ 2.675-5.449,2.781-5.719c0,0,0.547-0.859,1.359-0.094
+ c0,0,0.484,0.484,0,1.297S6.775,7.305,5.557,9.211c0,0-0.413,0.461-1.194,
+ 0.086S2.222,5.375,2.222,5.375S2.159,4.734,2.644,4.531z">
+ </path>
+ </symbol>
+
+ <symbol id="xmark" viewBox="0 0 10 10">
+ <path d="M8.967,7.196C8.172,6.852,7.37,6.058,6.672,5.189c0.385-0.463,
+ 0.665-0.834,0.764-1.008C7.825,3.5,9.382,1.553,8.068,1.067
+ C6.754,0.58,6.585,1.723,6.585,1.723C6.41,2.129,5.955,2.722,5.386,3.371C4.865,
+ 2.544,4.541,1.918,4.541,1.918
+ S3.812,0.24,2.863,0.654C1.915,1.067,2.304,2.283,2.304,2.283c0.349,1.122,
+ 0.834,2.082,1.368,2.898
+ C2.456,6.396,1.331,7.415,1.331,7.415S0.82,7.829,0.844,8.072C0.869,8.315,
+ 0.917,9.556,2.4,9.067
+ C3.084,8.843,4.122,7.933,5.083,6.95c1.306,1.348,2.498,1.949,2.498,1.949s0.535,
+ 0.51,1.386-0.244
+ C9.819,7.902,8.967,7.196,8.967,7.196z">
+ </path>
+ </symbol>
+
+ </defs>
+</svg>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/embedded-icon.html b/web/gui/src/main/webapp/_dev/embedded-icon.html
new file mode 100644
index 0000000..8d4d62a
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/embedded-icon.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+ ONOS -- Embedded icon test page
+ -->
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Embedded Icons</title>
+
+ <script src="../tp/d3.js"></script>
+
+ <link rel="stylesheet" href="../app/common.css">
+
+ <style>
+ html,
+ body {
+ background-color: #fff;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 9pt;
+ }
+
+ svg .icon .glyph {
+ stroke: none;
+ fill: white;
+ fill-rule: evenodd;
+ }
+
+ svg .icon.active {
+ fill: green;
+ }
+
+ svg .icon.inactive {
+ fill: darkred;
+ }
+
+ svg .icon rect {
+ stroke: black;
+ stroke-width: 1px;
+ }
+
+ </style>
+</head>
+<body class="light">
+<!-- minimal framework to access glyphs library module -->
+<script>
+ var libs = {};
+ var ONOS = { ui: { addLib: function (id, things) { libs[id] = things; }}};
+
+
+</script>
+
+<!-- Test HTML -->
+
+<div>
+ <table class="summary-list">
+ <tr> <th></th> <th>Two</th> <th>Three</th> </tr>
+ <tr>
+ <td>
+ <div icon icon-id="active">
+
+ <!-- icon directive needs to inject the following structure -->
+ <!-- ------------------------------------------------ -->
+ <svg width="20" height="20" viewBox="0 0 50 50">
+ <g class="icon active">
+ <rect width="50" height="50" rx="4"></rect>
+ <use class="glyph" xlink:href="#ui" width="50" height="50"></use>
+ </g>
+ </svg>
+ <!-- ------------------------------------------------ -->
+
+ </div>
+ </td>
+ <td>Some text</td>
+ <td>Some text</td>
+ </tr>
+ <tr>
+ <td>
+ <div icon icon-id="inactive">
+
+ <!-- icon directive needs to inject the following structure -->
+ <!-- ------------------------------------------------ -->
+ <svg width="20" height="20" viewBox="0 0 50 50">
+ <g class="icon inactive">
+ <rect width="50" height="50" rx="4"></rect>
+ <use class="glyph" xlink:href="#ui" width="50" height="50"></use>
+ </g>
+ </svg>
+ <!-- ------------------------------------------------ -->
+
+
+ </div>
+ </td>
+ <td>Some text</td>
+ <td>Some Other text</td>
+ </tr>
+ </table>
+</div>
+
+<!-- common definitions for other SVG elements to use -->
+<svg width="0" height="0">
+ <defs>
+ <symbol id="ui" viewBox="0 0 10 10">
+ <path d="M2,2.5a.5,.5,0,0,1,.5-.5h5
+ a.5,.5,0,0,1,.5,.5v3a.5,.5,0,0,1-.5,.5h-5a.5,
+ .5,0,0,1-.5-.5zM2.5,2.8a.3,.3,0,0,1,.3-.3
+ h4.4a.3,.3,0,0,1,.3,.3v2.4a.3,.3,0,0,1-.3,
+ .3h-4.4a.3,.3,0,0,1-.3-.3zM2,6.55h6l1,1.45h-8z">
+ </path>
+ </symbol>
+ </defs>
+</svg>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/glyphs.html b/web/gui/src/main/webapp/_dev/glyphs.html
new file mode 100644
index 0000000..a973936
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/glyphs.html
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright 2014 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+ ONOS -- Glyphs library test page (old version)
+ -->
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Glyphs</title>
+
+ <script src="../tp/d3.js"></script>
+
+ <style>
+ html,
+ body {
+ background-color: #ddf;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 9pt;
+ }
+
+ svg {
+ background-color: #fff;
+ }
+
+ svg .glyph {
+ stroke: none;
+ fill: black;
+ fill-rule: evenodd;
+ }
+
+ svg .icon text {
+ text-anchor: middle;
+ font-size: 5pt;
+ fill: green;
+ stroke: none;
+ }
+
+ </style>
+</head>
+<body>
+ <!-- minimal framework to access glyphs library module -->
+ <script>
+ var libs = {};
+ var ONOS = { ui: { addLib: function (id, things) { libs[id] = things; }}};
+ </script>
+
+ <!-- import the glyphs library -->
+ <script src="../glyphs.js"></script>
+
+ <svg></svg>
+
+ <!-- code to display the glyphs in the library -->
+ <script>
+ (function () {
+ var w = 1000,
+ h = 800,
+ vb = '0 0 ' + w + ' ' + h;
+
+ var svg = d3.select('svg')
+ .attr({ width: w, height: h, viewBox: vb });
+
+ // create definitions element...
+ var defs = svg.append('defs');
+
+ // create scaling group
+ var grp = svg.append('g')
+ .attr('transform', 'translate(20,20)scale(2)');
+
+ var mag = svg.append('g')
+ .attr('transform', 'translate(20,20)scale(12)');
+
+ function translate(loc) {
+ return 'translate(' + loc[0] + ',' + loc[1] +')';
+ }
+
+ function icon(what, id, loc, color, bg, size) {
+ var i = '#' + id,
+ c = color || 'black',
+ b = bg || '#eef',
+ z = size || 40,
+ g;
+
+ g = what.append('g')
+ .attr({ 'class': 'icon', transform: translate(loc) });
+
+ g.append('rect')
+ .attr({ width: z, height: z, rx: 4 })
+ .style('fill', b)
+ .style('stroke', 'black')
+ .style('stroke-width', 0.5);
+
+ g.append('use')
+ .attr({ 'class': 'glyph', width: z, height: z, 'xlink:href': i })
+ .style('fill', c);
+
+ if (id !== 'bird') {
+ g.append('text')
+ .text(id)
+ .attr({ x: z / 2, y: z + 8 })
+ }
+ }
+
+
+ // import glyphs...
+ libs.glyphs.loadDefs(defs);
+
+ // bird, top right corner
+ icon(svg, 'bird', [830,10], '#800', '#ecc', 160);
+
+ // show icons...
+ icon(grp, 'unknown', [ 0, 0]);
+ icon(grp, 'node', [ 50, 0]);
+ icon(grp, 'switch', [100, 0]);
+ icon(grp, 'roadm', [150, 0]);
+ icon(grp, 'endstation', [200, 0]);
+ icon(grp, 'router', [250, 0]);
+ icon(grp, 'bgpSpeaker', [300, 0]);
+ icon(grp, 'uiAttached', [350, 0]);
+ icon(grp, 'otn', [400, 0]);
+
+ icon(grp, 'chain', [ 0, 60]);
+ icon(grp, 'crown', [ 50, 60]);
+
+// icon(mag, 'crown', [20, 15], 'rgba(240,120,120,1)', 'transparent');
+
+ // more goodies to come soon.....
+ })();
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch01-01-hello-world-app.html b/web/gui/src/main/webapp/_dev/ng-examples/ch01-01-hello-world-app.html
new file mode 100644
index 0000000..82cfec6
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch01-01-hello-world-app.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<body ng-app>
+ <input type="text"
+ ng-model="name"
+ placeholder="Enter your name">
+
+ <h1>Hello <span ng-bind="name"></span></h1>
+ <!-- Note alternate syntax for same thig... -->
+ <h1>Hello {{ name }}</h1>
+
+ <script src="../../tp/angular.js"></script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-01-module-example.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-01-module-example.html
new file mode 100644
index 0000000..97432e3
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-01-module-example.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Hello AngularJS</title>
+
+ <script src="../../tp/angular.js"></script>
+</head>
+<body>
+ Hello {{1 + 1}}nd time AngularJS
+
+ <script type="text/javascript">
+ angular.module('notesApp', []);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-02-creating-controller.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-02-creating-controller.html
new file mode 100644
index 0000000..566c6dd
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-02-creating-controller.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Hello AngularJS</title>
+
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl">
+ Hello {{1 + 1}}nd time AngularJS
+
+ <script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ // controller specific code here
+ console.log('MainCtrl has been created');
+ }]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-03-hello-controller.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-03-hello-controller.html
new file mode 100644
index 0000000..c206bf8
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-03-hello-controller.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+ {{ctrl.helloMsg}} AngularJS.
+ <br/>
+ {{ctrl.goodbyeMsg}} AngularJS
+
+ <script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ this.helloMsg = 'Hello ';
+ var goodbyeMsg = 'Goodbye ';
+ }]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-04-controller-click-msg.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-04-controller-click-msg.html
new file mode 100644
index 0000000..4a4a22e
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-04-controller-click-msg.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+ {{ctrl.message}} AngularJS.
+
+ <button ng-click="ctrl.changeMessage()">
+ Change Message
+ </button>
+
+ <script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+ self.message = 'Hello';
+ self.changeMessage = function () {
+ self.message = 'Goodbye'
+ };
+ }]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-05-ng-repeat-example-1.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-05-ng-repeat-example-1.html
new file mode 100644
index 0000000..a262c1b
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-05-ng-repeat-example-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+ <div ng-repeat="note in ctrl.notes">
+ <span class="label"> {{note.label}} </span>
+ <!--<span class="status" ng-bind="note.done"></span>-->
+ <span class="status"> {{note.done}} </span>
+ </div>
+
+ <script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+ self.notes = [
+ {id: 1, label: 'First note', done: false},
+ {id: 2, label: 'Second note', done: false},
+ {id: 3, label: 'Done note', done: true},
+ {id: 4, label: 'Last note', done: false}
+ ]
+ }]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-06-more-directives.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-06-more-directives.html
new file mode 100644
index 0000000..254dd08
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-06-more-directives.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <style>
+ .done {
+ background-color: limegreen;
+ }
+ .pending {
+ background-color: yellow;
+ }
+ .assignee {
+ color: red;
+ font-weight: bold;
+ }
+ </style>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+ <div ng-repeat="note in ctrl.notes"
+ ng-class="ctrl.getNoteClass(note.done)">
+ <span class="label"> {{note.label}} </span>
+ <span class="assignee"
+ ng-show="note.assignee"
+ ng-bind="note.assignee">
+ </span>
+ </div>
+
+ <script type="text/javascript">
+ angular.module('notesApp', []).controller('MainCtrl', [
+ function () {
+ var self = this;
+ self.notes = [
+ {id: 1, label: 'First note', done: false, assignee: 'Simon'},
+ {id: 2, label: 'Second note', done: false},
+ {id: 3, label: 'Done note', done: true},
+ {id: 4, label: 'Last note', done: false, assignee: 'Fred'}
+ ];
+
+ self.getNoteClass = function (status) {
+ return {
+ done: status,
+ pending: !status
+ };
+ };
+ }
+ ]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-07-ng-repeat-object.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-07-ng-repeat-object.html
new file mode 100644
index 0000000..43de929
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-07-ng-repeat-object.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+ <div ng-repeat="(author, note) in ctrl.notes">
+ <span class="label"> {{note.label}} </span>
+ <span class="author" ng-bind="author"></span>
+ </div>
+
+ <script type="text/javascript">
+ angular.module('notesApp', []).controller('MainCtrl', [
+ function () {
+ var self = this;
+ self.notes = {
+ simon: { id: 1, label: 'First note', done: false},
+ Thomas: { id: 3, label: 'Finished third note', done: true},
+ alice: { id: 2, label: 'Second note', done: false}
+ };
+ }
+ ]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-08-ng-helper-vars.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-08-ng-helper-vars.html
new file mode 100644
index 0000000..cf872d9
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-08-ng-helper-vars.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <style>
+ span {
+ background-color: #cce;
+ }
+ </style>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+ <div ng-repeat="note in ctrl.notes">
+ <div>First element: {{$first}}</div>
+ <div>Middle element: {{$middle}}</div>
+ <div>Last element: {{$last}}</div>
+ <div>Index of element: {{$index}}</div>
+ <div>At even position: {{$even}}</div>
+ <div>At odd position: {{$odd}}</div>
+
+ <span class="label"> {{note.label}} </span>
+ <span class="status"> {{note.done}} </span>
+ <br/><br/>
+ </div>
+
+ <script type="text/javascript">
+ angular.module('notesApp', []).controller('MainCtrl', [
+ function () {
+ var self = this;
+ self.notes = [
+ {id: 1, label: 'First note', done: false},
+ {id: 2, label: 'Second note', done: false},
+ {id: 3, label: 'Done note', done: true},
+ {id: 4, label: 'Last note', done: false}
+ ];
+ }
+ ]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-09-ng-repeat-track-id.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-09-ng-repeat-track-id.html
new file mode 100644
index 0000000..23ad7dc
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-09-ng-repeat-track-id.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <style>
+ span {
+ background-color: #cce;
+ }
+ </style>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+ <button ng-click="ctrl.changeNotes()">Change Notes</button>
+ <br/>
+
+ DOM Elements change at every click
+ <div ng-repeat="note in ctrl.notes1">
+ {{note.$$hashKey}}
+ <span class="label"> {{note.label}} </span>
+ <span class="author"> {{note.done}} </span>
+ </div>
+ <br/>
+
+ DOM Elements are reused at every click
+ <div ng-repeat="note in ctrl.notes2 track by note.id">
+ {{note.$$hashKey}}
+ <span class="label"> {{note.label}} </span>
+ <span class="author"> {{note.done}} </span>
+ </div>
+
+ <script type="text/javascript">
+ angular.module('notesApp', []).controller('MainCtrl', [
+ function () {
+ var self = this;
+ var notes = [
+ {id: 1, label: 'First note', done: false, someRandom: 31431},
+ {id: 2, label: 'Second note', done: false},
+ {id: 3, label: 'Finished third note', done: true}
+ ];
+ self.notes1 = angular.copy(notes);
+ self.notes2 = angular.copy(notes);
+
+ self.changeNotes = function () {
+ notes = [
+ {id: 1, label: 'Changed note', done: false, someRandom: 4242},
+ {id: 2, label: 'Second note', done: false},
+ {id: 3, label: 'Finished third note', done: true}
+ ];
+ self.notes1 = angular.copy(notes);
+ self.notes2 = angular.copy(notes);
+ }
+ }
+ ]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch02-10-ng-repeat-across-elements.html b/web/gui/src/main/webapp/_dev/ng-examples/ch02-10-ng-repeat-across-elements.html
new file mode 100644
index 0000000..06a4fa7
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch02-10-ng-repeat-across-elements.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <style>
+ span {
+ background-color: #cce;
+ }
+ </style>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+ <table>
+ <tr ng-repeat-start="note in ctrl.notes">
+ <td>{{note.label}}</td>
+ </tr>
+ <tr ng-repeat-end>
+ <td>Done: {{note.done}}</td>
+ </tr>
+ </table>
+
+
+ <script type="text/javascript">
+ angular.module('notesApp', []).controller('MainCtrl', [
+ function () {
+ var self = this;
+ self.notes = [
+ {id: 1, label: 'First note', done: false},
+ {id: 2, label: 'Second note', done: false},
+ {id: 3, label: 'Finished third note', done: true}
+ ];
+ }
+ ]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-01-simple-ng-model.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-01-simple-ng-model.html
new file mode 100644
index 0000000..5c8a4b1
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-01-simple-ng-model.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <style>
+ span {
+ background-color: #cce;
+ }
+ </style>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+<input type="text" ng-model="ctrl.username"/>
+You typed {{ctrl.username}}
+
+
+<script type="text/javascript">
+ angular.module('notesApp', []).controller('MainCtrl', [
+ function () {
+ var self = this;
+ self.username = 'nothing';
+ }
+ ]);
+</script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-02-simple-ng-model2.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-02-simple-ng-model2.html
new file mode 100644
index 0000000..d02909f
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-02-simple-ng-model2.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <style>
+ span {
+ background-color: #cce;
+ }
+ </style>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+<input type="text" ng-model="ctrl.username"/>
+<input type="password" ng-model="ctrl.password"/>
+<button ng-click="ctrl.change()">Change values</button>
+<button ng-click="ctrl.submit()">Submit</button>
+
+
+
+
+<script type="text/javascript">
+ angular.module('notesApp', []).controller('MainCtrl', [
+ function () {
+ var self = this;
+ self.change = function () {
+ self.username = 'changed';
+ self.password = 'password';
+ };
+
+ self.submit = function () {
+ console.log('user clicked submit with ',
+ self.username, self.password);
+ };
+ }
+ ]);
+</script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-03-simple-form.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-03-simple-form.html
new file mode 100644
index 0000000..54a7ea4
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-03-simple-form.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <style>
+ span {
+ background-color: #cce;
+ }
+ </style>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+<!--
+ - Note, using a form has the advantage of reacting to RETURN triggering
+ - the submit, as well as pressing the submit button.
+ -->
+<form ng-submit="ctrl.submit()">
+ <input type="text" placeholder="username" ng-model="ctrl.user.username"/>
+ <input type="password" placeholder="password" ng-model="ctrl.user.password"/>
+ <input type="submit" value="Submit"/>
+ <p></p>
+ <textarea cols="60" rows="5" ng-model="ctrl.user.notes" placeholder="Notes">
+ </textarea>
+ <p>
+ NOTES:
+ <div>
+ {{ctrl.user.notes}}
+ </div>
+ </p>
+</form>
+
+<script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+
+ self.submit = function () {
+ console.log('User clicked submit with ', self.user);
+ };
+ }]);
+</script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-04-two-forms-databinding.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-04-two-forms-databinding.html
new file mode 100644
index 0000000..9cb4961
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-04-two-forms-databinding.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <style>
+ span {
+ background-color: #cce;
+ }
+ </style>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+<form ng-submit="ctrl.submit1()">
+ <input type="text" placeholder="username" ng-model="ctrl.username"/>
+ <input type="password" placeholder="password" ng-model="ctrl.password"/>
+ <input type="submit" value="Submit"/>
+</form>
+
+<!-- Better way of structuring the form data -->
+<form ng-submit="ctrl.submit2()">
+ <input type="text" placeholder="username" ng-model="ctrl.user.username"/>
+ <input type="password" placeholder="password" ng-model="ctrl.user.password"/>
+ <input type="submit" value="Submit"/>
+</form>
+
+<script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+
+ self.submit1 = function () {
+ // create user object to send to server
+ var user = {username: self.username, password: self.password};
+ console.log('First submit: ', user);
+ };
+ self.submit2 = function () {
+ console.log('Second submit: ', self.user);
+ };
+ }]);
+</script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-05-form-validation.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-05-form-validation.html
new file mode 100644
index 0000000..3501adb
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-05-form-validation.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <style>
+ span {
+ background-color: #cce;
+ }
+ </style>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+<form ng-submit="ctrl.submit()" name="myForm">
+ <input type="text"
+ placeholder="username"
+ ng-model="ctrl.user.username"
+ required
+ ng-minlength="4"/>
+
+ <input type="password"
+ placeholder="password"
+ ng-model="ctrl.user.password"
+ required/>
+
+ <input type="submit"
+ value="Submit"
+ ng-disabled="myForm.$invalid"/>
+</form>
+
+<script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+ self.submit = function () {
+ console.log('Submit: ', self.user);
+ };
+ }]);
+</script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-06-form-error-messages.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-06-form-error-messages.html
new file mode 100644
index 0000000..46c38c9
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-06-form-error-messages.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+<form ng-submit="ctrl.submit()" name="myForm">
+ <input type="text"
+ name="uname"
+ placeholder="username"
+ ng-model="ctrl.user.username"
+ required
+ ng-minlength="4"/>
+ <span ng-show="myForm.uname.$error.required">
+ This is a required field
+ </span>
+ <span ng-show="myForm.uname.$error.minlength">
+ Minimum length required is 4
+ </span>
+ <span ng-show="myForm.uname.$invalid">
+ This field is invalid
+ </span>
+ <br/>
+
+ <input type="password"
+ name="pwd"
+ placeholder="password"
+ ng-model="ctrl.user.password"
+ required/>
+ <span ng-show="myForm.pwd.$error.required">
+ This is a required field
+ </span>
+ <br/>
+
+ <input type="submit"
+ value="Submit"
+ ng-disabled="myForm.$invalid"/>
+</form>
+
+<script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+ self.submit = function () {
+ console.log('Submit: ', self.user);
+ };
+ }]);
+</script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-07-form-styling.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-07-form-styling.html
new file mode 100644
index 0000000..1b6ab86
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-07-form-styling.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <style>
+ .username.ng-valid {
+ background-color: greenyellow;
+ }
+ .username.ng-dirty.ng-invalid-required {
+ background-color: hotpink;
+ }
+ .username.ng-dirty.ng-invalid-minlength {
+ background-color: lightpink;
+ }
+ </style>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+<form ng-submit="ctrl.submit()" name="myForm">
+ <input type="text"
+ class="username"
+ name="uname"
+ placeholder="username"
+ ng-model="ctrl.user.username"
+ required
+ ng-minlength="4"/>
+
+ <input type="submit"
+ value="Submit"
+ ng-disabled="myForm.$invalid"/>
+</form>
+
+<script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+ self.submit = function () {
+ console.log('Submit: ', self.user);
+ };
+ }]);
+</script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-08-nested-forms.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-08-nested-forms.html
new file mode 100644
index 0000000..c314919
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-08-nested-forms.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html ng-app>
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<!-- no controller in this example -->
+<body>
+
+<form novalidate name="myForm">
+ <input type="text"
+ class="username"
+ name="uname"
+ ng-model="ctrl.user.username"
+ required=""
+ placeholder="Username"
+ ng-minlength="4"/>
+
+ <input type="password"
+ class="password"
+ name="pad"
+ ng-model="ctrl.user.password"
+ required=""
+ placeholder="Password"
+ required=""/>
+
+ <p/>
+
+ <ng-form name="profile">
+ <input type="text"
+ name="firstName"
+ ng-model="ctrl.user.profile.firstName"
+ placeholder="First Name"
+ required/>
+ <input type="text"
+ name="middleName"
+ ng-model="ctrl.user.profile.middleName"
+ placeholder="Middle Name"/>
+ <input type="text"
+ name="lastName"
+ ng-model="ctrl.user.profile.lastName"
+ placeholder="Last Name"
+ required/>
+
+ <input type="date"
+ name="dob"
+ placeholder="Date of birth"
+ ng-model="ctrl.user.profile.dob"/>
+ </ng-form>
+
+ <span ng-show="myForm.profile.$invalid">
+ Please fill out the profile information
+ </span>
+
+ <p/>
+
+ <input type="submit"
+ value="Submit"
+ ng-disabled="myForm.$invalid"/>
+</form>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-09-checkbox-example.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-09-checkbox-example.html
new file mode 100644
index 0000000..fe35af1
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-09-checkbox-example.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+ <div>
+ <h2>What are your favorite sports?</h2>
+ <div ng-repeat="sport in ctrl.sports">
+ <label ng-bind="sport.label"></label>
+ <div>
+ With binding:
+ <input type="checkbox"
+ ng-model="sport.selected"
+ ng-true-value="'YES'"
+ ng-false-value="'NO'"/>
+ </div>
+ <div>
+ using ng-checked:
+ <input type="checkbox"
+ ng-checked="sport.selected === 'YES'"/>
+ </div>
+ <div>
+ Current state: {{sport.selected}}
+ </div>
+ <br/>
+ </div>
+
+ </div>
+
+ <script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+ self.sports = [
+ {label: 'Basketball', selected: 'YES'},
+ {label: 'Cricket', selected: 'NO'},
+ {label: 'Soccer', selected: 'NO'},
+ {label: 'Swimming', selected: 'YES'}
+ ];
+ }]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-10-radio-buttons.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-10-radio-buttons.html
new file mode 100644
index 0000000..2a2cb83
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-10-radio-buttons.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+ <div>
+ <h2>Radio Buttons</h2>
+ <div ng-init="user.gender = 'female'">
+ <input type="radio"
+ name="gender"
+ ng-model="user.gender"
+ value="male"/>Male
+ <input type="radio"
+ name="gender"
+ ng-model="user.gender"
+ value="female"/>Female
+ </div>
+ </div>
+
+ <div>
+ <h2>Radio Buttons two</h2>
+ <div ng-init="user.gender2 = 'male'; otherGender = 'Other'">
+ <input type="radio"
+ name="gender2"
+ ng-model="user.gender2"
+ value="male"/>Male
+ <input type="radio"
+ name="gender2"
+ ng-model="user.gender2"
+ value="female"/>Female
+ <input type="radio"
+ name="gender2"
+ ng-model="user.gender2"
+ ng-value="otherGender"/>{{otherGender}}
+ </div>
+ </div>
+
+ <div>
+ <h2>Radio Buttons three</h2>
+ <div ng-repeat="ch in ctrl.choices">
+ <input type="radio"
+ name="choice"
+ ng-model="user.choice"
+ ng-value="ch"/>{{ch}}
+
+ </div>
+ </div>
+
+
+ <script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+
+ self.choices = ['foo', 'bar', 'baz', 'zoo', 'goo'];
+ }]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch04-11-select-example.html b/web/gui/src/main/webapp/_dev/ng-examples/ch04-11-select-example.html
new file mode 100644
index 0000000..a8cda33
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch04-11-select-example.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as ctrl">
+
+ <div>
+ <select ng-model="ctrl.selectedCountryId"
+ ng-options="c.id as c.label for c in ctrl.countries">
+ </select>
+ Selected Country ID: {{ctrl.selectedCountryId}}
+ </div>
+
+ <div>
+ <select ng-model="ctrl.selectedCountry"
+ ng-options="c.label for c in ctrl.countries track by c.id">
+ </select>
+ Selected Country: {{ctrl.selectedCountry}}
+ </div>
+
+ <script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+
+ self.countries = [
+ {label: 'UK', id: 1},
+ {label: 'USA', id: 2},
+ {label: 'France', id: 3},
+ {label: 'Italy', id: 4}
+ ];
+ var first = self.countries[0];
+ self.selectedCountryId = first.id;
+ self.selectedCountry = first;
+ }]);
+ </script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch05-01-need-for-service-app.js b/web/gui/src/main/webapp/_dev/ng-examples/ch05-01-need-for-service-app.js
new file mode 100644
index 0000000..4e25b0b
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch05-01-need-for-service-app.js
@@ -0,0 +1,34 @@
+// ch05-01-need-for-service-app.js
+
+angular.module('notesApp', [])
+ .controller('MainCtrl', [function () {
+ var self = this;
+ self.tab = 'first';
+ self.open = function (tab) {
+ self.tab = tab;
+ }
+ }])
+ .controller('SubCtrl', [function () {
+ var self = this;
+ self.list = [
+ {id: 0, label: 'Item 0'},
+ {id: 1, label: 'Item 1'}
+ ];
+
+ self.add = function () {
+ var n = self.list.length;
+ self.list.push({
+ id: n,
+ label: 'Item ' + n
+ });
+ }
+ }]);
+
+/*
+ NOTE: When we use controllers, they are instances that get created and
+ destroyed as we navigate across the application. Any state they
+ hold is temporary at best, and cannot be communicated to other
+ controllers.
+
+ That's why we'd use "services" instead.
+ */
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch05-01-need-for-service.html b/web/gui/src/main/webapp/_dev/ng-examples/ch05-01-need-for-service.html
new file mode 100644
index 0000000..21d17e4
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch05-01-need-for-service.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <script src="ch05-01-need-for-service-app.js"></script>
+</head>
+<body ng-controller="MainCtrl as mainCtrl">
+
+ <h1> Hello Controllers! </h1>
+ <button ng-click="mainCtrl.open('first')">Open First</button>
+ <button ng-click="mainCtrl.open('second')">Open Second</button>
+
+ <div ng-switch on="mainCtrl.tab">
+
+ <div ng-switch-when="first">
+ <div ng-controller="SubCtrl as ctrl">
+ <h3>First Tab</h3>
+ <button ng-click="ctrl.add()">Add more items</button>
+ <ul>
+ <li ng-repeat="item in ctrl.list">
+ <span ng-bind="item.label"></span>
+ </li>
+ </ul>
+ </div>
+ </div>
+
+ <div ng-switch-when="second">
+ <div ng-controller="SubCtrl as ctrl">
+ <h3>Second Tab</h3>
+ <button ng-click="ctrl.add()">Add more items</button>
+ <ul>
+ <li ng-repeat="item in ctrl.list">
+ <span ng-bind="item.label"></span>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch05-02-log-example.html b/web/gui/src/main/webapp/_dev/ng-examples/ch05-02-log-example.html
new file mode 100644
index 0000000..d516440
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch05-02-log-example.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-controller="MainCtrl as mainCtrl">
+
+ <h1> Hello Services! </h1>
+ <button ng-click="mainCtrl.logStuff()">Log something</button>
+
+ <script type="text/javascript">
+ angular.module('notesApp', [])
+ .controller('MainCtrl', ['$log', function ($log) {
+ var self = this;
+ self.logStuff = function () {
+ $log.log('The button was pressed');
+ };
+ }]);
+ </script>
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch05-03-simple-angular-service.html b/web/gui/src/main/webapp/_dev/ng-examples/ch05-03-simple-angular-service.html
new file mode 100644
index 0000000..74f2a8e
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch05-03-simple-angular-service.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html ng-app="notesApp">
+<head>
+ <title>Notes App</title>
+ <script src="../../tp/angular.js"></script>
+ <script src="ch05-03-simple-angular-service.js"></script>
+</head>
+<body ng-controller="MainCtrl as mainCtrl">
+
+ <h1> Hello Controllers! </h1>
+
+ <button ng-click="mainCtrl.open('first')"> Open First </button>
+ <button ng-click="mainCtrl.open('second')"> Open Second </button>
+
+ <div ng-switch on="mainCtrl.tab">
+
+ <div ng-switch-when="first">
+ <div ng-controller="SubCtrl as ctrl">
+ <h3>First Tab</h3>
+ <button ng-click="ctrl.add()">Add item</button>
+ <ul>
+ <li ng-repeat="item in ctrl.list()">
+ <span ng-bind="item.label"></span>
+ </li>
+ </ul>
+ </div>
+ </div>
+
+ <div ng-switch-when="second">
+ <div ng-controller="SubCtrl as ctrl">
+ <h3>Second Tab</h3>
+ <button ng-click="ctrl.add()">Add item</button>
+ <ul>
+ <li ng-repeat="item in ctrl.list()">
+ <span ng-bind="item.label"></span>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch05-03-simple-angular-service.js b/web/gui/src/main/webapp/_dev/ng-examples/ch05-03-simple-angular-service.js
new file mode 100644
index 0000000..25786be
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch05-03-simple-angular-service.js
@@ -0,0 +1,115 @@
+// ch05-03-simple-angular-service.js
+
+// this example shows three different ways of defining our own "service"...
+
+// use 'factory()' for functions/plain objects API
+// use 'service()' for JS class object API
+// use 'provider()' for configurable service API
+
+
+// this is a service definition
+function ItemServiceTwo() {
+ var items = [
+ {id: 0, label: 'Item 0'},
+ {id: 1, label: 'Item 1'}
+ ];
+ this.list = function () {
+ return items;
+ };
+ this.add = function (item) {
+ items.push(item);
+ };
+}
+
+// this is a provider definition
+function ItemServiceThree(optItems) {
+ var items = optItems || [];
+
+ this.list = function () {
+ return items;
+ };
+ this.add = function (item) {
+ items.push(item);
+ }
+}
+
+angular.module('notesApp', [])
+
+ // [provider] define item service as configurable provider
+ .provider('ItemServiceThree', function () {
+ var haveDefaultItems = true;
+
+ this.disableDefaultItems = function () {
+ haveDefaultItems = false;
+ };
+
+ // this function gets our dependencies..
+ this.$get = [function () {
+ var optItems = [];
+ if (haveDefaultItems) {
+ optItems = [
+ {id: 0, label: 'Item 0'},
+ {id: 1, label: 'Item 1'}
+ ];
+ }
+ return new ItemServiceThree(optItems);
+ }];
+ })
+
+ // [provider] define configuration for provider
+ .config(['ItemServiceThreeProvider', function (ItemServiceThreeProvider) {
+ // to see how the provider can change configuration
+ // change the value of shouldHaveDefaults to true and
+ // try running the example
+ var shouldHaveDefaults = false;
+
+ // get configuration from server.
+ // set shouldHaveDefaults somehow
+ // assume it magically changes for now
+ if (!shouldHaveDefaults) {
+ ItemServiceThreeProvider.disableDefaultItems();
+ }
+ }])
+
+ // [service] define item service as a JS class
+ .service('ItemServiceTwo', [ItemServiceTwo])
+
+ // [factory] define item service factory
+ .factory('ItemService', [function () {
+ var items = [
+ {id: 0, label: 'Item 0'},
+ {id: 1, label: 'Item 1'}
+ ];
+ return {
+ list: function () {
+ return items;
+ },
+ add: function (item) {
+ items.push(item);
+ }
+ };
+ }])
+
+ // ======================================================================
+ // define controllers...
+ .controller('MainCtrl', [function () {
+ var self = this;
+ self.tab = 'first';
+ self.open = function (tab) {
+ self.tab = tab;
+ };
+ }])
+
+ .controller('SubCtrl', ['ItemService', function (ItemService) {
+ var self = this;
+ self.list = function () {
+ return ItemService.list();
+ };
+ self.add = function () {
+ var n = self.list().length;
+ ItemService.add({
+ id: n,
+ label: 'Item ' + n
+ });
+ };
+ }]);
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch08-01-filter-example.html b/web/gui/src/main/webapp/_dev/ng-examples/ch08-01-filter-example.html
new file mode 100644
index 0000000..105209c
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch08-01-filter-example.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Filters in Action</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-app="filtersApp">
+
+ <div ng-controller="FilterCtrl as ctrl">
+ <div>
+ Amount as a number: {{ctrl.amount | number}}
+ </div>
+ <div>
+ Total cost as a currency: {{ctrl.totalCost | currency}}
+ </div>
+ <div>
+ Total cost in GBP: {{ctrl.totalCost | currency:'GBP '}}
+ </div>
+ <div>
+ Shout: {{ctrl.name | uppercase}}
+ </div>
+ <div>
+ Whisper: {{ctrl.name | lowercase}}
+ </div>
+ <div>
+ Start time: {{ctrl.startTime | date:'medium'}}
+ </div>
+ <div>
+ as JSON: {{ctrl.struct | json}}
+ </div>
+ </div>
+
+ <script type="text/javascript">
+ angular.module('filtersApp', [])
+ .controller('FilterCtrl', [function () {
+ var self = this;
+ self.amount = 1024;
+ self.totalCost = 4906;
+ self.name = 'Onos Rocks!';
+ self.startTime = new Date().getTime();
+ self.struct = {
+ foo: 'bar',
+ baz: 3.1415
+ };
+ }]);
+ </script>
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch08-02-filter-number-string.html b/web/gui/src/main/webapp/_dev/ng-examples/ch08-02-filter-number-string.html
new file mode 100644
index 0000000..46e9c4d
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch08-02-filter-number-string.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Filters in Action</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-app="filtersApp">
+
+ <ul ng-controller="FilterCtrl as ctrl">
+ <li>
+ Amount - {{ctrl.amount}}
+ </li>
+ <li>
+ Amount - Default Currency: {{ctrl.amount | currency}}
+ </li>
+ <li>
+ <!-- Using English pound sign -->
+ Amount - GBP Currency: {{ctrl.amount | currency:'£'}}
+ </li>
+ <li>
+ Amount - Number: {{ctrl.amount | number }}
+ </li>
+ <li>
+ Amount - Number (4 decimals): {{ctrl.amount | number:4}}
+ </li>
+ <li>
+ Amount - Yummy π = {{ctrl.pi | number:4 }}
+ </li>
+
+ <li>
+ Name - no filters: {{ctrl.name}}
+ </li>
+ <li>
+ Name - lowercase: {{ctrl.name | lowercase}}
+ </li>
+ <li>
+ Name - uppercase: {{ctrl.name | uppercase}}
+ </li>
+ <li>
+ Name - prefix: {{ctrl.name | limitTo:4}}
+ </li>
+
+ <li>
+ JSON filter: {{ctrl.struct | json}}
+ </li>
+
+ <li>
+ Timestamp: {{ctrl.startTime}}
+ </li>
+ <li>
+ Default Date filter: {{ctrl.startTime | date}}
+ </li>
+ <li>
+ Medium Date filter: {{ctrl.startTime | date:'medium'}}
+ </li>
+ <li>
+ Long Date filter: {{ctrl.startTime | date:'longDate'}}
+ </li>
+ <li>
+ Custom Date filter: {{ctrl.startTime | date:'M/dd, yyyy'}}
+ </li>
+ <li>
+ Custom Time filter: {{ctrl.startTime | date:'h:m a'}}
+ </li>
+ </ul>
+
+ <script type="text/javascript">
+ angular.module('filtersApp', [])
+ .controller('FilterCtrl', [function () {
+ var self = this;
+ self.amount = 1024;
+ self.totalCost = 4906;
+ self.name = 'Onos Rocks!';
+ self.startTime = new Date().getTime();
+ self.struct = {
+ foo: 'bar',
+ baz: 3.1415
+ };
+ self.pi = Math.PI;
+ }]);
+ </script>
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch08-03-filter-arrays.html b/web/gui/src/main/webapp/_dev/ng-examples/ch08-03-filter-arrays.html
new file mode 100644
index 0000000..a9ce3ca
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch08-03-filter-arrays.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Filters in Action</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-app="filtersApp">
+
+ <div ng-controller="FilterCtrl as ctrl">
+
+ <table>
+ <tr>
+ <td>
+ <button ng-click="ctrl.currentFilter = 'string'">
+ Filter with string
+ </button>
+ </td>
+ <td>
+ Filter Text
+ <input type="text"
+ ng-model="ctrl.filterOptions['string']"/>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <button ng-click="ctrl.currentFilter = 'object'">
+ Filter with object
+ </button>
+ </td>
+ <td>
+ Show Done or Not Done
+ <input type="checkbox"
+ ng-model="ctrl.filterOptions['object'].done"/>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <button ng-click="ctrl.currentFilter = 'function'">
+ Filter with function
+ </button>
+ </td>
+ </tr>
+ </table>
+ <ul>
+ <li ng-repeat="note in ctrl.notes |
+ filter:ctrl.filterOptions[ctrl.currentFilter] |
+ orderBy:ctrl.sortOrder |
+ limitTo:5">
+ {{note.label}} - {{note.type}} - {{note.done}}
+ </li>
+ </ul>
+ </div>
+
+
+ <script type="text/javascript">
+ angular.module('filtersApp', [])
+ .controller('FilterCtrl', [function () {
+ var self = this;
+
+ self.notes = [
+ {label: 'FC Todo', type: 'chore', done: false},
+ {label: 'FT Todo', type: 'task', done: false},
+ {label: 'FF Todo', type: 'fun', done: true},
+ {label: 'SC Todo', type: 'chore', done: false},
+ {label: 'ST Todo', type: 'task', done: true},
+ {label: 'SF Todo', type: 'fun', done: true},
+ {label: 'TC Todo', type: 'chore', done: false},
+ {label: 'TT Todo', type: 'task', done: false},
+ {label: 'TF Todo', type: 'fun', done: false}
+ ];
+
+ self.sortOrder = ['+type', '-label'];
+
+ self.filterOptions = {
+ 'string': '',
+ 'object': {done: false, label: 'F'},
+ 'function': function (note) {
+ return note.type === 'task' && note.done === false;
+ }
+ };
+
+ self.currentFilter = 'string';
+ }]);
+ </script>
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch08-04-custom-filters.html b/web/gui/src/main/webapp/_dev/ng-examples/ch08-04-custom-filters.html
new file mode 100644
index 0000000..f39991d
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch08-04-custom-filters.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Custom Filters in Action</title>
+ <script src="../../tp/angular.js"></script>
+</head>
+<body ng-app="filtersApp">
+
+ <div ng-controller="FilterCtrl as ctrl">
+ <div>
+ Start time (Timestamp): {{ctrl.startTime}}
+ </div>
+ <div>
+ Start time (Time): {{ctrl.startTime | date:'h:m a'}}
+ </div>
+ <div>
+ Start time (Our filter): {{ctrl.startTime | timeAgo}}
+ </div>
+ <div>
+ Start time (Our filter 2): {{ctrl.startTime | timeAgo:true}}
+ </div>
+ <div>
+ Some time ago (Computed): {{ctrl.someTimeAgo | date:'h:m a'}}
+ </div>
+ <div>
+ Some time ago (Our filter): {{ctrl.someTimeAgo | timeAgo}}
+ </div>
+ </div>
+
+ <script type="text/javascript">
+ angular.module('filtersApp', [])
+ .controller('FilterCtrl', [function () {
+ var self = this;
+ self.startTime = new Date().getTime();
+ self.someTimeAgo = self.startTime - (1000*3600*4);
+ }])
+ .filter('timeAgo', [function () {
+ var _m = 1000 * 60,
+ _h = _m * 60,
+ _d = _h * 24,
+ _mon = _d * 30;
+
+ return function (ts, ignoreSecs) {
+ var now = new Date().getTime(),
+ diff = now - ts;
+ if (diff < _m && !ignoreSecs) {
+ return 'seconds ago';
+ } else if (diff < _h) {
+ return 'minutes ago';
+ } else if (diff < _d) {
+ return 'hours ago';
+ } else if (diff < _mon) {
+ return 'days ago';
+ } else {
+ return 'months ago';
+ }
+ }
+ }]);
+ </script>
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/ch10-01-simple-routing.html b/web/gui/src/main/webapp/_dev/ng-examples/ch10-01-simple-routing.html
new file mode 100644
index 0000000..2961412
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/ch10-01-simple-routing.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Simple Routing</title>
+ <script src="../../tp/angular.js"></script>
+ <script src="../../tp/angular-route.js"></script>
+</head>
+<body ng-app="routingApp">
+
+ <h2>Angular Routing</h2>
+
+ <ul>
+ <li><a href="#/">Default Route</a></li>
+ <li><a href="#/second">Second Route</a></li>
+ <li><a href="#/asdfertdfghsdfg">Non-existent Route</a></li>
+ </ul>
+
+ <div ng-view></div>
+
+ <script type="text/javascript">
+ angular.module('routingApp', ['ngRoute'])
+ .config(['$routeProvider', function ($routeProvider) {
+ $routeProvider
+ .when('/', {
+ template: '<h5>This is the default route</h5>'
+ })
+ .when('/second', {
+ template: '<h5>This is the second route</h5>'
+ })
+ .otherwise({
+ redirectTo: '/'
+ });
+ }]);
+ </script>
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/js/ch03-controller.js b/web/gui/src/main/webapp/_dev/ng-examples/js/ch03-controller.js
new file mode 100644
index 0000000..92d3b0c
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/js/ch03-controller.js
@@ -0,0 +1,17 @@
+// Simple controller
+
+angular.module('notesApp', [])
+ .controller('ListCtrl', [function () {
+ var self = this;
+ self.items = [
+ {id: 1, label: 'First', done: true},
+ {id: 2, label: 'Second', done: false}
+ ];
+
+ self.getDoneClass = function (item) {
+ return {
+ finished: item.done,
+ unfinished: !item.done
+ };
+ };
+ }]);
diff --git a/web/gui/src/main/webapp/_dev/ng-examples/js/ch09-01-time-ago.js b/web/gui/src/main/webapp/_dev/ng-examples/js/ch09-01-time-ago.js
new file mode 100644
index 0000000..1a8b7f1
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/ng-examples/js/ch09-01-time-ago.js
@@ -0,0 +1,27 @@
+// ch09-01-time-ago.js
+
+angular.module('filterApp', [])
+ .filter('timeAgo', [function () {
+ var _m = 1000 * 60,
+ _h = _m * 60,
+ _d = _h * 24,
+ _mon = _d * 30;
+
+ return function (ts, ignoreSecs) {
+ var showSecs = !ignoreSecs,
+ now = new Date().getTime(),
+ diff = now - ts;
+
+ if (diff < _m && showSecs) {
+ return 'seconds ago';
+ } else if (diff < _h) {
+ return 'minutes ago';
+ } else if (diff < _d) {
+ return 'hours ago';
+ } else if (diff < _mon) {
+ return 'days ago';
+ } else {
+ return 'months ago';
+ }
+ }
+ }]);
diff --git a/web/gui/src/main/webapp/_dev/oblique.html b/web/gui/src/main/webapp/_dev/oblique.html
new file mode 100644
index 0000000..e54d18f
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/oblique.html
@@ -0,0 +1,473 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright 2014 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+ Testing transformations for transitioning between overhead and
+ perspective projections of two layers.
+ -->
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Layer Transformations</title>
+
+ <script src="../tp/d3.js"></script>
+ <script src="../tp/jquery-2.1.1.min.js"></script>
+
+ <style>
+ html,
+ body {
+ background-color: #ccc;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 9pt;
+ }
+
+ svg {
+ position: absolute;
+ background-color: #fff;
+ top: 30px;
+ left: 60px;
+ }
+
+ svg text {
+ font-size: 3pt;
+ }
+
+ </style>
+</head>
+<body>
+ <svg width="1000px" height="600px" viewBox="0 0 160 120"></svg>
+
+ <script>
+ (function (){
+
+ // Configuration...
+ var w = 160,
+ h = 120,
+ time = 1500;
+
+ var pktData = [
+ [20,60,'a'],
+ [60,20,'b'],
+ [100,20,'c'],
+ [140,60,'d'],
+ [100,100,'e'],
+ [60,100,'f'],
+ [20,20,'w'],
+ [140,20,'x'],
+ [20,100,'y'],
+ [140,100,'z']
+ ],
+ optData = [
+ [40,40,'p'],
+ [120,40,'q'],
+ [120,80,'r'],
+ [40,80,'s'],
+ [20,20,'j'],
+ [140,20,'k'],
+ [20,100,'l'],
+ [140,100,'m']
+ ],
+ linkData = [
+ ['a','p'],
+ ['p','b'],
+ ['b','c'],
+ ['c','q'],
+ ['q','d'],
+ ['d','r'],
+ ['r','e'],
+ ['e','f'],
+ ['f','s'],
+ ['s','a'],
+ ['s','q'],
+ ['p','r'],
+ ['b','f'],
+ ['c','e'],
+ ['w','j'],
+ ['x','k'],
+ ['z','m'],
+ ['y','l']
+ ];
+
+ // Transform parameters
+ var tf = {
+ tt: -.7, // x skew y factor
+ xsk: -35, // x skew angle
+ ysc: 0.5, // y scale
+ ytr: 50, // y translate
+ pad: 5
+ },
+ rectFill = {
+ pkt: 'rgba(130,130,170,0.3)',
+ opt: 'rgba(170,130,170,0.3)'
+ };
+
+ // Internal state...
+ var nodes = [],
+ links = [],
+ overhead = true,
+ xffn;
+
+ // D3/DOM magic...
+ var svg = d3.select('svg'),
+ nodeG,
+ linkG,
+ node,
+ link,
+ force,
+ pktLayer,
+ optLayer;
+
+
+ // General functions ...
+ function isF(f) {
+ return $.isFunction(f) ? f : null;
+ }
+
+ function translate(x,y) {
+ return 'translate(' + x + ',' + y + ')';
+ }
+
+ function scale(x,y) {
+ return 'scale(' + x + ',' + y + ')';
+ }
+ function skewX(x) {
+ return 'skewX(' + x + ')';
+ }
+
+
+ // Key Bindings...
+ var keyHandler = {
+ T: transform
+ };
+
+ function whatKey(code) {
+ switch (code) {
+ case 13: return 'enter';
+ case 16: return 'shift';
+ case 17: return 'ctrl';
+ case 18: return 'alt';
+ case 27: return 'esc';
+ case 32: return 'space';
+ case 37: return 'leftArrow';
+ case 38: return 'upArrow';
+ case 39: return 'rightArrow';
+ case 40: return 'downArrow';
+ case 91: return 'cmdLeft';
+ case 93: return 'cmdRight';
+ case 187: return 'equals';
+ case 189: return 'dash';
+ case 191: return 'slash';
+ default:
+ if ((code >= 48 && code <= 57) ||
+ (code >= 65 && code <= 90)) {
+ return String.fromCharCode(code);
+ } else if (code >= 112 && code <= 123) {
+ return 'F' + (code - 111);
+ }
+ return '.';
+ }
+ }
+
+ function keyIn() {
+ var event = d3.event,
+ keyCode = event.keyCode,
+ key = whatKey(keyCode),
+ fn = isF(keyHandler[key]);
+ if (fn) {
+ fn(key, keyCode, event);
+ }
+ }
+
+ // Key events....
+ function transform() {
+ overhead = !overhead;
+ if (overhead) {
+ toOverhead();
+ } else {
+ toOblique();
+ }
+ }
+
+ function toOverhead() {
+ xffn = null;
+ hidePlane(pktLayer);
+ hidePlane(optLayer);
+ transitionNodes();
+ }
+
+ function padBox(box, p) {
+ box.x -= p;
+ box.y -= p;
+ box.width += p*2;
+ box.height += p*2;
+ }
+
+ function toOblique() {
+ var box = nodeG.node().getBBox();
+ padBox(box, tf.pad);
+
+ xffn = function (xy, dir) {
+ var x = xy.x + xy.y*tf.tt,
+ y = xy.y*tf.ysc + tf.ysc*tf.ytr*dir;
+ return { x: x, y: y};
+ };
+
+ showPlane(pktLayer, box, -1);
+ showPlane(optLayer, box, 1);
+ transitionNodes();
+ }
+
+ function transitionNodes() {
+ // note: turn off force layout while transitioning.. if it is on
+// force.stop();
+
+ if (xffn) {
+ nodes.forEach(function (d) {
+ var dir = d.type === 'pkt' ? -1 : 1,
+ oldxy = {x: d.x, y: d.y},
+ coords = xffn(oldxy, dir);
+ d.oldxy = oldxy;
+ d.x = coords.x;
+ d.y = coords.y;
+ });
+ } else {
+ nodes.forEach(function (d) {
+ d.x = d.oldxy.x;
+ d.y = d.oldxy.y;
+ delete d.oldxy;
+ });
+ }
+
+ nodeG.selectAll('.node')
+ .transition()
+ .duration(time)
+ .attr({
+ transform: function (d) {
+ return translate(d.x, d.y);
+ }
+ });
+
+ linkG.selectAll('.link')
+ .transition()
+ .duration(time)
+ .attr({
+ x1: function (d) { return d.source.x; },
+ y1: function (d) { return d.source.y; },
+ x2: function (d) { return d.target.x; },
+ y2: function (d) { return d.target.y; }
+ });
+ }
+
+ function showPlane(layer, box, dir) {
+ layer.select('rect')
+ .attr(box)
+ .attr('opacity', 0)
+ .transition()
+ .duration(time)
+ .attr('opacity', 1)
+ .attr('transform', obliqueXform(dir));
+ }
+
+ function hidePlane(layer) {
+ var rect = layer.select('rect');
+ rect.transition()
+ .duration(time)
+ .attr('opacity', 0)
+ .attr('transform', overheadXform());
+
+ }
+
+ function obliqueXform(dir) {
+ return scale(1, tf.ysc) + translate(0, dir * tf.ytr) + skewX(tf.xsk);
+ }
+
+
+ function overheadXform() {
+ return skewX(0) + translate(0,0) + scale(1,1);
+ }
+
+ // Nodes and Links...
+ function prepareNodes() {
+ var hw = w/2,
+ hh = h/2;
+
+ function addNode(t, d) {
+ nodes.push({
+ type: t,
+ x: d[0] - hw,
+ y: d[1] - hh,
+ id: d[2],
+ fixed: true
+ });
+ }
+
+ optData.forEach(function (d) {
+ addNode('opt', d);
+ });
+ pktData.forEach(function (d) {
+ addNode('pkt', d);
+ });
+ }
+
+ function findNode(id) {
+ for (var i=0,n=nodes.length; i<n; i++) {
+ if (nodes[i].id === id) {
+ return nodes[i];
+ }
+ }
+ return null;
+ }
+
+ function prepareLinks() {
+ linkData.forEach(function (d) {
+ var src = d[0],
+ dst = d[1];
+ links.push({
+ id: src + '-' + dst,
+ source: findNode(src),
+ target: findNode(dst)
+ });
+ });
+
+ }
+
+ function updateNodes() {
+ node = nodeG.selectAll('.node')
+ .data(nodes, function (d) { return d.id; });
+
+ var entering = node.enter()
+ .append('g').attr({
+ id: function (d) { return d.id; },
+ 'class': function (d) { return 'node ' + d.type; }
+ });
+
+ entering.each(function (d) {
+ var el = d3.select(this);
+ d.el = el;
+
+ el.append('rect').attr({
+ width: 5,
+ height: 5,
+ fill: function (d) {
+ return d.type === 'pkt' ? '#669' : '#969';
+ },
+ rx: 1,
+ transform: 'translate(-2.5,-2.5)'
+ });
+ el.append('text')
+ .text(d.id)
+ .attr({
+ dy: '0.9em',
+ 'text-anchor': 'middle',
+ transform: 'translate(0,-2.5)',
+ fill: 'white'
+ });
+ });
+ }
+
+ function updateLinks() {
+ link = linkG.selectAll('.link')
+ .data(links, function (d) { return d.id; });
+
+ var entering = link.enter()
+ .append('line').attr({
+ id: function (d) { return d.id; },
+ class: 'link',
+ stroke: '#888',
+ 'stroke-width': 0.4,
+ opacity: 0.7
+ });
+
+ entering.each(function (d) {
+ d.el = d3.select(this);
+
+ });
+ }
+
+ function update() {
+ updateNodes();
+ updateLinks();
+ }
+
+ var ntick = 0;
+ function tick() {
+ console.log('tick ' + (++ntick));
+ node.attr({
+ transform: function (d) { return translate(d.x, d.y); }
+ });
+
+ link.attr({
+ x1: function (d) { return d.source.x; },
+ y1: function (d) { return d.source.y; },
+ x2: function (d) { return d.target.x; },
+ y2: function (d) { return d.target.y; }
+ });
+ }
+
+ function setOrigin(/*varargs*/) {
+ var i, n, g;
+ for (i= 0,n=arguments.length; i< n; i++) {
+ g = arguments[i];
+ g.attr('transform', translate(w/2, h/2));
+ }
+ }
+
+ function initLayers() {
+ optLayer.attr('class', 'layer').append('rect')
+ .attr('fill', rectFill.opt);
+ pktLayer.attr('class', 'layer').append('rect')
+ .attr('fill', rectFill.pkt);
+ }
+
+ function init() {
+ svg.append('text')
+ .text('Press the "T" key....')
+ .attr({ dy: '1.2em', fill: '#999'})
+ .style('font-size', '2.4pt')
+ .style('font-style', 'italic');
+
+ optLayer = svg.append('g').attr('id', 'optLayer');
+ pktLayer = svg.append('g').attr('id', 'pktLayer');
+ linkG = svg.append('g').attr('id', 'links');
+ nodeG = svg.append('g').attr('id', 'nodes');
+
+ setOrigin(optLayer, pktLayer, linkG, nodeG);
+
+ node = nodeG.selectAll('.node');
+ link = linkG.selectAll('.link');
+
+ initLayers();
+ prepareNodes();
+ prepareLinks();
+
+ force = d3.layout.force()
+ .size([w,h])
+ .nodes(nodes)
+ .links(links)
+ .gravity(0.4)
+ .friction(0.7)
+ .on('tick', tick);
+ update();
+ tick();
+ d3.select('body').on('keydown', keyIn);
+ }
+
+ init();
+ })();
+ </script>
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/onos-logo.svg b/web/gui/src/main/webapp/_dev/onos-logo.svg
new file mode 100644
index 0000000..db4b81a
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/onos-logo.svg
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 792 612" enable-background="new 0 0 792 612" xml:space="preserve">
+<g>
+ <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="293.4264" y1="313.4543" x2="293.7567" y2="294.5293">
+ <stop offset="0" style="stop-color:#007EC5"/>
+ <stop offset="1" style="stop-color:#00C0ED"/>
+ </linearGradient>
+ <path fill="url(#SVGID_1_)" d="M308,377.4c1.7,0,3.2-0.3,4.3-1c1.1-0.6,2-1.4,2.6-2.3c0.6-0.9,1.1-1.9,1.3-3c0.2-1.1,0.3-2.1,0.3-3
+ c0-0.9-0.1-1.9-0.3-3c-0.2-1.1-0.7-2.1-1.3-3c-0.6-0.9-1.5-1.7-2.6-2.3c-1.1-0.6-2.6-1-4.3-1h-31c-1.8,0-3.2,0.3-4.3,1
+ c-1.1,0.6-2,1.4-2.6,2.3c-0.6,0.9-1.1,1.9-1.3,3c-0.2,1.1-0.3,2.1-0.3,3c0,0.9,0.1,1.9,0.3,3c0.2,1.1,0.7,2.1,1.3,3
+ c0.6,0.9,1.5,1.7,2.6,2.3c1.1,0.6,2.5,1,4.3,1H308L308,377.4z M323.7,368c0,1.9-0.3,3.9-1,5.9c-0.6,2-1.6,3.8-2.8,5.4
+ c-1.2,1.6-2.7,2.9-4.5,4c-1.7,1-3.7,1.5-5.9,1.5h-35c-2.1-0.1-4-0.7-5.6-1.7c-1.6-1.1-3-2.4-4.2-4c-1.2-1.6-2-3.4-2.6-5.3
+ c-0.6-1.9-0.9-3.9-0.9-5.8c0-1.9,0.3-3.9,1-5.9c0.6-2,1.6-3.8,2.8-5.4c1.2-1.6,2.7-2.9,4.5-4c1.7-1,3.7-1.5,5.9-1.5h35
+ c2.1,0.1,4,0.7,5.6,1.7c1.6,1,3,2.4,4.2,4c1.2,1.6,2,3.4,2.6,5.3C323.4,364.2,323.7,366.1,323.7,368z"/>
+ <linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="364.0253" y1="215.4108" x2="366.8113" y2="55.7995">
+ <stop offset="0" style="stop-color:#007EC5"/>
+ <stop offset="1" style="stop-color:#00C0ED"/>
+ </linearGradient>
+ <path fill="url(#SVGID_2_)" d="M383.7,368c0-0.9-0.1-1.9-0.3-3c-0.2-1.1-0.7-2.1-1.3-3c-0.6-0.9-1.5-1.7-2.6-2.3s-2.6-1-4.3-1
+ h-27.7c-1.8,0-3.2,0.3-4.3,1c-1.1,0.6-2,1.4-2.6,2.3c-0.6,0.9-1.1,1.9-1.3,3c-0.2,1.1-0.3,2.1-0.3,3v13.1c0,1-0.4,1.9-1.1,2.6
+ c-0.7,0.7-1.6,1.1-2.6,1.1c-1,0-1.9-0.4-2.6-1.1c-0.7-0.7-1.1-1.6-1.1-2.6V368c0-1.9,0.3-3.9,1-5.9c0.6-2,1.6-3.8,2.8-5.4
+ c1.2-1.6,2.7-2.9,4.5-4c1.7-1,3.7-1.5,5.9-1.5h32.2c2.1,0.1,4,0.7,5.6,1.7c1.6,1,3,2.4,4.2,4c1.2,1.6,2,3.4,2.6,5.3
+ c0.6,1.9,0.9,3.9,0.9,5.8v13.1c0,1-0.4,1.9-1.1,2.6c-0.7,0.7-1.6,1.1-2.6,1.1c-1,0-1.9-0.4-2.6-1.1c-0.7-0.7-1.1-1.6-1.1-2.6V368z"
+ />
+ <linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="429.6967" y1="386.7026" x2="430.0228" y2="368.0231">
+ <stop offset="0" style="stop-color:#007EC5"/>
+ <stop offset="1" style="stop-color:#00C0ED"/>
+ </linearGradient>
+ <path fill="url(#SVGID_3_)" d="M445.5,377.4c1.7,0,3.2-0.3,4.3-1c1.1-0.6,2-1.4,2.6-2.3c0.6-0.9,1.1-1.9,1.3-3
+ c0.2-1.1,0.3-2.1,0.3-3c0-0.9-0.1-1.9-0.3-3c-0.2-1.1-0.7-2.1-1.3-3c-0.6-0.9-1.5-1.7-2.6-2.3c-1.1-0.6-2.6-1-4.3-1h-31
+ c-1.8,0-3.2,0.3-4.3,1c-1.1,0.6-2,1.4-2.6,2.3c-0.6,0.9-1.1,1.9-1.3,3c-0.2,1.1-0.3,2.1-0.3,3c0,0.9,0.1,1.9,0.3,3
+ c0.2,1.1,0.7,2.1,1.3,3c0.6,0.9,1.5,1.7,2.6,2.3c1.1,0.6,2.5,1,4.3,1H445.5L445.5,377.4z M461.3,368c0,1.9-0.3,3.9-1,5.9
+ c-0.6,2-1.6,3.8-2.8,5.4c-1.2,1.6-2.7,2.9-4.5,4c-1.7,1-3.7,1.5-5.9,1.5h-35c-2.1-0.1-4-0.7-5.6-1.7c-1.6-1.1-3-2.4-4.2-4
+ c-1.2-1.6-2-3.4-2.6-5.3c-0.6-1.9-0.9-3.9-0.9-5.8c0-1.9,0.3-3.9,1-5.9c0.6-2,1.6-3.8,2.8-5.4c1.2-1.6,2.7-2.9,4.5-4
+ c1.7-1,3.7-1.5,5.9-1.5h35c2.1,0.1,4,0.7,5.6,1.7c1.6,1,3,2.4,4.2,4c1.2,1.6,2,3.4,2.6,5.3C461,364.2,461.3,366.1,461.3,368z"/>
+ <linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="499.3867" y1="424.4887" x2="499.7166" y2="405.5856">
+ <stop offset="0" style="stop-color:#007EC5"/>
+ <stop offset="1" style="stop-color:#00C0ED"/>
+ </linearGradient>
+ <path fill="url(#SVGID_4_)" d="M479.2,371.7c-1.4,0-2.8-0.3-4-0.8c-1.2-0.5-2.3-1.3-3.2-2.2c-0.9-0.9-1.7-2-2.2-3.2
+ c-0.5-1.2-0.8-2.6-0.8-4c0-1.4,0.3-2.8,0.8-4c0.5-1.2,1.3-2.3,2.2-3.2c0.9-0.9,2-1.7,3.2-2.2c1.2-0.5,2.6-0.8,4-0.8h46.6
+ c1,0,1.9,0.4,2.6,1.1c0.7,0.7,1.1,1.6,1.1,2.6c0,1-0.4,1.9-1.1,2.6c-0.7,0.7-1.6,1.1-2.6,1.1H479c-0.8,0-1.4,0.3-2,0.8
+ c-0.6,0.5-0.9,1.2-0.9,2c0,0.8,0.3,1.4,0.9,2c0.6,0.6,1.3,0.8,2,0.8h42.5c1.4,0,2.8,0.3,4,0.8c1.3,0.5,2.3,1.3,3.3,2.2
+ c0.9,0.9,1.7,2,2.2,3.3c0.5,1.3,0.8,2.6,0.8,4c0,1.4-0.3,2.8-0.8,4c-0.5,1.2-1.3,2.3-2.2,3.2c-0.9,0.9-2,1.6-3.3,2.2
+ c-1.3,0.5-2.6,0.8-4,0.8H475c-1,0-1.9-0.4-2.6-1.1c-0.7-0.7-1.1-1.6-1.1-2.6c0-1,0.4-1.9,1.1-2.6c0.7-0.7,1.6-1.1,2.6-1.1h46.8
+ c0.8,0,1.4-0.3,2-0.8c0.6-0.5,0.8-1.2,0.8-2c0-0.8-0.3-1.5-0.8-2.1c-0.6-0.6-1.2-0.8-2-0.8H479.2z"/>
+</g>
+<g>
+ <g>
+ <path fill="#007EC5" d="M263,404.8c-1.2-1.2-1.8-2.7-1.8-4.6c0-1.9,0.6-3.4,1.8-4.6c1.2-1.2,2.7-1.8,4.5-1.8
+ c1.8,0,3.3,0.6,4.5,1.8c1.2,1.2,1.8,2.7,1.8,4.6c0,1.9-0.6,3.4-1.8,4.6c-1.2,1.2-2.7,1.8-4.5,1.8C265.6,406.6,264.1,406,263,404.8
+ L263,404.8z M263.7,396.4c-0.9,1-1.4,2.3-1.4,3.8c0,1.5,0.5,2.8,1.4,3.8c0.9,1,2.2,1.5,3.7,1.5c1.6,0,2.8-0.5,3.7-1.5
+ c0.9-1,1.4-2.3,1.4-3.8c0-1.5-0.5-2.8-1.4-3.8c-0.9-1-2.2-1.5-3.7-1.5C265.9,394.9,264.7,395.4,263.7,396.4z"/>
+ <path fill="#007EC5" d="M276.5,410.2v-11.8h1v1.4h0c0.3-0.5,0.7-0.9,1.3-1.2c0.6-0.3,1.2-0.4,1.8-0.4c1.2,0,2.2,0.4,3,1.2
+ c0.8,0.8,1.2,1.8,1.2,3c0,1.2-0.4,2.2-1.2,3c-0.8,0.8-1.8,1.2-3,1.2c-0.6,0-1.3-0.1-1.8-0.4c-0.6-0.3-1-0.7-1.3-1.2h0v5.3H276.5
+ L276.5,410.2z M278.4,400c-0.6,0.6-1,1.4-1,2.3c0,0.9,0.3,1.6,1,2.3c0.6,0.6,1.4,0.9,2.3,0.9c0.9,0,1.7-0.3,2.3-0.9
+ c0.6-0.6,0.9-1.4,0.9-2.3c0-0.9-0.3-1.7-0.9-2.3c-0.6-0.6-1.3-0.9-2.3-0.9C279.8,399.1,279,399.4,278.4,400z"/>
+ <path fill="#007EC5" d="M294.1,404.1l0.8,0.6c-0.8,1.1-1.9,1.7-3.4,1.7c-1.2,0-2.2-0.4-2.9-1.2c-0.7-0.8-1.1-1.8-1.1-3
+ c0-1.2,0.4-2.2,1.1-3c0.7-0.8,1.7-1.2,2.8-1.2c1.2,0,2.1,0.4,2.7,1.1c0.7,0.7,1,1.6,1,2.6v0.7h-6.6c0,0.2,0,0.4,0.1,0.6
+ c0.1,0.2,0.1,0.5,0.3,0.8c0.1,0.3,0.3,0.5,0.5,0.8c0.2,0.2,0.5,0.4,0.9,0.6c0.4,0.2,0.8,0.2,1.2,0.2c0.5,0,1-0.1,1.5-0.4
+ C293.5,404.9,293.8,404.6,294.1,404.1L294.1,404.1z M288.5,401.6h5.6c0-0.7-0.3-1.3-0.8-1.8c-0.5-0.5-1.2-0.8-1.9-0.8
+ c-0.5,0-1,0.1-1.4,0.3c-0.4,0.2-0.7,0.5-0.9,0.8c-0.2,0.3-0.3,0.6-0.4,0.8C288.5,401.3,288.5,401.5,288.5,401.6z"/>
+ <path fill="#007EC5" d="M298.1,406.3v-5.7c0-0.2,0-0.6,0-1.2c0-0.6,0-0.9,0-1.1h1c0,0.8,0,1.3,0.1,1.4h0.1
+ c0.2-0.5,0.6-0.8,1.1-1.1c0.5-0.3,1-0.5,1.7-0.5c2,0,3,1.1,3,3.4v4.7h-1v-4.7c0-1.7-0.7-2.5-2-2.5c-0.8,0-1.5,0.3-2,0.8
+ c-0.5,0.6-0.8,1.4-0.8,2.4v3.9H298.1z"/>
+ </g>
+ <g>
+ <polygon fill="#007EC5" points="313.1,406.3 313.1,394.2 314.5,394.2 321.9,404.8 321.9,404.8 321.9,394.2 323.1,394.2
+ 323.1,406.3 321.6,406.3 314.2,395.7 314.2,395.7 314.2,406.3 "/>
+ <path fill="#007EC5" d="M333,404.1l0.8,0.6c-0.8,1.1-1.9,1.7-3.4,1.7c-1.2,0-2.2-0.4-2.9-1.2c-0.7-0.8-1.1-1.8-1.1-3
+ c0-1.2,0.4-2.2,1.1-3c0.7-0.8,1.7-1.2,2.8-1.2c1.2,0,2.1,0.4,2.7,1.1c0.7,0.7,1,1.6,1,2.6v0.7h-6.6c0,0.2,0,0.4,0.1,0.6
+ c0.1,0.2,0.1,0.5,0.3,0.8c0.1,0.3,0.3,0.5,0.5,0.8c0.2,0.2,0.5,0.4,0.9,0.6c0.4,0.2,0.8,0.2,1.2,0.2c0.5,0,1-0.1,1.5-0.4
+ C332.4,404.9,332.8,404.6,333,404.1L333,404.1z M327.4,401.6h5.6c0-0.7-0.3-1.3-0.8-1.8c-0.5-0.5-1.2-0.8-1.9-0.8
+ c-0.5,0-1,0.1-1.4,0.3c-0.4,0.2-0.7,0.5-0.9,0.8c-0.2,0.3-0.3,0.6-0.4,0.8C327.4,401.3,327.4,401.5,327.4,401.6z"/>
+ <path fill="#007EC5" d="M340.9,398.4v0.9h-2.3v5.1c0,0.4,0.1,0.6,0.3,0.8c0.2,0.2,0.5,0.3,0.8,0.3c0.4,0,0.7-0.1,1.2-0.3l0.1,0.9
+ c-0.5,0.2-0.9,0.3-1.3,0.3c-0.7,0-1.2-0.2-1.5-0.6c-0.3-0.4-0.5-0.9-0.5-1.5v-5.1h-1.7v-0.9h1.7v-2.3h1v2.3H340.9z"/>
+ <polygon fill="#007EC5" points="344.8,406.3 342.3,398.4 343.5,398.4 345.4,405 345.4,405 347.6,398.4 348.6,398.4 350.9,405
+ 351,405 352.8,398.4 353.9,398.4 351.5,406.3 350.5,406.3 348.1,399.8 348.1,399.8 345.9,406.3 "/>
+ <path fill="#007EC5" d="M356.9,405.3c-0.8-0.8-1.2-1.8-1.2-3c0-1.2,0.4-2.2,1.2-3c0.8-0.8,1.8-1.2,3-1.2c1.2,0,2.2,0.4,3,1.2
+ c0.8,0.8,1.2,1.8,1.2,3c0,1.2-0.4,2.2-1.2,3c-0.8,0.8-1.8,1.2-3,1.2C358.7,406.5,357.7,406.1,356.9,405.3L356.9,405.3z M357.7,400
+ c-0.6,0.6-0.9,1.4-0.9,2.3c0,0.9,0.3,1.7,0.9,2.3c0.6,0.6,1.3,0.9,2.3,0.9c0.9,0,1.7-0.3,2.3-0.9c0.6-0.6,0.9-1.4,0.9-2.3
+ c0-0.9-0.3-1.7-0.9-2.3c-0.6-0.6-1.3-0.9-2.3-0.9C359,399.1,358.2,399.4,357.7,400z"/>
+ <path fill="#007EC5" d="M367.1,406.3v-5.7c0-0.2,0-0.6,0-1.2c0-0.6,0-0.9,0-1.1h1c0,0.8,0,1.3,0.1,1.4c0.6-1.1,1.4-1.6,2.5-1.6
+ c0.2,0,0.4,0,0.6,0.1l-0.1,1c-0.1,0-0.3-0.1-0.4-0.1c-0.9,0-1.5,0.3-1.9,0.8c-0.4,0.5-0.6,1.2-0.6,2v4.3H367.1z"/>
+ <polygon fill="#007EC5" points="373.5,406.3 373.5,393.3 374.5,393.3 374.5,402 378.4,398.4 379.9,398.4 375.9,402 380.4,406.3
+ 378.9,406.3 374.5,402.1 374.5,406.3 "/>
+ </g>
+ <g>
+ <path fill="#007EC5" d="M388.2,404.8c-1.2-1.2-1.8-2.7-1.8-4.6c0-1.9,0.6-3.4,1.8-4.6c1.2-1.2,2.7-1.8,4.5-1.8
+ c1.8,0,3.3,0.6,4.5,1.8c1.2,1.2,1.8,2.7,1.8,4.6c0,1.9-0.6,3.4-1.8,4.6c-1.2,1.2-2.7,1.8-4.5,1.8
+ C390.8,406.6,389.3,406,388.2,404.8L388.2,404.8z M388.9,396.4c-0.9,1-1.4,2.3-1.4,3.8c0,1.5,0.5,2.8,1.4,3.8
+ c0.9,1,2.2,1.5,3.7,1.5c1.6,0,2.8-0.5,3.7-1.5c0.9-1,1.4-2.3,1.4-3.8c0-1.5-0.5-2.8-1.4-3.8c-0.9-1-2.2-1.5-3.7-1.5
+ C391.1,394.9,389.9,395.4,388.9,396.4z"/>
+ <path fill="#007EC5" d="M401.7,410.2v-11.8h1v1.4h0c0.3-0.5,0.7-0.9,1.3-1.2c0.6-0.3,1.2-0.4,1.8-0.4c1.2,0,2.2,0.4,3,1.2
+ c0.8,0.8,1.2,1.8,1.2,3c0,1.2-0.4,2.2-1.2,3c-0.8,0.8-1.8,1.2-3,1.2c-0.6,0-1.3-0.1-1.8-0.4c-0.6-0.3-1-0.7-1.3-1.2h0v5.3H401.7
+ L401.7,410.2z M403.6,400c-0.6,0.6-1,1.4-1,2.3c0,0.9,0.3,1.6,1,2.3c0.6,0.6,1.4,0.9,2.3,0.9c0.9,0,1.7-0.3,2.3-0.9
+ c0.6-0.6,0.9-1.4,0.9-2.3c0-0.9-0.3-1.7-0.9-2.3c-0.6-0.6-1.3-0.9-2.3-0.9C405,399.1,404.2,399.4,403.6,400z"/>
+ <path fill="#007EC5" d="M419.3,404.1l0.8,0.6c-0.8,1.1-1.9,1.7-3.4,1.7c-1.2,0-2.2-0.4-2.9-1.2c-0.7-0.8-1.1-1.8-1.1-3
+ c0-1.2,0.4-2.2,1.1-3s1.7-1.2,2.8-1.2c1.2,0,2.1,0.4,2.7,1.1c0.7,0.7,1,1.6,1,2.6v0.7h-6.6c0,0.2,0,0.4,0.1,0.6
+ c0.1,0.2,0.1,0.5,0.3,0.8c0.1,0.3,0.3,0.5,0.5,0.8c0.2,0.2,0.5,0.4,0.9,0.6c0.4,0.2,0.8,0.2,1.2,0.2c0.5,0,1-0.1,1.5-0.4
+ C418.7,404.9,419,404.6,419.3,404.1L419.3,404.1z M413.7,401.6h5.6c0-0.7-0.3-1.3-0.8-1.8c-0.5-0.5-1.2-0.8-1.9-0.8
+ c-0.5,0-1,0.1-1.4,0.3c-0.4,0.2-0.7,0.5-0.9,0.8c-0.2,0.3-0.3,0.6-0.4,0.8C413.7,401.3,413.7,401.5,413.7,401.6z"/>
+ <path fill="#007EC5" d="M423.3,406.3v-5.7c0-0.2,0-0.6,0-1.2c0-0.6,0-0.9,0-1.1h1c0,0.8,0,1.3,0.1,1.4c0.6-1.1,1.4-1.6,2.5-1.6
+ c0.2,0,0.4,0,0.6,0.1l-0.1,1c-0.1,0-0.3-0.1-0.4-0.1c-0.9,0-1.5,0.3-1.9,0.8c-0.4,0.5-0.6,1.2-0.6,2v4.3H423.3z"/>
+ <path fill="#007EC5" d="M435.9,401v1.9c0,1.4,0.1,2.5,0.2,3.3h-1c-0.1-0.4-0.1-0.8-0.1-1.3h0c-0.6,1-1.5,1.5-2.8,1.5
+ c-0.8,0-1.4-0.2-2-0.6c-0.5-0.4-0.8-1-0.8-1.8c0-1.8,1.5-2.7,4.4-2.7h1.2V401c0-0.6-0.2-1.1-0.6-1.4c-0.4-0.3-0.9-0.5-1.6-0.5
+ c-0.9,0-1.7,0.3-2.4,0.9l-0.6-0.7c0.4-0.3,0.8-0.6,1.4-0.8c0.6-0.2,1.1-0.3,1.6-0.3c1,0,1.8,0.2,2.3,0.7
+ C435.6,399.3,435.9,400,435.9,401L435.9,401z M434.9,402.3h-1.1c-1,0-1.8,0.1-2.4,0.4c-0.7,0.3-1,0.7-1,1.4c0,0.5,0.2,0.8,0.5,1.1
+ c0.4,0.3,0.8,0.4,1.2,0.4c1,0,1.7-0.3,2.1-0.8c0.4-0.5,0.6-1.2,0.6-1.9V402.3z"/>
+ <path fill="#007EC5" d="M443.2,398.4v0.9h-2.3v5.1c0,0.4,0.1,0.6,0.3,0.8c0.2,0.2,0.5,0.3,0.8,0.3c0.4,0,0.7-0.1,1.2-0.3l0.1,0.9
+ c-0.5,0.2-0.9,0.3-1.3,0.3c-0.7,0-1.2-0.2-1.5-0.6c-0.3-0.4-0.5-0.9-0.5-1.5v-5.1h-1.7v-0.9h1.7v-2.3h1v2.3H443.2z"/>
+ <path fill="#007EC5" d="M445.9,406.3v-7.9h1v7.9H445.9L445.9,406.3z M445.9,395.8c-0.1-0.1-0.2-0.3-0.2-0.5c0-0.2,0.1-0.4,0.2-0.5
+ c0.1-0.1,0.3-0.2,0.5-0.2c0.2,0,0.4,0.1,0.5,0.2c0.1,0.1,0.2,0.3,0.2,0.5c0,0.2-0.1,0.4-0.2,0.5c-0.1,0.1-0.3,0.2-0.5,0.2
+ C446.2,396,446,395.9,445.9,395.8z"/>
+ <path fill="#007EC5" d="M450.6,406.3v-5.7c0-0.2,0-0.6,0-1.2c0-0.6,0-0.9,0-1.1h1c0,0.8,0,1.3,0.1,1.4h0.1
+ c0.2-0.5,0.6-0.8,1.1-1.1c0.5-0.3,1-0.5,1.7-0.5c2,0,3,1.1,3,3.4v4.7h-1v-4.7c0-1.7-0.7-2.5-2-2.5c-0.8,0-1.5,0.3-2,0.8
+ c-0.5,0.6-0.8,1.4-0.8,2.4v3.9H450.6z"/>
+ <path fill="#007EC5" d="M468.7,398.4v7.4c0,0.8-0.1,1.4-0.3,2c-0.2,0.6-0.4,1-0.7,1.3c-0.3,0.3-0.6,0.6-1,0.8
+ c-0.4,0.2-0.8,0.3-1.1,0.4c-0.3,0.1-0.7,0.1-1.1,0.1c-0.8,0-1.6-0.1-2.3-0.4c-0.7-0.3-1.3-0.7-1.7-1.2l0.8-0.8
+ c0.7,1,1.7,1.5,3.1,1.5c2.1,0,3.2-1.2,3.2-3.6v-1.1h0c-0.6,1-1.6,1.5-3,1.5c-1.2,0-2.2-0.4-3-1.2c-0.8-0.8-1.2-1.7-1.2-2.9
+ c0-1.1,0.4-2.1,1.2-2.9c0.8-0.8,1.8-1.2,3-1.2c1.3,0,2.3,0.5,3,1.5h0v-1.3H468.7L468.7,398.4z M466.8,404.4
+ c0.6-0.6,0.9-1.3,0.9-2.2c0-0.9-0.3-1.6-0.9-2.2c-0.6-0.6-1.3-0.9-2.2-0.9c-0.9,0-1.6,0.3-2.2,0.9c-0.6,0.6-0.9,1.3-0.9,2.2
+ c0,0.9,0.3,1.6,0.9,2.2c0.6,0.6,1.3,0.9,2.2,0.9C465.5,405.3,466.2,405,466.8,404.4z"/>
+ </g>
+ <g>
+ <path fill="#007EC5" d="M476,404.7l1.1-0.7c0.6,1,1.5,1.5,2.8,1.5c0.8,0,1.4-0.2,1.9-0.6c0.5-0.4,0.8-1,0.8-1.7
+ c0-0.5-0.2-1-0.5-1.3c-0.3-0.3-0.7-0.6-1.2-0.7c-0.5-0.1-1-0.3-1.5-0.5c-0.5-0.2-1-0.4-1.5-0.6c-0.5-0.2-0.8-0.6-1.2-1
+ c-0.3-0.5-0.5-1.1-0.5-1.8c0-1,0.4-1.8,1.1-2.4c0.8-0.6,1.7-0.9,2.8-0.9c1.4,0,2.5,0.5,3.3,1.5l-1,0.7c-0.6-0.8-1.4-1.2-2.4-1.2
+ c-0.8,0-1.4,0.2-1.9,0.6c-0.5,0.4-0.8,1-0.8,1.7c0,0.5,0.1,0.9,0.3,1.2c0.2,0.3,0.5,0.6,0.9,0.8c0.4,0.2,0.8,0.3,1.2,0.5
+ c0.4,0.1,0.9,0.3,1.3,0.4c0.4,0.2,0.9,0.3,1.2,0.6c0.4,0.2,0.7,0.6,0.9,1c0.2,0.4,0.3,0.9,0.3,1.6c0,1-0.4,1.9-1.1,2.5
+ c-0.7,0.6-1.6,0.9-2.7,0.9C478.1,406.6,476.8,406,476,404.7z"/>
+ <path fill="#007EC5" d="M492.9,398.4l-4.1,10.3c-0.4,1.1-1.2,1.7-2.2,1.7c-0.3,0-0.6-0.1-1-0.2l0.1-1c0.4,0.1,0.7,0.2,0.9,0.2
+ c0.3,0,0.6-0.1,0.8-0.4c0.2-0.2,0.4-0.6,0.5-1l0.7-1.8l-3.2-7.9h1.1l2.6,6.7l2.5-6.7H492.9z"/>
+ <path fill="#007EC5" d="M494.4,404.9l0.9-0.6c0.2,0.4,0.5,0.7,0.9,1c0.4,0.2,0.9,0.3,1.4,0.3c0.5,0,0.9-0.1,1.3-0.4
+ c0.4-0.3,0.5-0.6,0.5-1.1c0-0.4-0.2-0.7-0.5-0.9c-0.3-0.2-0.7-0.4-1.2-0.5c-0.5-0.1-0.9-0.2-1.4-0.3c-0.5-0.1-0.9-0.3-1.2-0.7
+ c-0.3-0.3-0.5-0.8-0.5-1.3c0-0.7,0.3-1.3,0.8-1.7c0.5-0.4,1.2-0.6,1.9-0.6c1.4,0,2.3,0.5,2.8,1.5l-0.9,0.5c-0.4-0.7-1-1.1-1.9-1.1
+ c-0.4,0-0.8,0.1-1.1,0.3c-0.4,0.2-0.5,0.5-0.5,0.9c0,0.4,0.2,0.7,0.5,0.9c0.3,0.2,0.7,0.3,1.2,0.4c0.5,0.1,0.9,0.2,1.4,0.3
+ c0.5,0.1,0.9,0.3,1.2,0.7c0.3,0.3,0.5,0.8,0.5,1.4c0,0.8-0.3,1.4-0.8,1.8c-0.6,0.4-1.2,0.6-2,0.6
+ C496.1,406.5,495,405.9,494.4,404.9z"/>
+ <path fill="#007EC5" d="M507.2,398.4v0.9h-2.3v5.1c0,0.4,0.1,0.6,0.3,0.8c0.2,0.2,0.5,0.3,0.8,0.3c0.4,0,0.7-0.1,1.2-0.3l0.1,0.9
+ c-0.5,0.2-0.9,0.3-1.3,0.3c-0.7,0-1.2-0.2-1.5-0.6c-0.3-0.4-0.5-0.9-0.5-1.5v-5.1h-1.7v-0.9h1.7v-2.3h1v2.3H507.2z"/>
+ <path fill="#007EC5" d="M515.9,404.1l0.8,0.6c-0.8,1.1-1.9,1.7-3.4,1.7c-1.2,0-2.2-0.4-2.9-1.2c-0.7-0.8-1.1-1.8-1.1-3
+ c0-1.2,0.4-2.2,1.1-3s1.7-1.2,2.8-1.2c1.2,0,2.1,0.4,2.7,1.1c0.7,0.7,1,1.6,1,2.6v0.7h-6.6c0,0.2,0,0.4,0.1,0.6
+ c0.1,0.2,0.1,0.5,0.3,0.8c0.1,0.3,0.3,0.5,0.5,0.8c0.2,0.2,0.5,0.4,0.9,0.6c0.4,0.2,0.8,0.2,1.2,0.2c0.5,0,1-0.1,1.5-0.4
+ C515.3,404.9,515.7,404.6,515.9,404.1L515.9,404.1z M510.3,401.6h5.6c0-0.7-0.3-1.3-0.8-1.8c-0.5-0.5-1.2-0.8-1.9-0.8
+ c-0.5,0-1,0.1-1.4,0.3c-0.4,0.2-0.7,0.5-0.9,0.8c-0.2,0.3-0.3,0.6-0.4,0.8C510.3,401.3,510.3,401.5,510.3,401.6z"/>
+ <path fill="#007EC5" d="M520,406.3v-5.7c0-0.2,0-0.6,0-1.2c0-0.6,0-0.9,0-1.1h1c0,0.8,0,1.3,0.1,1.4h0.1c0.2-0.5,0.6-0.8,1.1-1.1
+ c0.5-0.3,1-0.5,1.7-0.5c0.5,0,1,0.1,1.5,0.4c0.4,0.3,0.7,0.7,0.9,1.3c0.2-0.6,0.6-1,1.1-1.3c0.5-0.3,1-0.4,1.6-0.4
+ c2,0,3,1.1,3,3.4v4.7h-1v-4.7c0-1.7-0.7-2.5-2-2.5c-0.4,0-0.8,0.1-1.2,0.3c-0.3,0.2-0.6,0.4-0.8,0.7c-0.2,0.3-0.3,0.6-0.4,0.9
+ c-0.1,0.3-0.1,0.6-0.1,0.9v4.4h-1v-4.8c0-0.8-0.1-1.3-0.4-1.8c-0.3-0.4-0.7-0.6-1.2-0.6c-0.8,0-1.5,0.3-2,0.8
+ c-0.5,0.6-0.8,1.4-0.8,2.4v3.9H520z"/>
+ </g>
+</g>
+<g>
+
+ <linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="280.7511" y1="468.8727" x2="530.5958" y2="160.3402" gradientTransform="matrix(-0.9595 0.2818 0.2818 0.9595 742.5177 -113.6192)">
+ <stop offset="0" style="stop-color:#C6262F"/>
+ <stop offset="1.288056e-03" style="stop-color:#C6262F"/>
+ <stop offset="0.3136" style="stop-color:#D64B43"/>
+ <stop offset="0.5951" style="stop-color:#E26255"/>
+ <stop offset="0.8334" style="stop-color:#EA6F61"/>
+ <stop offset="1" style="stop-color:#ED7466"/>
+ </linearGradient>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="url(#SVGID_5_)" d="M427.7,300.4c-6.9,0.6-13.1,5-19.2,7.1
+ c-18.1,6.2-33.9,9.1-56.5,4.7c24.6,17.2,36.6,13,63.7,0.1c-0.5,0.6-0.7,1.3-1.3,1.9c1.4-0.4,2.4-1.7,3.4-2.2
+ c-0.4,0.7-0.9,1.5-1.4,1.9c2.2-0.6,3.7-2.3,5.9-3.9c-2.4,2.1-4.2,5-6,8c-1.5,2.5-3.1,4.8-5.1,6.9c-1,1-1.9,1.9-2.9,2.9
+ c-1.4,1.3-2.9,2.5-5.1,2.9c1.7,0.1,3.6-0.3,6.5-1.9c-1.6,2.4-7.1,6.2-9.9,7.2c10.5-2.6,19.2-15.9,25.7-18
+ c18.3-5.9,13.8-3.4,27-14.2c1.6-1.3,3-1,5.1-0.8c1.1,0.1,2.1,0.3,3.2,0.5c0.8,0.2,1.4,0.4,2.2,0.8l1.8,0.9c-1.9-4.5-2.3-4.1-5.9-6
+ c-2.3-1.3-3.3-3.8-6.2-4.9c-7.1-2.6-11.9,11.7-11.7-5c0.1-8,4.2-14.4,6.4-22c1.1-3.8,2.3-7.6,2.4-11.5c0.1-2.3,0-4.7-0.4-7
+ c-2-11.2-8.4-21.5-19.7-24.8c-1-0.3-1.1-0.3-0.9,0c9.6,17.1,7.2,38.3,3.1,54.2C429.9,285.5,426.7,293.2,427.7,300.4z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#E6E7E8" d="M344.4,311.8c7.1,4.9,15,9.5,23.8,10.7
+ c-8.3-0.4-16.6-3.8-27.3-11.3C342,311.4,343.2,311.6,344.4,311.8z"/>
+</g>
+</svg>
diff --git a/web/gui/src/main/webapp/_dev/overlaywork/AppUiTopoOverlay.java b/web/gui/src/main/webapp/_dev/overlaywork/AppUiTopoOverlay.java
new file mode 100644
index 0000000..aad890c
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/overlaywork/AppUiTopoOverlay.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015,2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.meowster.over;
+
+import org.onosproject.ui.UiTopoOverlay;
+import org.onosproject.ui.topo.ButtonId;
+import org.onosproject.ui.topo.PropertyPanel;
+import org.onosproject.ui.topo.TopoConstants.CoreButtons;
+import org.onosproject.ui.topo.TopoConstants.Glyphs;
+
+import static org.onosproject.ui.topo.TopoConstants.Properties.*;
+
+/**
+ * Our topology overlay.
+ */
+public class AppUiTopoOverlay extends UiTopoOverlay {
+
+ // NOTE: this must match the ID defined in topov.js
+ private static final String OVERLAY_ID = "meowster-overlay";
+
+ private static final String MY_TITLE = "I changed the title";
+ private static final String MY_VERSION = "Beta-1.0.0042";
+
+ private static final ButtonId FOO_BUTTON = new ButtonId("foo");
+ private static final ButtonId BAR_BUTTON = new ButtonId("bar");
+
+ public AppUiTopoOverlay() {
+ super(OVERLAY_ID);
+ }
+
+
+ @Override
+ public void modifySummary(PropertyPanel pp) {
+ pp.title("My App Rocks!")
+ .typeId(Glyphs.CROWN)
+ .removeProps(
+ TOPOLOGY_SSCS,
+ INTENTS,
+ TUNNELS,
+ FLOWS,
+ VERSION
+ )
+ .addProp(VERSION, MY_VERSION);
+
+ }
+
+ @Override
+ public void modifyDeviceDetails(PropertyPanel pp) {
+ pp.title(MY_TITLE);
+ pp.removeProps(LATITUDE, LONGITUDE);
+
+ pp.addButton(FOO_BUTTON)
+ .addButton(BAR_BUTTON);
+
+ pp.removeButtons(CoreButtons.SHOW_PORT_VIEW)
+ .removeButtons(CoreButtons.SHOW_GROUP_VIEW)
+ .removeButtons(CoreButtons.SHOW_METER_VIEW);
+ }
+
+}
diff --git a/web/gui/src/main/webapp/_dev/overlaywork/README.txt b/web/gui/src/main/webapp/_dev/overlaywork/README.txt
new file mode 100644
index 0000000..d7dcbec
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/overlaywork/README.txt
@@ -0,0 +1,4 @@
+NOTE:
+
+This directory is putting under revision control some key files from
+an example stand-alone app, as I develop the topology overlay functionality.
diff --git a/web/gui/src/main/webapp/_dev/overlaywork/topov.js b/web/gui/src/main/webapp/_dev/overlaywork/topov.js
new file mode 100644
index 0000000..068c30c
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/overlaywork/topov.js
@@ -0,0 +1,157 @@
+// sample topology overlay - client side
+(function () {
+ 'use strict';
+
+ // injected refs
+ var $log, tov;
+
+ // internal state
+ var someStateValue = true;
+
+ // our overlay definition
+ var overlay = {
+ // NOTE: this must match the ID defined in AppUiTopoOverlay
+ overlayId: 'meowster-overlay',
+ glyphId: '*star4',
+ tooltip: 'Sample Meowster Topo Overlay',
+
+ // These glyphs get installed using the overlayId as a prefix.
+ // e.g. 'star4' is installed as 'meowster-overlay-star4'
+ // They can be referenced (from this overlay) as '*star4'
+ // That is, the '*' prefix stands in for 'meowster-overlay-'
+ glyphs: {
+ star4: {
+ vb: '0 0 8 8',
+ d: 'M1,4l2,-1l1,-2l1,2l2,1l-2,1l-1,2l-1,-2z'
+ },
+ banner: {
+ vb: '0 0 6 6',
+ d: 'M1,1v4l2,-2l2,2v-4z'
+ }
+ },
+
+ activate: function () {
+ $log.debug("sample topology overlay ACTIVATED");
+ },
+ deactivate: function () {
+ $log.debug("sample topology overlay DEACTIVATED");
+ },
+
+
+
+
+
+ // detail panel button definitions
+ buttons: {
+ foo: {
+ gid: 'chain',
+ tt: 'A FOO action',
+ cb: function (data) {
+ $log.debug('FOO action invoked with data:', data);
+ }
+ },
+ bar: {
+ gid: '*banner',
+ tt: 'A BAR action',
+ cb: function (data) {
+ $log.debug('BAR action invoked with data:', data);
+ }
+ }
+ },
+
+ // Key bindings for traffic overlay buttons
+ // NOTE: fully qual. button ID is derived from overlay-id and key-name
+ keyBindings: {
+ V: {
+ cb: buttonCallback,
+ tt: 'Uses the V key',
+ gid: '*banner'
+ },
+ F: {
+ cb: buttonCallback,
+ tt: 'Uses the F key',
+ gid: 'chain'
+ },
+ G: {
+ cb: buttonCallback,
+ tt: 'Uses the G key',
+ gid: 'crown'
+ },
+
+ T: {
+ cb: buttonCallback,
+ tt: 'Uses the T key',
+ gid: 'switch'
+ },
+
+ R: {
+ cb: buttonCallback,
+ tt: 'Uses the R key',
+ gid: 'endstation'
+ },
+
+ 0: {
+ cb: buttonCallback,
+ tt: 'Uses the ZERO key',
+ gid: 'xMark'
+ },
+
+ _keyOrder: [
+ '0', 'V', 'F', 'G', 'T', 'R'
+ ]
+
+ // NOTE: T and R should be rejected (not installed)
+ // T is reserved for 'toggle Theme'
+ // R is reserved for 'Reset pan and zoom'
+ },
+
+ hooks: {
+ // hook for handling escape key
+ // Must return true to consume ESC, false otherwise.
+ escape: cancelState,
+
+ // hooks for when the selection changes...
+ empty: function () {
+ selectionCallback('empty');
+ },
+ single: function (data) {
+ selectionCallback('single', data);
+ },
+ multi: function (selectOrder) {
+ selectionCallback('multi', selectOrder);
+ tov.addDetailButton('foo');
+ tov.addDetailButton('bar');
+ }
+ }
+
+ };
+
+ // invoked when the escape key is pressed
+ function cancelState() {
+ if (someStateValue) {
+ someStateValue = false;
+ // we consumed the ESC event
+ return true;
+ }
+ return false;
+ }
+
+ function buttonCallback(x) {
+ $log.debug('Toolbar-button callback', x);
+ }
+
+ function selectionCallback(x, d) {
+ $log.debug('Selection callback', x, d);
+ }
+
+ // invoke code to register with the overlay service
+ angular.module('ovSample')
+ .run(['$log', 'TopoOverlayService',
+
+ function (_$log_, _tov_) {
+ $log = _$log_;
+ tov = _tov_;
+ tov.register(overlay);
+ }]);
+
+}());
diff --git a/web/gui/src/main/webapp/_dev/practice-table.html b/web/gui/src/main/webapp/_dev/practice-table.html
new file mode 100644
index 0000000..1912cc7
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/practice-table.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+ ONOS -- Displaying icons with Angular test page
+ -->
+
+<html>
+<head lang="en">
+ <meta charset="UTF-8">
+ <title>Practice Table Formatting</title>
+
+ <script type="text/javascript" src="../tp/angular.js"></script>
+ <script type="text/javascript" src="../tp/angular-route.js"></script>
+
+ <script type="text/javascript" src="../tp/d3.js"></script>
+
+ <script type="text/javascript" src="practice-table.js"></script>
+ <script type="text/javascript" src="../app/fw/widget/widget.js"></script>
+ <script type="text/javascript" src="../app/fw/widget/table.js"></script>
+
+ <style>
+ html,
+ body {
+ background-color: #ddf;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 9pt;
+ }
+
+ h2 {
+ color: darkred;
+ }
+
+ </style>
+
+</head>
+<!-- outline for using a controller in Angular -->
+<body ng-app="practiceTable">
+ <h2>Scrolling Table Practice</h2>
+ <div id="tableDiv" ng-controller="showTableCtrl as ctrl">
+ </div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/_dev/practice-table.js b/web/gui/src/main/webapp/_dev/practice-table.js
new file mode 100644
index 0000000..f244c86
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/practice-table.js
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Showing Icons Test Module
+ */
+
+(function () {
+ 'use strict';
+
+ var config = {
+ colIds: ['_iconid_available', 'id', 'mfr', 'hw', 'sw', 'serial',
+ 'annotations'],
+ colText: ['Availability', 'URI', 'Vendor', 'Hardware Version',
+ 'Software Version', 'Serial Number', 'Protocol']
+ },
+ deviceData = {
+ "devices": [{
+ "id": "of:0000000000000001",
+ "available": true,
+ "_iconid_available": "active",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000004",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ },
+ {
+ "id": "of:0000000000000092",
+ "available": false,
+ "_iconid_available": "inactive",
+ "role": "MASTER",
+ "mfr": "Nicira, Inc.",
+ "hw": "Open vSwitch",
+ "sw": "2.0.1",
+ "serial": "None",
+ "annotations": {
+ "protocol": "OF_10"
+ }
+ }]
+ };
+
+ function setColWidth(t) {
+ var tHeaders, tdElement, colWidth;
+
+ tHeaders = t.selectAll('th');
+
+ // select each td in the first row and set the header's width to the
+ // corresponding td's width, if td is larger than header's width
+ tHeaders.each(function(thElement, index){
+ thElement = d3.select(this);
+
+ tdElement = t.select('td:nth-of-type(' + (index + 1) + ')');
+ colWidth = tdElement.style('width');
+
+ thElement.style('width', colWidth);
+ tdElement.style('width', colWidth);
+ });
+ }
+
+ function setCSS(thead, tbody, height) {
+ thead.style('display', 'block');
+ tbody.style({'display': 'block',
+ 'height': height || '100px',
+ 'overflow': 'auto'
+ });
+ }
+
+ function fixTable(t, th, tb, height) {
+ setColWidth(t);
+ setCSS(th, tb, height);
+ }
+
+ angular.module('practiceTable', ['onosWidget'])
+
+ .controller('showTableCtrl', ['$log', '$scope', '$rootScope',
+ '$timeout', 'TableService',
+ function ($log, $scope, $rootScope, $timeout, ts) {
+ var self = this;
+ var table = ts.renderTable(d3.select('#tableDiv'), config, deviceData);
+ }])
+
+ .directive('fixedHeader', ['$log', '$timeout', '$compile',
+ function ($log, $timeout, $compile) {
+ return {
+ restrict: 'A',
+ scope: {
+ tHeight: '@'
+ },
+
+ link: function (scope, element, attrs) {
+ var table = d3.select(element[0]),
+ thead = table.select('thead'),
+ tbody = table.select('tbody');
+
+ // wait until the table is visible
+ scope.$watch(
+ function () { return (!(table.offsetParent === null)); },
+ function(newValue, oldValue) {
+ if (newValue === true) {
+
+ // ensure thead and tbody have no display
+ thead.style('display', null);
+ tbody.style('display', null);
+
+ $timeout(function () {
+ fixTable(table, thead, tbody, scope.tHeight);
+ });
+ }
+ });
+ }
+ };
+ }]);
+}());
diff --git a/web/gui/src/main/webapp/_dev/show-icons-test.js b/web/gui/src/main/webapp/_dev/show-icons-test.js
new file mode 100644
index 0000000..915e016
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/show-icons-test.js
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014,2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Showing Icons Test Module
+ */
+
+(function () {
+ 'use strict';
+
+ // assuming the glyph is a square
+ // div is a D3 selection of the <DIV> element into which icon should load
+ // size is the size of the glyph
+ // id is the symbol id
+ // rer is the rectangle the glyph will be in's rounded corners
+ // svgClass is the class name for your glyph
+ function createGlyph(div, size, id, rer, svgClass) {
+ var dim = size || 20,
+ texty = 30,
+ gid = id || 'unknown',
+ rx = rer || 4,
+ svgCls = svgClass || 'embeddedGlyph',
+ svg, g;
+
+ svg = div.append('svg').attr({
+ 'class': svgCls,
+ width: dim,
+ height: dim + texty,
+ viewBox: '0 0 ' + dim + ' ' + dim
+ });
+
+ g = svg.append('g').attr({
+ 'class': 'glyph'
+ });
+
+ g.append('rect').attr({
+ width: dim,
+ height: dim,
+ rx: rx
+ });
+
+ g.append('use').attr({
+ width: dim,
+ height: dim,
+ 'class': 'glyph',
+ 'xlink:href': '#' + gid
+ });
+
+ g.append('text')
+ .attr({
+ 'text-anchor': 'left',
+ y: '1em',
+ x: 0,
+ transform: 'translate(0, ' + dim + ')scale(0.8)'
+ })
+ .style('fill', '#800')
+ .text(id);
+ }
+
+ angular.module('showIconsTest', ['onosSvg'])
+
+ .controller('OvShowIconsTest', ['$log', 'GlyphService', 'IconService',
+ function ($log, gs, icns) {
+ var self = this;
+
+ gs.init();
+
+ var div = d3.select('#showIcons');
+
+ // show device online and offline icons
+ icns.loadEmbeddedIcon(div, 'active', 50);
+ div.append('span').style('padding-left', '15px');
+ icns.loadEmbeddedIcon(div, 'inactive', 50);
+
+ var defs = d3.select('defs');
+
+ // show all glyphs in glyph library
+ gs.loadDefs(defs, null, true);
+ var list = gs.ids(),
+ gDiv = d3.select('#showGlyphs'),
+ ctr = 0;
+ list.forEach(function (id) {
+ createGlyph(gDiv, 50, id);
+ ctr += 1;
+ if (ctr%6 > 0) {
+ gDiv.append('span').style('padding-left', '15px');
+ } else {
+ gDiv.append('br');
+ }
+ });
+
+ $log.log('OvShowIconsTest has been created');
+ }]);
+}());
diff --git a/web/gui/src/main/webapp/_dev/show-icons.html b/web/gui/src/main/webapp/_dev/show-icons.html
new file mode 100644
index 0000000..ba3a390
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/show-icons.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+ ONOS -- Displaying icons with Angular test page
+ -->
+
+<html>
+<head lang="en">
+ <meta charset="UTF-8">
+ <title>Show Icons Angular</title>
+
+ <script type="text/javascript" src="../tp/angular.js"></script>
+ <script type="text/javascript" src="../tp/angular-route.js"></script>
+
+ <script type="text/javascript" src="../tp/d3.js"></script>
+
+ <script type="text/javascript" src="../app/fw/util/util.js"></script>
+ <script type="text/javascript" src="../app/fw/util/fn.js"></script>
+ <script type="text/javascript" src="../app/fw/util/theme.js"></script>
+ <script type="text/javascript" src="../app/fw/util/keys.js"></script>
+
+ <script type="text/javascript" src="../app/fw/svg/svg.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/svgUtil.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/glyph.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/glyphData.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/icon.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/geodata.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/map.js"></script>
+ <script type="text/javascript" src="../app/fw/svg/zoom.js"></script>
+
+ <script type="text/javascript" src="show-icons-test.js"></script>
+
+ <link rel="stylesheet" href="../app/common.css">
+ <link rel="stylesheet" href="../app/fw/svg/icon.css">
+
+ <style>
+ html,
+ body {
+ background-color: #ddf;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 9pt;
+ }
+
+ h2 {
+ color: darkred;
+ }
+
+ svg .glyph {
+ stroke: none;
+ fill: #123456;
+ fill-rule: evenodd;
+ }
+
+ svg.embeddedGlyph .glyph rect {
+ fill: #fff
+ }
+
+ </style>
+
+</head>
+<!-- outline for using a controller in Angular -->
+<body class="light" ng-app="showIconsTest" ng-controller="OvShowIconsTest as ctrl">
+ <h2>Displaying Icons and Glyphs with Angular</h2>
+ <div id="showIcons">
+ <p>Show all icons in icon library:<br></p>
+ </div>
+ <hr>
+ <div id="showGlyphs">
+ <p>Show all glyphs in glyph library:</p>
+ <p>(Displays checkMark and xMark too, because icons are built on top
+ of glyphs.)</p>
+ </div>
+
+
+
+</body>
+</html>
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/_dev/svg-exercise.html b/web/gui/src/main/webapp/_dev/svg-exercise.html
new file mode 100644
index 0000000..f9c11b8
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/svg-exercise.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+ ONOS -- SVG mouse over d3 exercise html
+ -->
+
+<html>
+<head lang="en">
+ <meta charset="UTF-8">
+ <title>Upgrade Performance</title>
+
+ <script type="text/javascript" src="../tp/angular.js"></script>
+ <script type="text/javascript" src="../tp/d3.js"></script>
+ <script type="text/javascript" src="svg-exercise.js"></script>
+ <script type="text/javascript" src="../app/fw/util/util.js"></script>
+ <script type="text/javascript" src="../app/fw/util/fn.js"></script>
+
+
+ <style>
+ html,
+ body, div {
+ background-color: #eee;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 9pt;
+ margin: 0;
+ overflow: hidden;
+ }
+ .button {
+ fill: #369;
+ filter: url(#buttonBevel);
+ }
+ svg text {
+ fill: white;
+ letter-spacing: .005em;
+ }
+ </style>
+</head>
+
+<body ng-app="svgExercise">
+
+<div id="svgExDiv" ng-controller="svgExCtrl as ctrl">
+ <improve-performance></improve-performance>
+</div>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ viewBox="-10 -10 110 110"
+ visibility="hidden">
+ <filter id="buttonBevel"
+ filterUnits="objectBoundingBox"
+ x="-10%" y="-10%" width="110%" height="110%">
+ <feGaussianBlur in="SourceAlpha"
+ stdDeviation="4"
+ result="blur"/>
+ <feSpecularLighting in="blur"
+ surfaceScale="7"
+ specularConstant="0.6"
+ specularExponent="5"
+ result="spec"
+ lighting-color="#4E7199">
+ <fePointLight x="-5000" y="-10000" z="20000"/>
+ </feSpecularLighting>
+ <feComposite in="spec"
+ in2="SourceAlpha"
+ operator="in"
+ result="spec2"/>
+ <feComposite in="SourceGraphic"
+ in2="spec2"
+ operator="arithmetic"
+ k1="0" k2="1" k3="1" k4="0" />
+ </filter>
+</svg>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/svg-exercise.js b/web/gui/src/main/webapp/_dev/svg-exercise.js
new file mode 100644
index 0000000..96ed131
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/svg-exercise.js
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- SVG mouse over d3 exercise module
+ */
+
+(function () {
+ 'use strict';
+
+ // injected references
+ var $log, fs;
+
+ // constants
+ var btnWidth = 175,
+ btnHeight = 50,
+ hoverZone = 70,
+ sectorDivisions = 3,
+ margin = 10;
+
+ // svg elements
+ var svg, g;
+
+ // other variables
+ var winWidth, winHeight,
+ sectorWidth, sectorHeight,
+ currSector = 4, // always starts in the middle
+ mouse;
+
+ // ====================================================
+
+ function centeredOnWindow(axis, dim) {
+ return (axis / 2) - (dim / 2);
+ }
+
+ function onMouseMove() {
+ mouse = d3.mouse(this);
+ moveButton();
+ }
+
+ function removeMouseListener() {
+ g.on('mousemove', null);
+ }
+
+ function addMouseListener() {
+ g.on('mousemove', onMouseMove);
+ }
+
+ function selectSector() {
+ var sector, row, col,
+ currCol = currSector % sectorDivisions;
+
+ do {
+ sector = Math.floor((Math.random() * 9));
+ col = sector % sectorDivisions;
+ } while (col === currCol);
+ currSector = sector;
+ row = Math.floor(sector / sectorDivisions);
+
+ return {
+ xmin: (sectorWidth * col) + margin,
+ xmax: ((sectorWidth * col) + sectorWidth) - margin,
+ ymin: (sectorHeight * row) + margin,
+ ymax: ((sectorHeight * row) + sectorHeight) - margin
+ };
+ }
+
+ function selectXY(sectorCoords) {
+ var x, y, x1, y1;
+
+ do {
+ x = (Math.random() * sectorCoords.xmax) + sectorCoords.xmin;
+ y = (Math.random() * sectorCoords.ymax) + sectorCoords.ymin;
+ x1 = x + btnWidth;
+ y1 = y + btnHeight;
+ } while (x1 > sectorCoords.xmax || y1 > sectorCoords.ymax);
+
+ return {
+ x: x,
+ y: y
+ };
+ }
+
+ function gTranslate(x, y) {
+ return 'translate(' + x + ',' + y + ')';
+ }
+
+ function moveButton() {
+ var sec = selectSector(),
+ pos = selectXY(sec);
+ g.transition()
+ .duration(300)
+ .ease('cubic-out')
+ .each('start', removeMouseListener)
+ .attr('transform', gTranslate(pos.x, pos.y))
+ .each('end', addMouseListener);
+ }
+
+ angular.module('svgExercise', ['onosUtil'])
+
+ .controller('svgExCtrl', ['$log', function (_$log_) {
+ $log = _$log_;
+ }])
+
+ .directive('improvePerformance', ['FnService', function (_fs_) {
+ fs = _fs_;
+ return {
+ restrict: 'E',
+ link: function (scope, elem) {
+ winWidth = fs.windowSize().width;
+ winHeight = fs.windowSize().height;
+ sectorWidth = winWidth / sectorDivisions;
+ sectorHeight = winHeight / sectorDivisions;
+
+ svg = d3.select(elem[0])
+ .append('svg')
+ .attr({
+ width: winWidth + 'px',
+ height: winHeight + 'px'
+ });
+
+ g = svg.append('g');
+
+ g.append('rect')
+ .attr({
+ width: btnWidth + 'px',
+ height: btnHeight + 'px',
+ rx: '10px',
+ 'class': 'button'
+ });
+
+ g.append('text')
+ .style('text-anchor', 'middle')
+ .text('Click for better performance.')
+ .attr({
+ x: btnWidth / 2,
+ y: (btnHeight / 2) + 5
+ });
+
+ g.append('rect')
+ .attr({
+ fill: 'none',
+ 'pointer-events': 'all',
+ width: btnWidth + hoverZone + 'px',
+ height: btnHeight + hoverZone + 'px',
+ x: -(hoverZone / 2),
+ y: -(hoverZone / 2)
+ });
+ g.attr('transform',
+ gTranslate(centeredOnWindow(winWidth, btnWidth),
+ centeredOnWindow(winHeight, btnHeight)));
+
+ addMouseListener();
+ }
+ };
+ }]);
+}());
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/_dev/topojson/countrycodes.html b/web/gui/src/main/webapp/_dev/topojson/countrycodes.html
new file mode 100644
index 0000000..246d9e4
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/topojson/countrycodes.html
@@ -0,0 +1,376 @@
+<!DOCTYPE html>
+<!--
+ *
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+-->
+<html lang="en">
+<head>
+ <title>2-Letter, 3-Letter, Country Codes for All Countries in the World</title>
+ <meta charset="utf-8">
+ <script charset="utf-8" src="../../tp/jquery-2.1.1.min.js"></script>
+</head>
+<body>
+
+<style type="text/css" scoped>
+ body {
+ font-family: Helvetica Neue, Helvetica, Arial, sans-serif ;
+ background-color: #eef;
+ }
+ .mainContent {
+ margin: auto;
+ width: 800px;
+ background-color: #ddf;
+ padding: 8px;
+ }
+
+ table {
+ margin: auto;
+ }
+ th {
+ font-style: italic;
+ text-align: left;
+ background-color: #aad;
+ color: #66c;
+ padding: 4px;
+ }
+ td {
+ padding: 4px;
+ }
+ td.code {
+ font-family: monospace;
+ font-size: 120%;
+ }
+ td.num {
+ text-align: right;
+ }
+ tr:nth-child(even) {
+ background-color: #dde;
+ }
+ tr:nth-child(odd) {
+ background-color: #eef;
+ }
+
+</style>
+
+<div class="content">
+ <div class="mainContent">
+ <div class="miscTxt">
+ <header>
+ <h1>Complete List of Country Codes </h1>
+ </header>
+ <p>
+ The 2-letter codes shown below are supplied by the ISO
+ (<i>International Organization for Standardization</i>).
+ It bases its list of country names and abbreviations on
+ the list of names published by the United Nations.
+ The UN also uses 3-letter codes, and numerical codes
+ to identify nations.
+ </p>
+
+ <table>
+ <thead>
+ <tr>
+ <th> Country </th>
+ <th> A2 (ISO) </th>
+ <th> A3 (UN) </th>
+ <th> NUM (UN) </th>
+ </tr>
+ </thead>
+ <tbody id="codes-body">
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+
+<script type="text/javascript">
+
+ var data = [
+ [ 'Afghanistan', 'AF', 'AFG', 4 ],
+ [ 'Albania', 'AL', 'ALB', 8 ],
+ [ 'Algeria', 'DZ', 'DZA', 12 ],
+ [ 'American Samoa', 'AS', 'ASM', 16 ],
+ [ 'Andorra', 'AD', 'AND', 20 ],
+ [ 'Angola', 'AO', 'AGO', 24 ],
+ [ 'Anguilla', 'AI', 'AIA', 660 ],
+ [ 'Antarctica', 'AQ', 'ATA', 10 ],
+ [ 'Antigua and Barbuda', 'AG', 'ATG', 28 ],
+ [ 'Argentina', 'AR', 'ARG', 32 ],
+ [ 'Armenia', 'AM', 'ARM', 51 ],
+ [ 'Aruba', 'AW', 'ABW', 533 ],
+ [ 'Australia', 'AU', 'AUS', 36 ],
+ [ 'Austria', 'AT', 'AUT', 40 ],
+ [ 'Azerbaijan', 'AZ', 'AZE', 31 ],
+ [ 'Bahamas', 'BS', 'BHS', 44 ],
+ [ 'Bahrain', 'BH', 'BHR', 48 ],
+ [ 'Bangladesh', 'BD', 'BGD', 50 ],
+ [ 'Barbados', 'BB', 'BRB', 52 ],
+ [ 'Belarus', 'BY', 'BLR', 112 ],
+ [ 'Belgium', 'BE', 'BEL', 56 ],
+ [ 'Belize', 'BZ', 'BLZ', 84 ],
+ [ 'Benin', 'BJ', 'BEN', 204 ],
+ [ 'Bermuda', 'BM', 'BMU', 60 ],
+ [ 'Bhutan', 'BT', 'BTN', 64 ],
+ [ 'Bolivia', 'BO', 'BOL', 68 ],
+ [ 'Bonaire', 'BQ', 'BES', 535 ],
+ [ 'Bosnia and Herzegovina', 'BA', 'BIH', 70 ],
+ [ 'Botswana', 'BW', 'BWA', 72 ],
+ [ 'Bouvet Island', 'BV', 'BVT', 74 ],
+ [ 'Brazil', 'BR', 'BRA', 76 ],
+ [ 'British Indian Ocean Territory', 'IO', 'IOT', 86 ],
+ [ 'Brunei Darussalam', 'BN', 'BRN', 96 ],
+ [ 'Bulgaria', 'BG', 'BGR', 100 ],
+ [ 'Burkina Faso', 'BF', 'BFA', 854 ],
+ [ 'Burundi', 'BI', 'BDI', 108 ],
+ [ 'Cambodia', 'KH', 'KHM', 116 ],
+ [ 'Cameroon', 'CM', 'CMR', 120 ],
+ [ 'Canada', 'CA', 'CAN', 124 ],
+ [ 'Cape Verde', 'CV', 'CPV', 132 ],
+ [ 'Cayman Islands', 'KY', 'CYM', 136 ],
+ [ 'Central African Republic', 'CF', 'CAF', 140 ],
+ [ 'Chad', 'TD', 'TCD', 148 ],
+ [ 'Chile', 'CL', 'CHL', 152 ],
+ [ 'China', 'CN', 'CHN', 156 ],
+ [ 'Christmas Island', 'CX', 'CXR', 162 ],
+ [ 'Cocos (Keeling) Islands', 'CC', 'CCK', 166 ],
+ [ 'Colombia', 'CO', 'COL', 170 ],
+ [ 'Comoros', 'KM', 'COM', 174 ],
+ [ 'Congo', 'CG', 'COG', 178 ],
+ [ 'Democratic Republic of the Congo', 'CD', 'COD', 180 ],
+ [ 'Cook Islands', 'CK', 'COK', 184 ],
+ [ 'Costa Rica', 'CR', 'CRI', 188 ],
+ [ 'Croatia', 'HR', 'HRV', 191 ],
+ [ 'Cuba', 'CU', 'CUB', 192 ],
+ [ 'Curaçao', 'CW', 'CUW', 531 ],
+ [ 'Cyprus', 'CY', 'CYP', 196 ],
+ [ 'Czech Republic', 'CZ', 'CZE', 203 ],
+ [ 'Côte dIvoire', 'CI', 'CIV', 384 ],
+ [ 'Denmark', 'DK', 'DNK', 208 ],
+ [ 'Djibouti', 'DJ', 'DJI', 262 ],
+ [ 'Dominica', 'DM', 'DMA', 212 ],
+ [ 'Dominican Republic', 'DO', 'DOM', 214 ],
+ [ 'Ecuador', 'EC', 'ECU', 218 ],
+ [ 'Egypt', 'EG', 'EGY', 818 ],
+ [ 'El Salvador', 'SV', 'SLV', 222 ],
+ [ 'Equatorial Guinea', 'GQ', 'GNQ', 226 ],
+ [ 'Eritrea', 'ER', 'ERI', 232 ],
+ [ 'Estonia', 'EE', 'EST', 233 ],
+ [ 'Ethiopia', 'ET', 'ETH', 231 ],
+ [ 'Falkland Islands (Malvinas)', 'FK', 'FLK', 238 ],
+ [ 'Faroe Islands', 'FO', 'FRO', 234 ],
+ [ 'Fiji', 'FJ', 'FJI', 242 ],
+ [ 'Finland', 'FI', 'FIN', 246 ],
+ [ 'France', 'FR', 'FRA', 250 ],
+ [ 'French Guiana', 'GF', 'GUF', 254 ],
+ [ 'French Polynesia', 'PF', 'PYF', 258 ],
+ [ 'French Southern Territories', 'TF', 'ATF', 260 ],
+ [ 'Gabon', 'GA', 'GAB', 266 ],
+ [ 'Gambia', 'GM', 'GMB', 270 ],
+ [ 'Georgia', 'GE', 'GEO', 268 ],
+ [ 'Germany', 'DE', 'DEU', 276 ],
+ [ 'Ghana', 'GH', 'GHA', 288 ],
+ [ 'Gibraltar', 'GI', 'GIB', 292 ],
+ [ 'Greece', 'GR', 'GRC', 300 ],
+ [ 'Greenland', 'GL', 'GRL', 304 ],
+ [ 'Grenada', 'GD', 'GRD', 308 ],
+ [ 'Guadeloupe', 'GP', 'GLP', 312 ],
+ [ 'Guam', 'GU', 'GUM', 316 ],
+ [ 'Guatemala', 'GT', 'GTM', 320 ],
+ [ 'Guernsey', 'GG', 'GGY', 831 ],
+ [ 'Guinea', 'GN', 'GIN', 324 ],
+ [ 'Guinea-Bissau', 'GW', 'GNB', 624 ],
+ [ 'Guyana', 'GY', 'GUY', 328 ],
+ [ 'Haiti', 'HT', 'HTI', 332 ],
+ [ 'Heard Island and McDonald Mcdonald Islands', 'HM', 'HMD', 334 ],
+ [ 'Holy See (Vatican City State)', 'VA', 'VAT', 336 ],
+ [ 'Honduras', 'HN', 'HND', 340 ],
+ [ 'Hong Kong', 'HK', 'HKG', 344 ],
+ [ 'Hungary', 'HU', 'HUN', 348 ],
+ [ 'Iceland', 'IS', 'ISL', 352 ],
+ [ 'India', 'IN', 'IND', 356 ],
+ [ 'Indonesia', 'ID', 'IDN', 360 ],
+ [ 'Iran, Islamic Republic of', 'IR', 'IRN', 364 ],
+ [ 'Iraq', 'IQ', 'IRQ', 368 ],
+ [ 'Ireland', 'IE', 'IRL', 372 ],
+ [ 'Isle of Man', 'IM', 'IMN', 833 ],
+ [ 'Israel', 'IL', 'ISR', 376 ],
+ [ 'Italy', 'IT', 'ITA', 380 ],
+ [ 'Jamaica', 'JM', 'JAM', 388 ],
+ [ 'Japan', 'JP', 'JPN', 392 ],
+ [ 'Jersey', 'JE', 'JEY', 832 ],
+ [ 'Jordan', 'JO', 'JOR', 400 ],
+ [ 'Kazakhstan', 'KZ', 'KAZ', 398 ],
+ [ 'Kenya', 'KE', 'KEN', 404 ],
+ [ 'Kiribati', 'KI', 'KIR', 296 ],
+ [ 'Korea, Democratic People\'s Republic of', 'KP', 'PRK', 408 ],
+ [ 'Korea, Republic of', 'KR', 'KOR', 410 ],
+ [ 'Kuwait', 'KW', 'KWT', 414 ],
+ [ 'Kyrgyzstan', 'KG', 'KGZ', 417 ],
+ [ 'Lao People\'s Democratic Republic', 'LA', 'LAO', 418 ],
+ [ 'Latvia', 'LV', 'LVA', 428 ],
+ [ 'Lebanon', 'LB', 'LBN', 422 ],
+ [ 'Lesotho', 'LS', 'LSO', 426 ],
+ [ 'Liberia', 'LR', 'LBR', 430 ],
+ [ 'Libya', 'LY', 'LBY', 434 ],
+ [ 'Liechtenstein', 'LI', 'LIE', 438 ],
+ [ 'Lithuania', 'LT', 'LTU', 440 ],
+ [ 'Luxembourg', 'LU', 'LUX', 442 ],
+ [ 'Macao', 'MO', 'MAC', 446 ],
+ [ 'Macedonia, the Former Yugoslav Republic of', 'MK', 'MKD', 807 ],
+ [ 'Madagascar', 'MG', 'MDG', 450 ],
+ [ 'Malawi', 'MW', 'MWI', 454 ],
+ [ 'Malaysia', 'MY', 'MYS', 458 ],
+ [ 'Maldives', 'MV', 'MDV', 462 ],
+ [ 'Mali', 'ML', 'MLI', 466 ],
+ [ 'Malta', 'MT', 'MLT', 470 ],
+ [ 'Marshall Islands', 'MH', 'MHL', 584 ],
+ [ 'Martinique', 'MQ', 'MTQ', 474 ],
+ [ 'Mauritania', 'MR', 'MRT', 478 ],
+ [ 'Mauritius', 'MU', 'MUS', 480 ],
+ [ 'Mayotte', 'YT', 'MYT', 175 ],
+ [ 'Mexico', 'MX', 'MEX', 484 ],
+ [ 'Micronesia, Federated States of', 'FM', 'FSM', 583 ],
+ [ 'Moldova, Republic of', 'MD', 'MDA', 498 ],
+ [ 'Monaco', 'MC', 'MCO', 492 ],
+ [ 'Mongolia', 'MN', 'MNG', 496 ],
+ [ 'Montenegro', 'ME', 'MNE', 499 ],
+ [ 'Montserrat', 'MS', 'MSR', 500 ],
+ [ 'Morocco', 'MA', 'MAR', 504 ],
+ [ 'Mozambique', 'MZ', 'MOZ', 508 ],
+ [ 'Myanmar', 'MM', 'MMR', 104 ],
+ [ 'Namibia', 'NA', 'NAM', 516 ],
+ [ 'Nauru', 'NR', 'NRU', 520 ],
+ [ 'Nepal', 'NP', 'NPL', 524 ],
+ [ 'Netherlands', 'NL', 'NLD', 528 ],
+ [ 'New Caledonia', 'NC', 'NCL', 540 ],
+ [ 'New Zealand', 'NZ', 'NZL', 554 ],
+ [ 'Nicaragua', 'NI', 'NIC', 558 ],
+ [ 'Niger', 'NE', 'NER', 562 ],
+ [ 'Nigeria', 'NG', 'NGA', 566 ],
+ [ 'Niue', 'NU', 'NIU', 570 ],
+ [ 'Norfolk Island', 'NF', 'NFK', 574 ],
+ [ 'Northern Mariana Islands', 'MP', 'MNP', 580 ],
+ [ 'Norway', 'NO', 'NOR', 578 ],
+ [ 'Oman', 'OM', 'OMN', 512 ],
+ [ 'Pakistan', 'PK', 'PAK', 586 ],
+ [ 'Palau', 'PW', 'PLW', 585 ],
+ [ 'Palestine, State of', 'PS', 'PSE', 275 ],
+ [ 'Panama', 'PA', 'PAN', 591 ],
+ [ 'Papua New Guinea', 'PG', 'PNG', 598 ],
+ [ 'Paraguay', 'PY', 'PRY', 600 ],
+ [ 'Peru', 'PE', 'PER', 604 ],
+ [ 'Philippines', 'PH', 'PHL', 608 ],
+ [ 'Pitcairn', 'PN', 'PCN', 612 ],
+ [ 'Poland', 'PL', 'POL', 616 ],
+ [ 'Portugal', 'PT', 'PRT', 620 ],
+ [ 'Puerto Rico', 'PR', 'PRI', 630 ],
+ [ 'Qatar', 'QA', 'QAT', 634 ],
+ [ 'Romania', 'RO', 'ROU', 642 ],
+ [ 'Russian Federation', 'RU', 'RUS', 643 ],
+ [ 'Rwanda', 'RW', 'RWA', 646 ],
+ [ 'Reunion', 'RE', 'REU', 638 ],
+ [ 'Saint Barthalemy', 'BL', 'BLM', 652 ],
+ [ 'Saint Helena', 'SH', 'SHN', 654 ],
+ [ 'Saint Kitts and Nevis', 'KN', 'KNA', 659 ],
+ [ 'Saint Lucia', 'LC', 'LCA', 662 ],
+ [ 'Saint Martin (French part)', 'MF', 'MAF', 663 ],
+ [ 'Saint Pierre and Miquelon', 'PM', 'SPM', 666 ],
+ [ 'Saint Vincent and the Grenadines', 'VC', 'VCT', 670 ],
+ [ 'Samoa', 'WS', 'WSM', 882 ],
+ [ 'San Marino', 'SM', 'SMR', 674 ],
+ [ 'Sao Tome and Principe', 'ST', 'STP', 678 ],
+ [ 'Saudi Arabia', 'SA', 'SAU', 682 ],
+ [ 'Senegal', 'SN', 'SEN', 686 ],
+ [ 'Serbia', 'RS', 'SRB', 688 ],
+ [ 'Seychelles', 'SC', 'SYC', 690 ],
+ [ 'Sierra Leone', 'SL', 'SLE', 694 ],
+ [ 'Singapore', 'SG', 'SGP', 702 ],
+ [ 'Sint Maarten (Dutch part)', 'SX', 'SXM', 534 ],
+ [ 'Slovakia', 'SK', 'SVK', 703 ],
+ [ 'Slovenia', 'SI', 'SVN', 705 ],
+ [ 'Solomon Islands', 'SB', 'SLB', 90 ],
+ [ 'Somalia', 'SO', 'SOM', 706 ],
+ [ 'South Africa', 'ZA', 'ZAF', 710 ],
+ [ 'South Georgia and the South Sandwich Islands', 'GS', 'SGS', 239 ],
+ [ 'South Sudan', 'SS', 'SSD', 728 ],
+ [ 'Spain', 'ES', 'ESP', 724 ],
+ [ 'Sri Lanka', 'LK', 'LKA', 144 ],
+ [ 'Sudan', 'SD', 'SDN', 729 ],
+ [ 'Suriname', 'SR', 'SUR', 740 ],
+ [ 'Svalbard and Jan Mayen', 'SJ', 'SJM', 744 ],
+ [ 'Swaziland', 'SZ', 'SWZ', 748 ],
+ [ 'Sweden', 'SE', 'SWE', 752 ],
+ [ 'Switzerland', 'CH', 'CHE', 756 ],
+ [ 'Syrian Arab Republic', 'SY', 'SYR', 760 ],
+ [ 'Taiwan, Province of China', 'TW', 'TWN', 158 ],
+ [ 'Tajikistan', 'TJ', 'TJK', 762 ],
+ [ 'United Republic of Tanzania', 'TZ', 'TZA', 834 ],
+ [ 'Thailand', 'TH', 'THA', 764 ],
+ [ 'Timor-Leste', 'TL', 'TLS', 626 ],
+ [ 'Togo', 'TG', 'TGO', 768 ],
+ [ 'Tokelau', 'TK', 'TKL', 772 ],
+ [ 'Tonga', 'TO', 'TON', 776 ],
+ [ 'Trinidad and Tobago', 'TT', 'TTO', 780 ],
+ [ 'Tunisia', 'TN', 'TUN', 788 ],
+ [ 'Turkey', 'TR', 'TUR', 792 ],
+ [ 'Turkmenistan', 'TM', 'TKM', 795 ],
+ [ 'Turks and Caicos Islands', 'TC', 'TCA', 796 ],
+ [ 'Tuvalu', 'TV', 'TUV', 798 ],
+ [ 'Uganda', 'UG', 'UGA', 800 ],
+ [ 'Ukraine', 'UA', 'UKR', 804 ],
+ [ 'United Arab Emirates', 'AE', 'ARE', 784 ],
+ [ 'United Kingdom', 'GB', 'GBR', 826 ],
+ [ 'United States', 'US', 'USA', 840 ],
+ [ 'United States Minor Outlying Islands', 'UM', 'UMI', 581 ],
+ [ 'Uruguay', 'UY', 'URY', 858 ],
+ [ 'Uzbekistan', 'UZ', 'UZB', 860 ],
+ [ 'Vanuatu', 'VU', 'VUT', 548 ],
+ [ 'Venezuela', 'VE', 'VEN', 862 ],
+ [ 'Viet Nam', 'VN', 'VNM', 704 ],
+ [ 'British Virgin Islands', 'VG', 'VGB', 92 ],
+ [ 'US Virgin Islands', 'VI', 'VIR', 850 ],
+ [ 'Wallis and Futuna', 'WF', 'WLF', 876 ],
+ [ 'Western Sahara', 'EH', 'ESH', 732 ],
+ [ 'Yemen', 'YE', 'YEM', 887 ],
+ [ 'Zambia', 'ZM', 'ZMB', 894 ],
+ [ 'Zimbabwe', 'ZW', 'ZWE', 716 ],
+ [ 'Aland Islands', 'AX', 'ALA', 248 ]
+ ];
+
+ var bod = $('#codes-body');
+
+ function addRow(name, a2, a3, num) {
+ bod.append('<tr>' +
+ '<td>'+ name + '</td>' +
+ '<td class="code">'+ a2 + '</td>' +
+ '<td class="code">'+ a3 + '</td>' +
+ '<td class="num">'+ num + '</td>' +
+ '</tr>');
+ }
+
+ function loadRows() {
+ data.forEach(function (d) {
+ if (d.length) {
+ addRow(d[0], d[1], d[2], d[3]);
+ }
+ });
+ }
+
+ loadRows();
+</script>
+
+</body>
+</html>
diff --git a/web/gui/src/main/webapp/_dev/topojson/samerica.html b/web/gui/src/main/webapp/_dev/topojson/samerica.html
new file mode 100644
index 0000000..15bb331
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/topojson/samerica.html
@@ -0,0 +1,87 @@
+<!--
+ -- Sample code to show extracting country data from a countries TopoJSON
+ -- file and projecting it into an SVG layer.
+ --
+ -- See: http://bl.ocks.org/pnavarrc/62047b5638d624cfa9cb
+ -->
+<html>
+<head>
+ <title>S America</title>
+
+ <script charset="utf-8" src="../../tp/d3.min.js"></script>
+ <script charset="utf-8" src="../../tp/topojson.v1.min.js"></script>
+
+ <style>
+ svg {
+ border: 1px solid #888;
+ }
+ .country {
+ fill: #bcd1ff;
+ stroke: #7c79e6;
+ stroke-width: 1;
+ }
+ </style>
+</head>
+
+<body>
+ <div id="map"></div>
+
+ <script>
+ var datapath = '../../data/map/countries.topojson',
+ height = 500,
+ width = 500;
+
+ // create geographic projection
+ var projection = d3.geo.mercator()
+ .translate([width/2, height/2]);
+
+ // configure path generator
+ var pathGenerator = d3.geo.path()
+ .projection(projection);
+
+ var div = d3.select('#map'),
+ svg = div.append('svg'),
+ grp = svg.append('g');
+
+ svg.attr('width', width).attr('height', height);
+
+ d3.json(datapath, function (error, data) {
+ if (error) {
+ console.error(error);
+ throw error;
+ }
+
+ var features = topojson.feature(data, data.objects.countries).features;
+
+ // S.America
+ var southAmerica = features.filter(function (country) {
+ return country.properties.continent === 'South America';
+ });
+
+ var southAmericaFeature = {
+ type: 'FeatureCollection',
+ features: southAmerica
+ };
+
+ // compute bounds and centroid
+ var bounds = d3.geo.bounds(southAmericaFeature),
+ center = d3.geo.centroid(southAmericaFeature);
+
+ // compute angular distance between bound corners
+ var distance = d3.geo.distance(bounds[0], bounds[1]),
+ scale = height / distance / Math.sqrt(2);
+
+ // update projection
+ projection.scale(scale).center(center);
+
+ // draw
+ var countries = grp.selectAll('path.country')
+ .data([southAmericaFeature]);
+ countries.enter().append('path').classed('country', true);
+ countries.attr('d', pathGenerator);
+ countries.exit().remove();
+ });
+ </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/_dev/trie-test.html b/web/gui/src/main/webapp/_dev/trie-test.html
new file mode 100644
index 0000000..2d6517a
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/trie-test.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright 2016 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!--
+ ONOS -- Sample use of trie functions in fn.js
+ -->
+
+<html>
+<head lang="en">
+ <meta charset="UTF-8">
+ <title>Test Trie Functions</title>
+
+ <script type="text/javascript" src="../tp/angular.js"></script>
+ <script type="text/javascript" src="../tp/angular-route.js"></script>
+
+ <script type="text/javascript" src="../tp/d3.js"></script>
+
+ <script type="text/javascript" src="../app/fw/util/util.js"></script>
+ <script type="text/javascript" src="../app/fw/util/fn.js"></script>
+
+ <script type="text/javascript" src="trie-test.js"></script>
+
+ <link rel="stylesheet" href="../app/common.css">
+
+ <style>
+ html,
+ body {
+ background-color: #ddf;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 9pt;
+ }
+
+ h2 {
+ color: darkred;
+ }
+
+ #output div {
+ font-family: monospace;
+ white-space: pre;
+ }
+ </style>
+
+</head>
+
+<!-- outline for using a controller in Angular -->
+<body class="light" ng-app="trie" ng-controller="OvTrieTest as ctrl">
+ <h2>Testing the Trie Functions</h2>
+ <div id="output"></div>
+</body>
+</html>
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/_dev/trie-test.js b/web/gui/src/main/webapp/_dev/trie-test.js
new file mode 100644
index 0000000..2c8716c
--- /dev/null
+++ b/web/gui/src/main/webapp/_dev/trie-test.js
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Test code illustrating use of trie functions
+ */
+
+(function () {
+ 'use strict';
+
+ // injected refs
+ var $log, fs;
+
+ // internal state
+ var out,
+ trie = {},
+ counter = 5000;
+
+ function write(string) {
+ out.append('div').text(string);
+ }
+
+ function lookup(word) {
+ var result = fs.trieLookup(trie, word),
+ f = fs.isF(result),
+ show = f ? '{function}' : result;
+
+
+ write('------> ' + word + ' ==> ' + show);
+
+ f && f();
+ }
+
+ function add(word, data) {
+ var result = fs.addToTrie(trie, word, data);
+ write(' ADD> ' + word + ' [' + data + '] ==> ' + result);
+ }
+
+ function remove(word) {
+ var result = fs.removeFromTrie(trie, word);
+ write('REMOVE> ' + word + ' ==> ' + result);
+ }
+
+ function func1() {
+ counter++;
+ write('** function call ** ' + counter);
+ }
+
+ function func2() {
+ counter += 11;
+ write('** alternate call ** ' + counter);
+ }
+
+ function runTests() {
+ lookup('cat');
+
+ add('cat', 101);
+
+ lookup('ca');
+ lookup('cat');
+ lookup('cats');
+
+ add('cab', 103);
+ add('cog', 105);
+
+ lookup('cut');
+ lookup('cab');
+
+ remove('cab');
+
+ lookup('cab');
+ lookup('cat');
+
+ add('fun', func1);
+
+ lookup('fun');
+ lookup('fun');
+ lookup('fun');
+ lookup('cat');
+ lookup('fun');
+
+ add('fun', func2);
+
+ lookup('fun');
+ lookup('fun');
+ lookup('fun');
+
+ remove('fun');
+
+ lookup('fun');
+ }
+
+ angular.module('trie', ['onosUtil'])
+ .controller('OvTrieTest', ['$log', 'FnService',
+
+ function (_$log_, _fs_) {
+ $log = _$log_;
+ fs = _fs_;
+ out = d3.select('#output');
+
+ runTests();
+ }]);
+}());