jira_dependency_visualizer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>