jira_dependency_visualizer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cd184318e4e1123ce0623671d1bf5fa5e1d3f15d
4
+ data.tar.gz: ae6a5e18503bbf86e8205ef5e00639eaf5502b00
5
+ SHA512:
6
+ metadata.gz: 1f12ce3b3a0dcb251973172e276d51276d92f694c4e4af96bc0288aac4bdf2a8574669cb9260793ed99eea2f1f2bbc3035d4c56383c25b475ebf001eb5aa366e
7
+ data.tar.gz: 14bbfa4f6fefbbe79327dd7304a666be0510d46cc9f8a18b7a7da4f19c0ddc00a2b06256fcb5ec030f9ccc1a4ce9d73a347a56655e47a3092e5cec24071e3880
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior
38
+ may be reported by contacting a project maintainer. All complaints
39
+ will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers
41
+ are obligated to maintain confidentiality with regard to the reporter
42
+ of an incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,129 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jira_dependency_visualizer (0.1.0)
5
+ jira-ruby (~> 0.1)
6
+ ruby-graphviz (~> 1.2)
7
+ trollop (~> 2.1)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activesupport (4.2.6)
13
+ i18n (~> 0.7)
14
+ json (~> 1.7, >= 1.7.7)
15
+ minitest (~> 5.1)
16
+ thread_safe (~> 0.3, >= 0.3.4)
17
+ tzinfo (~> 1.1)
18
+ ast (2.2.0)
19
+ coderay (1.1.1)
20
+ coveralls (0.8.13)
21
+ json (~> 1.8)
22
+ simplecov (~> 0.11.0)
23
+ term-ansicolor (~> 1.3)
24
+ thor (~> 0.19.1)
25
+ tins (~> 1.6.0)
26
+ diff-lcs (1.2.5)
27
+ docile (1.1.5)
28
+ factory_girl (4.5.0)
29
+ activesupport (>= 3.0.0)
30
+ ffi (1.9.10)
31
+ formatador (0.2.5)
32
+ guard (2.13.0)
33
+ formatador (>= 0.2.4)
34
+ listen (>= 2.7, <= 4.0)
35
+ lumberjack (~> 1.0)
36
+ nenv (~> 0.1)
37
+ notiffany (~> 0.0)
38
+ pry (>= 0.9.12)
39
+ shellany (~> 0.0)
40
+ thor (>= 0.18.1)
41
+ guard-compat (1.2.1)
42
+ guard-rspec (4.6.4)
43
+ guard (~> 2.1)
44
+ guard-compat (~> 1.1)
45
+ rspec (>= 2.99.0, < 4.0)
46
+ i18n (0.7.0)
47
+ jira-ruby (0.1.17)
48
+ activesupport
49
+ oauth (~> 0.4.7)
50
+ json (1.8.3)
51
+ listen (3.0.6)
52
+ rb-fsevent (>= 0.9.3)
53
+ rb-inotify (>= 0.9.7)
54
+ lumberjack (1.0.10)
55
+ method_source (0.8.2)
56
+ minitest (5.8.4)
57
+ nenv (0.3.0)
58
+ notiffany (0.0.8)
59
+ nenv (~> 0.1)
60
+ shellany (~> 0.0)
61
+ oauth (0.4.7)
62
+ parser (2.3.0.6)
63
+ ast (~> 2.2)
64
+ powerpack (0.1.1)
65
+ pry (0.10.3)
66
+ coderay (~> 1.1.0)
67
+ method_source (~> 0.8.1)
68
+ slop (~> 3.4)
69
+ rainbow (2.1.0)
70
+ rake (10.5.0)
71
+ rb-fsevent (0.9.7)
72
+ rb-inotify (0.9.7)
73
+ ffi (>= 0.5.0)
74
+ rspec (3.4.0)
75
+ rspec-core (~> 3.4.0)
76
+ rspec-expectations (~> 3.4.0)
77
+ rspec-mocks (~> 3.4.0)
78
+ rspec-core (3.4.4)
79
+ rspec-support (~> 3.4.0)
80
+ rspec-expectations (3.4.0)
81
+ diff-lcs (>= 1.2.0, < 2.0)
82
+ rspec-support (~> 3.4.0)
83
+ rspec-mocks (3.4.1)
84
+ diff-lcs (>= 1.2.0, < 2.0)
85
+ rspec-support (~> 3.4.0)
86
+ rspec-support (3.4.1)
87
+ rubocop (0.37.2)
88
+ parser (>= 2.3.0.4, < 3.0)
89
+ powerpack (~> 0.1)
90
+ rainbow (>= 1.99.1, < 3.0)
91
+ ruby-progressbar (~> 1.7)
92
+ unicode-display_width (~> 0.3)
93
+ ruby-graphviz (1.2.2)
94
+ ruby-progressbar (1.7.5)
95
+ shellany (0.0.1)
96
+ simplecov (0.11.2)
97
+ docile (~> 1.1.0)
98
+ json (~> 1.8)
99
+ simplecov-html (~> 0.10.0)
100
+ simplecov-html (0.10.0)
101
+ slop (3.6.0)
102
+ term-ansicolor (1.3.2)
103
+ tins (~> 1.0)
104
+ thor (0.19.1)
105
+ thread_safe (0.3.5)
106
+ tins (1.6.0)
107
+ trollop (2.1.2)
108
+ tzinfo (1.2.2)
109
+ thread_safe (~> 0.1)
110
+ unicode-display_width (0.3.1)
111
+ yard (0.8.7.6)
112
+
113
+ PLATFORMS
114
+ ruby
115
+
116
+ DEPENDENCIES
117
+ bundler (~> 1.11)
118
+ coveralls (~> 0.8)
119
+ factory_girl (~> 4.5)
120
+ guard-rspec (~> 4.6)
121
+ jira_dependency_visualizer!
122
+ pry (~> 0.10)
123
+ rake (~> 10.5)
124
+ rspec (~> 3.4)
125
+ rubocop (~> 0.37)
126
+ yard (~> 0.8)
127
+
128
+ BUNDLED WITH
129
+ 1.11.2
data/Guardfile ADDED
@@ -0,0 +1,11 @@
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
+ # watch /lib/ files
3
+ watch(%r{^lib/(.+).rb$}) do |m|
4
+ "spec/#{m[1]}_spec.rb"
5
+ end
6
+
7
+ # watch /spec/ files
8
+ watch(%r{^spec/(.+).rb$}) do |m|
9
+ "spec/#{m[1]}.rb"
10
+ end
11
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 alejandro.figueroa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ [![Build Status](https://travis-ci.org/thejandroman/jira_dependency_visualizer.svg?branch=master)](https://travis-ci.org/thejandroman/jira_dependency_visualizer)
2
+
3
+ # JiraDependencyVisualizer
4
+
5
+ This gem was created as a way to visualize dependencies between
6
+ tickets in Jira. The initial use case was to view how an epic's
7
+ dependent tickets were interconnected along with their current status.
8
+
9
+ The status colors in the graph are customizable via a yaml file. See
10
+ `./config/color.yaml` for an example.
11
+
12
+ ## Dependencies
13
+
14
+ This gem requires the graphviz package to be installed. On
15
+ Mac/homebrew: `brew install graphviz`.
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'jira_dependency_visualizer'
23
+ ```
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install jira_dependency_visualizer
32
+
33
+ ## Usage
34
+
35
+ The gem can be consumed as either a CLI tool or as a library.
36
+
37
+ ### CLI Tool
38
+
39
+ $ jira_dependency_visualizer --help
40
+
41
+ ### Library
42
+
43
+ See documentation: http://www.rubydoc.info/gems/jira_dependency_visualizer/
44
+
45
+ ## Development
46
+
47
+ After checking out the repo, run `bundle install` to install
48
+ dependencies. Then, run `bundle exec rake` to run the tests.
49
+
50
+ ## Contributing
51
+
52
+ Bug reports and pull requests are welcome on GitHub at
53
+ https://github.com/thejandroman/jira-dependency-visualizer. This
54
+ project is intended to be a safe, welcoming space for collaboration,
55
+ and contributors are expected to adhere to the
56
+ [Contributor Covenant](http://contributor-covenant.org) code of
57
+ conduct.
58
+
59
+ ## License
60
+
61
+ The gem is available as open source under the terms of the
62
+ [MIT License](http://opensource.org/licenses/MIT).
63
+
64
+ ## Attribution
65
+
66
+ This ruby gem is heavily influenced by
67
+ https://github.com/pawelrychlik/jira-dependency-graph.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+ require 'yard'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ RuboCop::RakeTask.new
9
+
10
+ task default: [:rubocop, :spec]
11
+
12
+ YARD::Rake::YardocTask.new
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+ require 'jira_dependency_visualizer'
3
+ require 'yaml'
4
+ require 'trollop'
5
+
6
+ opts = Trollop.options do
7
+ version JiraDependencyVisualizer::VERSION
8
+ banner <<-EOS
9
+ Takes a Jira ticket and builds a dependency graph based on that
10
+ ticket's dependent tickets.
11
+
12
+ Usage:
13
+ jira_dependency_visualizer [options]
14
+ where [options] are:
15
+ EOS
16
+
17
+ opt :color_config,
18
+ 'YAML file specifying the colors to use in the graph',
19
+ type: :string
20
+
21
+ opt :context_path,
22
+ 'The Jira application\'s context path',
23
+ type: :string,
24
+ short: 'c',
25
+ default: ''
26
+
27
+ opt :exclude_link,
28
+ 'Jira issue link to exclude; can be specified multiple times',
29
+ type: :string,
30
+ short: 'e',
31
+ multi: true
32
+
33
+ opt :graph_format,
34
+ 'The format to write the dependency graph in',
35
+ type: :string,
36
+ short: 'f',
37
+ default: 'svg'
38
+
39
+ opt :graph_filename,
40
+ 'The filename to write the dependency graph to',
41
+ type: :string,
42
+ short: 'g',
43
+ default: './issue_graph.svg'
44
+
45
+ opt :issue_id,
46
+ 'The issue ID visualize',
47
+ type: :string,
48
+ short: 'i',
49
+ required: true
50
+
51
+ opt :password,
52
+ '[REQUIRED] The Jira user\'s password',
53
+ type: :string,
54
+ short: 'p',
55
+ required: true
56
+
57
+ opt :proxy_address,
58
+ 'The proxy address',
59
+ type: :string
60
+
61
+ opt :proxy_port,
62
+ 'The proxy port',
63
+ type: :int
64
+
65
+ opt :read_timeout,
66
+ 'Number of seconds to wait for data to be read',
67
+ type: :int,
68
+ short: 't'
69
+
70
+ opt :rest_base_path,
71
+ 'The Jira rest API base path',
72
+ type: :string,
73
+ short: 'r',
74
+ default: '/rest/api/latest'
75
+
76
+ opt :site,
77
+ '[REQUIRED] URL for Jira',
78
+ type: :string,
79
+ short: 's',
80
+ required: true
81
+
82
+ opt :use_ssl,
83
+ 'Whether to use SSL',
84
+ type: :flag,
85
+ default: true
86
+
87
+ opt :username,
88
+ '[REQUIRED] The Jira user\'s username',
89
+ type: :string,
90
+ short: 'u',
91
+ required: true
92
+ end
93
+
94
+ puts 'Building options...'
95
+ opts[:auth_type] = :basic
96
+
97
+ colors = opts[:color_config] ? YAML.load_file(opts.delete(:color_config)) : {}
98
+
99
+ exclude_links = opts.delete(:exclude_link)
100
+ issue_id = opts.delete(:issue_id)
101
+ graph_filename = opts.delete(:graph_filename)
102
+ graph_format = opts.delete(:graph_format)
103
+
104
+ puts 'Creating objects...'
105
+ jira = JiraDependencyVisualizer::Jira.new(opts)
106
+ graph = JiraDependencyVisualizer::Graph.new(issue_id, jira, exclude_links, colors)
107
+
108
+ puts 'Finding dependencies...'
109
+ graph.walk
110
+
111
+ puts 'Creating dependency graph...'
112
+ graph.write_graph(graph_filename, graph_format)
data/issue_graph.svg ADDED
@@ -0,0 +1,339 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <!-- Generated by graphviz version 2.38.0 (20140413.2041)
5
+ -->
6
+ <!-- Title: INF&#45;1855 Pages: 1 -->
7
+ <svg width="1760pt" height="461pt"
8
+ viewBox="0.00 0.00 1759.98 461.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
+ <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 457)">
10
+ <title>INF&#45;1855</title>
11
+ <polygon fill="white" stroke="none" points="-4,4 -4,-457 1755.98,-457 1755.98,4 -4,4"/>
12
+ <!-- INF&#45;1855 -->
13
+ <g id="node1" class="node"><title>INF&#45;1855</title>
14
+ <ellipse fill="none" stroke="black" cx="1019.99" cy="-435" rx="44.9768" ry="18"/>
15
+ <text text-anchor="middle" x="1019.99" y="-430.8" font-family="Times,serif" font-size="14.00">INF&#45;1855</text>
16
+ </g>
17
+ <!-- INF&#45;1971 -->
18
+ <g id="node2" class="node"><title>INF&#45;1971</title>
19
+ <g id="a_node2"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1971" xlink:title="Logsync user for pushing TDN logs">
20
+ <ellipse fill="green" stroke="black" cx="44.9884" cy="-362" rx="44.9768" ry="18"/>
21
+ <text text-anchor="middle" x="44.9884" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1971</text>
22
+ </a>
23
+ </g>
24
+ </g>
25
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1971 -->
26
+ <g id="edge1" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1971</title>
27
+ <path fill="none" stroke="orange" d="M975.195,-432.338C863.929,-428.085 566.04,-415.938 317.988,-399 220.516,-392.344 194.821,-399.004 98.9884,-380 95.1396,-379.237 91.178,-378.298 87.2323,-377.257"/>
28
+ <polygon fill="orange" stroke="orange" points="88.1066,-373.867 77.5307,-374.502 86.1939,-380.601 88.1066,-373.867"/>
29
+ </g>
30
+ <!-- INF&#45;1970 -->
31
+ <g id="node3" class="node"><title>INF&#45;1970</title>
32
+ <g id="a_node3"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1970" xlink:title="Tagsync AWS user in aws&#45;china for instance scanning">
33
+ <ellipse fill="lightgrey" stroke="black" cx="152.988" cy="-362" rx="44.9768" ry="18"/>
34
+ <text text-anchor="middle" x="152.988" y="-357.8" font-family="Times,serif" font-size="14.00">INF&#45;1970</text>
35
+ </a>
36
+ </g>
37
+ </g>
38
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1970 -->
39
+ <g id="edge2" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1970</title>
40
+ <path fill="none" stroke="orange" d="M974.566,-434.754C850.425,-436.007 495.467,-434.182 206.988,-380 203.132,-379.276 199.165,-378.364 195.216,-377.341"/>
41
+ <polygon fill="orange" stroke="orange" points="196.084,-373.949 185.51,-374.611 194.189,-380.688 196.084,-373.949"/>
42
+ </g>
43
+ <!-- INF&#45;1969 -->
44
+ <g id="node4" class="node"><title>INF&#45;1969</title>
45
+ <g id="a_node4"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1969" xlink:title="Tagsync to support different provider settings per taget">
46
+ <ellipse fill="green" stroke="black" cx="260.988" cy="-362" rx="44.9768" ry="18"/>
47
+ <text text-anchor="middle" x="260.988" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1969</text>
48
+ </a>
49
+ </g>
50
+ </g>
51
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1969 -->
52
+ <g id="edge3" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1969</title>
53
+ <path fill="none" stroke="orange" d="M975.997,-431.225C889.158,-425.677 689.582,-412.579 521.988,-399 429.903,-391.539 405.565,-398.197 314.988,-380 311.142,-379.227 307.181,-378.282 303.236,-377.237"/>
54
+ <polygon fill="orange" stroke="orange" points="304.112,-373.847 293.536,-374.475 302.195,-380.58 304.112,-373.847"/>
55
+ </g>
56
+ <!-- INF&#45;1968 -->
57
+ <g id="node5" class="node"><title>INF&#45;1968</title>
58
+ <g id="a_node5"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1968" xlink:title="New AWS SSH key for root user">
59
+ <ellipse fill="green" stroke="black" cx="368.988" cy="-362" rx="44.9768" ry="18"/>
60
+ <text text-anchor="middle" x="368.988" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1968</text>
61
+ </a>
62
+ </g>
63
+ </g>
64
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1968 -->
65
+ <g id="edge4" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1968</title>
66
+ <path fill="none" stroke="orange" d="M975.34,-432.34C889.166,-428.797 694.02,-419.121 530.988,-399 482.618,-393.03 470.334,-391.565 422.988,-380 419.387,-379.12 415.675,-378.131 411.962,-377.083"/>
67
+ <polygon fill="orange" stroke="orange" points="412.792,-373.679 402.211,-374.208 410.813,-380.393 412.792,-373.679"/>
68
+ </g>
69
+ <!-- INF&#45;1967 -->
70
+ <g id="node6" class="node"><title>INF&#45;1967</title>
71
+ <g id="a_node6"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1967" xlink:title="Nginx server_name setting difference for aws&#45;china/domain">
72
+ <ellipse fill="purple" stroke="black" cx="518.988" cy="-276" rx="44.9768" ry="18"/>
73
+ <text text-anchor="middle" x="518.988" y="-271.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1967</text>
74
+ </a>
75
+ </g>
76
+ </g>
77
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1967 -->
78
+ <g id="edge5" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1967</title>
79
+ <path fill="none" stroke="orange" d="M975.043,-433.958C874.151,-433.032 633.452,-425.931 568.988,-380 568.988,-380 546.563,-333.804 531.749,-303.287"/>
80
+ <polygon fill="orange" stroke="orange" points="534.761,-301.476 527.245,-294.008 528.463,-304.533 534.761,-301.476"/>
81
+ </g>
82
+ <!-- INF&#45;1966 -->
83
+ <g id="node7" class="node"><title>INF&#45;1966</title>
84
+ <g id="a_node7"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1966" xlink:title="Different GPG keys/password for TDN files backup from manage">
85
+ <ellipse fill="green" stroke="black" cx="622.988" cy="-362" rx="44.9768" ry="18"/>
86
+ <text text-anchor="middle" x="622.988" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1966</text>
87
+ </a>
88
+ </g>
89
+ </g>
90
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1966 -->
91
+ <g id="edge6" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1966</title>
92
+ <path fill="none" stroke="orange" d="M977.082,-429.326C911.749,-421.743 783.652,-405.039 676.988,-380 673.379,-379.153 669.661,-378.186 665.945,-377.154"/>
93
+ <polygon fill="orange" stroke="orange" points="666.768,-373.748 656.188,-374.304 664.806,-380.467 666.768,-373.748"/>
94
+ </g>
95
+ <!-- INF&#45;1965 -->
96
+ <g id="node8" class="node"><title>INF&#45;1965</title>
97
+ <g id="a_node8"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1965" xlink:title="AWS bucket to pull initial TDN files from in China">
98
+ <ellipse fill="lightgrey" stroke="black" cx="730.988" cy="-362" rx="44.9768" ry="18"/>
99
+ <text text-anchor="middle" x="730.988" y="-357.8" font-family="Times,serif" font-size="14.00">INF&#45;1965</text>
100
+ </a>
101
+ </g>
102
+ </g>
103
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1965 -->
104
+ <g id="edge7" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1965</title>
105
+ <path fill="none" stroke="orange" d="M980.667,-425.959C933.805,-416.148 853.257,-398.558 784.988,-380 781.461,-379.041 777.82,-378.002 774.171,-376.927"/>
106
+ <polygon fill="orange" stroke="orange" points="775.155,-373.568 764.57,-374.024 773.129,-380.268 775.155,-373.568"/>
107
+ </g>
108
+ <!-- INF&#45;1964 -->
109
+ <g id="node9" class="node"><title>INF&#45;1964</title>
110
+ <g id="a_node9"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1964" xlink:title="Monitoring for TDN Nodes in China">
111
+ <ellipse fill="purple" stroke="black" cx="838.988" cy="-362" rx="44.9768" ry="18"/>
112
+ <text text-anchor="middle" x="838.988" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1964</text>
113
+ </a>
114
+ </g>
115
+ </g>
116
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1964 -->
117
+ <g id="edge8" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1964</title>
118
+ <path fill="none" stroke="orange" d="M988.873,-421.795C958.607,-409.922 912.476,-391.827 879.389,-378.848"/>
119
+ <polygon fill="orange" stroke="orange" points="880.587,-375.558 870,-375.165 878.031,-382.075 880.587,-375.558"/>
120
+ </g>
121
+ <!-- INF&#45;1963 -->
122
+ <g id="node10" class="node"><title>INF&#45;1963</title>
123
+ <g id="a_node10"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1963" xlink:title="Special subnet for TDN autoscaling nodes">
124
+ <ellipse fill="green" stroke="black" cx="946.988" cy="-362" rx="44.9768" ry="18"/>
125
+ <text text-anchor="middle" x="946.988" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1963</text>
126
+ </a>
127
+ </g>
128
+ </g>
129
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1963 -->
130
+ <g id="edge9" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1963</title>
131
+ <path fill="none" stroke="orange" d="M1003.42,-417.889C993.742,-408.473 981.362,-396.432 970.665,-386.028"/>
132
+ <polygon fill="orange" stroke="orange" points="972.845,-383.266 963.236,-378.803 967.965,-388.284 972.845,-383.266"/>
133
+ </g>
134
+ <!-- INF&#45;1962 -->
135
+ <g id="node11" class="node"><title>INF&#45;1962</title>
136
+ <g id="a_node11"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1962" xlink:title="ELBs to be created">
137
+ <ellipse fill="green" stroke="black" cx="953.988" cy="-104" rx="44.9768" ry="18"/>
138
+ <text text-anchor="middle" x="953.988" y="-99.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1962</text>
139
+ </a>
140
+ </g>
141
+ </g>
142
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1962 -->
143
+ <g id="edge10" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1962</title>
144
+ <path fill="none" stroke="orange" d="M1016.53,-416.775C1005.73,-362.92 972.531,-197.429 959.407,-132.013"/>
145
+ <polygon fill="orange" stroke="orange" points="962.808,-131.171 957.41,-122.055 955.945,-132.548 962.808,-131.171"/>
146
+ </g>
147
+ <!-- INF&#45;1961 -->
148
+ <g id="node12" class="node"><title>INF&#45;1961</title>
149
+ <g id="a_node12"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1961" xlink:title="Launch Configuration for Autoscaling Groups">
150
+ <ellipse fill="green" stroke="black" cx="1142.99" cy="-18" rx="44.9768" ry="18"/>
151
+ <text text-anchor="middle" x="1142.99" y="-13.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1961</text>
152
+ </a>
153
+ </g>
154
+ </g>
155
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1961 -->
156
+ <g id="edge11" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1961</title>
157
+ <path fill="none" stroke="orange" d="M1064.64,-432.186C1133.41,-428.266 1259.77,-416.194 1282.99,-380 1353.62,-269.891 1368.7,-195.406 1296.99,-86 1274.58,-51.8208 1230.55,-34.984 1195.28,-26.7453"/>
158
+ <polygon fill="orange" stroke="orange" points="1195.64,-23.2415 1185.13,-24.5484 1194.16,-30.0833 1195.64,-23.2415"/>
159
+ </g>
160
+ <!-- INF&#45;1960 -->
161
+ <g id="node13" class="node"><title>INF&#45;1960</title>
162
+ <g id="a_node13"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1960" xlink:title="Autoscaling Groups to be created">
163
+ <ellipse fill="green" stroke="black" cx="1061.99" cy="-104" rx="44.9768" ry="18"/>
164
+ <text text-anchor="middle" x="1061.99" y="-99.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1960</text>
165
+ </a>
166
+ </g>
167
+ </g>
168
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1960 -->
169
+ <g id="edge12" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1960</title>
170
+ <path fill="none" stroke="orange" d="M1034.57,-417.801C1045.29,-404.189 1057.99,-383.692 1057.99,-363 1057.99,-363 1057.99,-363 1057.99,-189 1057.99,-169.957 1059.03,-148.514 1060.05,-132.059"/>
171
+ <polygon fill="orange" stroke="orange" points="1063.54,-132.249 1060.7,-122.042 1056.56,-131.792 1063.54,-132.249"/>
172
+ </g>
173
+ <!-- INF&#45;1959 -->
174
+ <g id="node14" class="node"><title>INF&#45;1959</title>
175
+ <g id="a_node14"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1959" xlink:title="Testing Instance boot time for ELB grace period">
176
+ <ellipse fill="purple" stroke="black" cx="1242.99" cy="-104" rx="44.9768" ry="18"/>
177
+ <text text-anchor="middle" x="1242.99" y="-99.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1959</text>
178
+ </a>
179
+ </g>
180
+ </g>
181
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1959 -->
182
+ <g id="edge13" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1959</title>
183
+ <path fill="none" stroke="orange" d="M1063.88,-430.677C1136.08,-423.989 1271.99,-405.726 1271.99,-363 1271.99,-363 1271.99,-363 1271.99,-189 1271.99,-168.813 1264.41,-147.318 1257.01,-131.126"/>
184
+ <polygon fill="orange" stroke="orange" points="1259.99,-129.263 1252.48,-121.788 1253.69,-132.314 1259.99,-129.263"/>
185
+ </g>
186
+ <!-- INF&#45;1958 -->
187
+ <g id="node15" class="node"><title>INF&#45;1958</title>
188
+ <g id="a_node15"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1958" xlink:title="Transfer AMI to aws&#45;china">
189
+ <ellipse fill="lightgrey" stroke="black" cx="1136.99" cy="-190" rx="44.9768" ry="18"/>
190
+ <text text-anchor="middle" x="1136.99" y="-185.8" font-family="Times,serif" font-size="14.00">INF&#45;1958</text>
191
+ </a>
192
+ </g>
193
+ </g>
194
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1958 -->
195
+ <g id="edge14" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1958</title>
196
+ <path fill="none" stroke="orange" d="M1047.17,-420.594C1056.16,-415.001 1065.51,-407.747 1071.99,-399 1110.97,-346.34 1095.21,-320.46 1114.99,-258 1119.2,-244.687 1124.03,-229.936 1128.09,-217.672"/>
197
+ <polygon fill="orange" stroke="orange" points="1131.45,-218.635 1131.28,-208.041 1124.81,-216.43 1131.45,-218.635"/>
198
+ </g>
199
+ <!-- INF&#45;1957 -->
200
+ <g id="node16" class="node"><title>INF&#45;1957</title>
201
+ <g id="a_node16"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1957" xlink:title="Test AMI build by packer">
202
+ <ellipse fill="lightgrey" stroke="black" cx="1168.99" cy="-276" rx="44.9768" ry="18"/>
203
+ <text text-anchor="middle" x="1168.99" y="-271.8" font-family="Times,serif" font-size="14.00">INF&#45;1957</text>
204
+ </a>
205
+ </g>
206
+ </g>
207
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1957 -->
208
+ <g id="edge15" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1957</title>
209
+ <path fill="none" stroke="orange" d="M1061.94,-428.347C1113.53,-420.436 1196.54,-404.254 1214.99,-380 1233.36,-355.853 1224.03,-338.35 1208.99,-312 1206.24,-307.192 1202.59,-302.715 1198.6,-298.678"/>
210
+ <polygon fill="orange" stroke="orange" points="1200.93,-296.067 1191.19,-291.91 1196.21,-301.237 1200.93,-296.067"/>
211
+ </g>
212
+ <!-- INF&#45;1956 -->
213
+ <g id="node17" class="node"><title>INF&#45;1956</title>
214
+ <g id="a_node17"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1956" xlink:title="Manage DB to support &quot;allow_china&quot; for a space/client">
215
+ <ellipse fill="purple" stroke="black" cx="1382.99" cy="-362" rx="44.9768" ry="18"/>
216
+ <text text-anchor="middle" x="1382.99" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1956</text>
217
+ </a>
218
+ </g>
219
+ </g>
220
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1956 -->
221
+ <g id="edge16" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1956</title>
222
+ <path fill="none" stroke="orange" d="M1065.11,-434.789C1125.67,-434.519 1235.82,-429.323 1323.99,-399 1334.57,-395.363 1345.26,-389.601 1354.59,-383.745"/>
223
+ <polygon fill="orange" stroke="orange" points="1356.63,-386.589 1363.06,-378.167 1352.78,-380.742 1356.63,-386.589"/>
224
+ </g>
225
+ <!-- INF&#45;1955 -->
226
+ <g id="node18" class="node"><title>INF&#45;1955</title>
227
+ <g id="a_node18"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1955" xlink:title="DNS domain decided on/purchased (route53, Ultra)">
228
+ <ellipse fill="purple" stroke="black" cx="476.988" cy="-362" rx="44.9768" ry="18"/>
229
+ <text text-anchor="middle" x="476.988" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1955</text>
230
+ </a>
231
+ </g>
232
+ </g>
233
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1955 -->
234
+ <g id="edge17" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1955</title>
235
+ <path fill="none" stroke="orange" d="M974.898,-433.444C870.892,-431.727 616.921,-424.927 535.988,-399 525.25,-395.56 514.446,-389.795 505.071,-383.875"/>
236
+ <polygon fill="orange" stroke="orange" points="506.834,-380.845 496.569,-378.223 502.959,-386.674 506.834,-380.845"/>
237
+ </g>
238
+ <!-- INF&#45;1954 -->
239
+ <g id="node19" class="node"><title>INF&#45;1954</title>
240
+ <g id="a_node19"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1954" xlink:title="ICP license for 80/443 traffic">
241
+ <ellipse fill="purple" stroke="black" cx="1490.99" cy="-362" rx="44.9768" ry="18"/>
242
+ <text text-anchor="middle" x="1490.99" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;1954</text>
243
+ </a>
244
+ </g>
245
+ </g>
246
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1954 -->
247
+ <g id="edge18" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1954</title>
248
+ <path fill="none" stroke="orange" d="M1064.47,-431.732C1141.42,-427.037 1303.95,-413.721 1436.99,-380 1440.53,-379.102 1444.18,-378.106 1447.84,-377.06"/>
249
+ <polygon fill="orange" stroke="orange" points="1448.86,-380.407 1457.45,-374.205 1446.87,-373.697 1448.86,-380.407"/>
250
+ </g>
251
+ <!-- INF&#45;1556 -->
252
+ <g id="node20" class="node"><title>INF&#45;1556</title>
253
+ <g id="a_node20"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1556" xlink:title="Test Deploying TDN Framework to AWS/Beijing Region">
254
+ <ellipse fill="red" stroke="black" cx="1598.99" cy="-362" rx="44.9768" ry="18"/>
255
+ <text text-anchor="middle" x="1598.99" y="-357.8" font-family="Times,serif" font-size="14.00">INF&#45;1556</text>
256
+ </a>
257
+ </g>
258
+ </g>
259
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1556 -->
260
+ <g id="edge19" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1556</title>
261
+ <path fill="none" stroke="orange" d="M1064.71,-432.507C1155.93,-428.783 1369.63,-416.582 1544.99,-380 1548.67,-379.232 1552.45,-378.314 1556.23,-377.308"/>
262
+ <polygon fill="orange" stroke="orange" points="1557.48,-380.592 1566.14,-374.482 1555.56,-373.861 1557.48,-380.592"/>
263
+ </g>
264
+ <!-- INF&#45;1445 -->
265
+ <g id="node21" class="node"><title>INF&#45;1445</title>
266
+ <g id="a_node21"><a xlink:href="https://ensighten.atlassian.net/browse/INF-1445" xlink:title="Tagsync China Whitelist">
267
+ <ellipse fill="lightgrey" stroke="black" cx="1706.99" cy="-362" rx="44.9768" ry="18"/>
268
+ <text text-anchor="middle" x="1706.99" y="-357.8" font-family="Times,serif" font-size="14.00">INF&#45;1445</text>
269
+ </a>
270
+ </g>
271
+ </g>
272
+ <!-- INF&#45;1855&#45;&gt;INF&#45;1445 -->
273
+ <g id="edge20" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;1445</title>
274
+ <path fill="none" stroke="orange" d="M1065,-433.688C1169.4,-432.201 1435.71,-424.012 1652.99,-380 1656.83,-379.221 1660.79,-378.272 1664.74,-377.224"/>
275
+ <polygon fill="orange" stroke="orange" points="1665.78,-380.566 1674.44,-374.458 1663.86,-373.834 1665.78,-380.566"/>
276
+ </g>
277
+ <!-- INF&#45;324 -->
278
+ <g id="node22" class="node"><title>INF&#45;324</title>
279
+ <g id="a_node22"><a xlink:href="https://ensighten.atlassian.net/browse/INF-324" xlink:title="Capture AWS Tag Server image with Packer">
280
+ <ellipse fill="green" stroke="black" cx="1164.99" cy="-362" rx="40.6335" ry="18"/>
281
+ <text text-anchor="middle" x="1164.99" y="-357.8" font-family="Times,serif" font-size="14.00" fill="white">INF&#45;324</text>
282
+ </a>
283
+ </g>
284
+ </g>
285
+ <!-- INF&#45;1855&#45;&gt;INF&#45;324 -->
286
+ <g id="edge21" class="edge"><title>INF&#45;1855&#45;&gt;INF&#45;324</title>
287
+ <path fill="none" stroke="orange" d="M1053.63,-422.809C1070.86,-416.608 1091.95,-408.281 1109.99,-399 1118.78,-394.475 1127.92,-388.889 1136.17,-383.478"/>
288
+ <polygon fill="orange" stroke="orange" points="1138.37,-386.219 1144.71,-377.734 1134.46,-380.411 1138.37,-386.219"/>
289
+ </g>
290
+ <!-- INF&#45;1960&#45;&gt;INF&#45;1961 -->
291
+ <g id="edge22" class="edge"><title>INF&#45;1960&#45;&gt;INF&#45;1961</title>
292
+ <path fill="none" stroke="red" d="M1070.33,-85.9289C1075.75,-75.9205 1083.46,-63.4321 1092.44,-54 1097.6,-48.5773 1103.72,-43.4993 1109.9,-38.9839"/>
293
+ <polygon fill="red" stroke="red" points="1112.03,-41.7635 1118.27,-33.1958 1108.05,-36.0069 1112.03,-41.7635"/>
294
+ <text text-anchor="middle" x="1111.26" y="-56.8" font-family="Times,serif" font-size="14.00">blocks</text>
295
+ </g>
296
+ <!-- INF&#45;1958&#45;&gt;INF&#45;1962 -->
297
+ <g id="edge26" class="edge"><title>INF&#45;1958&#45;&gt;INF&#45;1962</title>
298
+ <path fill="none" stroke="red" d="M1102.85,-177.979C1084.38,-171.648 1061.34,-163.151 1041.44,-154 1022.8,-145.432 1002.79,-134.366 986.615,-124.919"/>
299
+ <polygon fill="red" stroke="red" points="987.967,-121.652 977.577,-119.575 984.404,-127.678 987.967,-121.652"/>
300
+ <text text-anchor="middle" x="1060.26" y="-142.8" font-family="Times,serif" font-size="14.00">blocks</text>
301
+ </g>
302
+ <!-- INF&#45;1958&#45;&gt;INF&#45;1961 -->
303
+ <g id="edge25" class="edge"><title>INF&#45;1958&#45;&gt;INF&#45;1961</title>
304
+ <path fill="none" stroke="red" d="M1137.6,-171.764C1138.64,-142.159 1140.78,-81.4326 1142.03,-46.1122"/>
305
+ <polygon fill="red" stroke="red" points="1145.53,-46.1462 1142.39,-36.0289 1138.54,-45.8992 1145.53,-46.1462"/>
306
+ <text text-anchor="middle" x="1159.26" y="-99.8" font-family="Times,serif" font-size="14.00">blocks</text>
307
+ </g>
308
+ <!-- INF&#45;1958&#45;&gt;INF&#45;1960 -->
309
+ <g id="edge24" class="edge"><title>INF&#45;1958&#45;&gt;INF&#45;1960</title>
310
+ <path fill="none" stroke="red" d="M1114.83,-174.011C1107.23,-168.27 1099,-161.327 1092.44,-154 1086.19,-147.029 1080.45,-138.619 1075.68,-130.749"/>
311
+ <polygon fill="red" stroke="red" points="1078.58,-128.78 1070.54,-121.878 1072.52,-132.286 1078.58,-128.78"/>
312
+ <text text-anchor="middle" x="1111.26" y="-142.8" font-family="Times,serif" font-size="14.00">blocks</text>
313
+ </g>
314
+ <!-- INF&#45;1958&#45;&gt;INF&#45;1959 -->
315
+ <g id="edge23" class="edge"><title>INF&#45;1958&#45;&gt;INF&#45;1959</title>
316
+ <path fill="none" stroke="red" d="M1156.43,-173.593C1173.02,-160.45 1197.05,-141.404 1215.59,-126.715"/>
317
+ <polygon fill="red" stroke="red" points="1218.01,-129.263 1223.67,-120.309 1213.66,-123.777 1218.01,-129.263"/>
318
+ <text text-anchor="middle" x="1215.26" y="-142.8" font-family="Times,serif" font-size="14.00">blocks</text>
319
+ </g>
320
+ <!-- INF&#45;1957&#45;&gt;INF&#45;1958 -->
321
+ <g id="edge27" class="edge"><title>INF&#45;1957&#45;&gt;INF&#45;1958</title>
322
+ <path fill="none" stroke="red" d="M1162.51,-258.001C1158.09,-246.388 1152.14,-230.765 1147.09,-217.526"/>
323
+ <polygon fill="red" stroke="red" points="1150.29,-216.072 1143.45,-207.973 1143.74,-218.564 1150.29,-216.072"/>
324
+ <text text-anchor="middle" x="1173.26" y="-228.8" font-family="Times,serif" font-size="14.00">blocks</text>
325
+ </g>
326
+ <!-- INF&#45;1955&#45;&gt;INF&#45;1967 -->
327
+ <g id="edge28" class="edge"><title>INF&#45;1955&#45;&gt;INF&#45;1967</title>
328
+ <path fill="none" stroke="red" d="M484.349,-344.06C488.581,-334.549 494.102,-322.514 499.437,-312 501.028,-308.864 502.753,-305.602 504.497,-302.386"/>
329
+ <polygon fill="red" stroke="red" points="507.585,-304.033 509.365,-293.588 501.461,-300.643 507.585,-304.033"/>
330
+ <text text-anchor="middle" x="518.264" y="-314.8" font-family="Times,serif" font-size="14.00">blocks</text>
331
+ </g>
332
+ <!-- INF&#45;324&#45;&gt;INF&#45;1957 -->
333
+ <g id="edge29" class="edge"><title>INF&#45;324&#45;&gt;INF&#45;1957</title>
334
+ <path fill="none" stroke="red" d="M1165.8,-344.001C1166.34,-332.691 1167.06,-317.576 1167.68,-304.566"/>
335
+ <polygon fill="red" stroke="red" points="1171.19,-304.417 1168.17,-294.262 1164.19,-304.084 1171.19,-304.417"/>
336
+ <text text-anchor="middle" x="1186.26" y="-314.8" font-family="Times,serif" font-size="14.00">blocks</text>
337
+ </g>
338
+ </g>
339
+ </svg>