reviewer 0.1.1 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.alexignore +1 -0
- data/.flayignore +1 -0
- data/.github/workflows/main.yml +14 -4
- data/.gitignore +5 -0
- data/.inch.yml +4 -0
- data/.reviewer.example.yml +63 -0
- data/.reviewer.future.yml +221 -0
- data/.reviewer.yml +140 -0
- data/.reviewer_stdout +0 -0
- data/.rubocop.yml +20 -0
- data/CHANGELOG.md +38 -3
- data/Gemfile +2 -4
- data/Gemfile.lock +103 -20
- data/LICENSE.txt +4 -20
- data/README.md +23 -29
- data/Rakefile +5 -5
- data/bin/console +4 -4
- data/exe/fmt +7 -0
- data/exe/rvw +7 -0
- data/lib/reviewer/arguments/files.rb +94 -0
- data/lib/reviewer/arguments/keywords.rb +133 -0
- data/lib/reviewer/arguments/tags.rb +71 -0
- data/lib/reviewer/arguments.rb +54 -10
- data/lib/reviewer/batch.rb +91 -0
- data/lib/reviewer/command/string/env.rb +44 -0
- data/lib/reviewer/command/string/flags.rb +51 -0
- data/lib/reviewer/command/string.rb +66 -0
- data/lib/reviewer/command.rb +75 -0
- data/lib/reviewer/configuration.rb +32 -7
- data/lib/reviewer/conversions.rb +16 -0
- data/lib/reviewer/guidance.rb +77 -0
- data/lib/reviewer/history.rb +69 -0
- data/lib/reviewer/keywords/git/staged.rb +64 -0
- data/lib/reviewer/keywords/git.rb +14 -0
- data/lib/reviewer/keywords.rb +9 -0
- data/lib/reviewer/loader.rb +36 -9
- data/lib/reviewer/output/printer.rb +44 -0
- data/lib/reviewer/output/scrubber.rb +48 -0
- data/lib/reviewer/output/token.rb +85 -0
- data/lib/reviewer/output.rb +122 -0
- data/lib/reviewer/runner/strategies/captured.rb +157 -0
- data/lib/reviewer/runner/strategies/passthrough.rb +63 -0
- data/lib/reviewer/runner.rb +131 -0
- data/lib/reviewer/shell/result.rb +84 -0
- data/lib/reviewer/shell/timer.rb +72 -0
- data/lib/reviewer/shell.rb +54 -0
- data/lib/reviewer/tool/settings.rb +38 -19
- data/lib/reviewer/tool.rb +137 -23
- data/lib/reviewer/tools.rb +87 -8
- data/lib/reviewer/version.rb +1 -1
- data/lib/reviewer.rb +107 -28
- data/reviewer.gemspec +34 -19
- data/structure.svg +1 -0
- metadata +244 -12
- data/bin/review +0 -5
- data/lib/reviewer/tool/command.rb +0 -78
- data/lib/reviewer/tool/env.rb +0 -39
- data/lib/reviewer/tool/flags.rb +0 -39
- data/lib/reviewer/tool/verbosity.rb +0 -39
data/lib/reviewer/tools.rb
CHANGED
@@ -1,18 +1,97 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Provides a collection of the configured tools
|
4
3
|
module Reviewer
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
# Provides convenient access to subsets of configured tools based on provided arguments,
|
5
|
+
# configured tools, their enabled/disabled status, and more.
|
6
|
+
class Tools
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
# Provides an instance to work with for knowing which tools to run in a given context.
|
10
|
+
# @param tags: nil [Array] the tags to use to filter tools for a run
|
11
|
+
# @param tool_names: nil [type] the explicitly provided tool names to filter tools for a run
|
12
|
+
#
|
13
|
+
# @return [Reviewer::Tools] collection of tools based on the current run context
|
14
|
+
def initialize(tags: nil, tool_names: nil)
|
15
|
+
@tags = tags
|
16
|
+
@tool_names = tool_names
|
17
|
+
end
|
18
|
+
|
19
|
+
# The current state of all available configured tools regardless of whether they are disabled
|
20
|
+
#
|
21
|
+
# @return [Hash] hash representing all of the configured tools
|
22
|
+
def to_h
|
23
|
+
configured
|
24
|
+
end
|
25
|
+
alias inspect to_h
|
26
|
+
|
27
|
+
# Provides a collection of all configured tools instantiated as Tool instances
|
28
|
+
#
|
29
|
+
# @return [Array<Tool>] the full collection of all Tool instances
|
30
|
+
def all
|
31
|
+
configured.keys.map { |tool_name| Tool.new(tool_name) }
|
32
|
+
end
|
33
|
+
alias to_a all
|
34
|
+
|
35
|
+
# Provides a collection of all enabled tools instantiated as Tool instances
|
36
|
+
#
|
37
|
+
# @return [Array<Tool>] the full collection of all enabled Tool instances
|
38
|
+
def enabled
|
39
|
+
@enabled ||= all.keep_if(&:enabled?)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Provides a collection of all explicitly-specified-via-command-line tools as Tool instances
|
43
|
+
#
|
44
|
+
# @return [Array<Tool>] the full collection of explicitly-specified tools for a run
|
45
|
+
def specified
|
46
|
+
all.keep_if { |tool| named?(tool) }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Provides a collection of all tagged-via-command-line tools as Tool instances
|
50
|
+
#
|
51
|
+
# @return [Array<Tool>] the full collection of tagged-via-command-line tools for a run
|
52
|
+
def tagged
|
53
|
+
enabled.keep_if { |tool| tagged?(tool) }
|
54
|
+
end
|
55
|
+
|
56
|
+
# Uses the full context of a run to provide the filtered subset of tools to use. It takes into
|
57
|
+
# consideration: tagged tools, explicitly-specified tools, configuration (enabled/disabled), and
|
58
|
+
# any other relevant details that should influence whether a specific tool should be run as part
|
59
|
+
# of the current batch being executed.
|
60
|
+
#
|
61
|
+
# @return [Array<Tool>] the full collection of should-be-used-for-this-run tools
|
62
|
+
def current
|
63
|
+
subset? ? (specified + tagged).uniq : enabled
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Determines if the current run should include a subset of a tools or the full suite of enabled
|
69
|
+
# tools by determining if any tool names or tags were provided that would reduce the full set to
|
70
|
+
# only a subset of relevant tools.
|
71
|
+
#
|
72
|
+
# @return [Boolean] true if any tool names or tags are provided via the command line
|
73
|
+
def subset?
|
74
|
+
tool_names.any? || tags.any?
|
75
|
+
end
|
76
|
+
|
77
|
+
def configured
|
78
|
+
@configured ||= Loader.configuration
|
79
|
+
end
|
80
|
+
|
81
|
+
def tags
|
82
|
+
Array(@tags || Reviewer.arguments.tags)
|
83
|
+
end
|
84
|
+
|
85
|
+
def tool_names
|
86
|
+
Array(@tool_names || Reviewer.arguments.keywords.for_tool_names)
|
8
87
|
end
|
9
88
|
|
10
|
-
def
|
11
|
-
|
89
|
+
def tagged?(tool)
|
90
|
+
tool.enabled? && (tags & tool.tags).any?
|
12
91
|
end
|
13
92
|
|
14
|
-
def
|
15
|
-
|
93
|
+
def named?(tool)
|
94
|
+
tool_names.map(&:to_s).include?(tool.key.to_s)
|
16
95
|
end
|
17
96
|
end
|
18
97
|
end
|
data/lib/reviewer/version.rb
CHANGED
data/lib/reviewer.rb
CHANGED
@@ -1,42 +1,121 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
require_relative "reviewer/tools"
|
8
|
-
require_relative "reviewer/version"
|
3
|
+
require 'benchmark'
|
4
|
+
require 'forwardable'
|
5
|
+
# require 'logger'
|
6
|
+
require 'rainbow'
|
9
7
|
|
8
|
+
require_relative 'reviewer/conversions'
|
9
|
+
|
10
|
+
require_relative 'reviewer/arguments'
|
11
|
+
require_relative 'reviewer/batch'
|
12
|
+
require_relative 'reviewer/command'
|
13
|
+
require_relative 'reviewer/configuration'
|
14
|
+
require_relative 'reviewer/guidance'
|
15
|
+
require_relative 'reviewer/history'
|
16
|
+
require_relative 'reviewer/keywords'
|
17
|
+
require_relative 'reviewer/loader'
|
18
|
+
require_relative 'reviewer/output'
|
19
|
+
require_relative 'reviewer/runner'
|
20
|
+
require_relative 'reviewer/shell'
|
21
|
+
require_relative 'reviewer/tool'
|
22
|
+
require_relative 'reviewer/tools'
|
23
|
+
require_relative 'reviewer/version'
|
24
|
+
|
25
|
+
# Primary interface for the reviewer tools
|
10
26
|
module Reviewer
|
11
27
|
class Error < StandardError; end
|
12
28
|
|
13
29
|
class << self
|
14
|
-
|
15
|
-
|
30
|
+
# Resets the loaded tools
|
31
|
+
def reset!
|
32
|
+
@tools = nil
|
33
|
+
end
|
16
34
|
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
35
|
+
# Runs the `review` command for the specified tools/files. Reviewer expects all configured
|
36
|
+
# commands that are not disabled to have an entry for the `review` command.
|
37
|
+
# @param clear_screen [boolean] clears the screen to reduce noise when true
|
38
|
+
#
|
39
|
+
# @return [void] Prints output to the console
|
40
|
+
def review(clear_screen: false)
|
41
|
+
perform(:review, clear_screen: clear_screen)
|
42
|
+
end
|
23
43
|
|
24
|
-
|
25
|
-
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
44
|
+
# Runs the `format` command for the specified tools/files for which it is configured.
|
45
|
+
# @param clear_screen [boolean] clears the screen to reduce noise when true
|
46
|
+
#
|
47
|
+
# @return [void] Prints output to the console
|
48
|
+
def format(clear_screen: false)
|
49
|
+
perform(:format, clear_screen: clear_screen)
|
50
|
+
end
|
30
51
|
|
31
|
-
|
32
|
-
|
33
|
-
|
52
|
+
# The collection of arguments that were passed via the command line.
|
53
|
+
#
|
54
|
+
# @return [Reviewer::Arguments] exposes tags, files, and keywords from arguments
|
55
|
+
def arguments
|
56
|
+
@arguments ||= Arguments.new
|
57
|
+
end
|
34
58
|
|
35
|
-
|
36
|
-
|
37
|
-
|
59
|
+
# An interface for the collection of configured tools for accessing subsets of tools
|
60
|
+
# based on enabled/disabled, tags, keywords, etc.
|
61
|
+
#
|
62
|
+
# @return [Reviewer::Tools] exposes the set of tools to be run in a given context
|
63
|
+
def tools
|
64
|
+
@tools ||= Tools.new
|
65
|
+
end
|
66
|
+
|
67
|
+
# The primary output method for Reviewer to consistently display success/failure details for a
|
68
|
+
# unique run of each tool and the collective summary when relevant.
|
69
|
+
#
|
70
|
+
# @return [Reviewer::Output] prints formatted output to the console.
|
71
|
+
def output
|
72
|
+
@output ||= Output.new
|
73
|
+
end
|
74
|
+
|
75
|
+
# A file store for sharing information across runs
|
76
|
+
#
|
77
|
+
# @return [Reviewer::History] a YAML::Store (or Pstore) containing data on tools
|
78
|
+
def history
|
79
|
+
@history ||= History.new
|
80
|
+
end
|
81
|
+
|
82
|
+
# Exposes the configuration options for Reviewer.
|
83
|
+
#
|
84
|
+
# @return [Reviewer::Configuration] configuration settings instance
|
85
|
+
def configuration
|
86
|
+
@configuration ||= Configuration.new
|
87
|
+
end
|
88
|
+
|
89
|
+
# A block approach to configuring Reviewer.
|
90
|
+
#
|
91
|
+
# @example Set configuration file path
|
92
|
+
# Reviewer.configure do |config|
|
93
|
+
# config.file = '~/configuration.yml'
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# @return [Reviewer::Configuration] Reviewer configuration settings
|
97
|
+
def configure
|
98
|
+
yield(configuration)
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
# Provides a consistent approach to running and benchmarking commmands and preventing further
|
104
|
+
# execution of later tools if a command fails.
|
105
|
+
# @param command_type [Symbol] the specific command to run for each tool
|
106
|
+
# @param clear_screen [Boolean] if true, clears the screen before a run
|
107
|
+
#
|
108
|
+
# @example Run the `review` command for each relevant tool
|
109
|
+
# perform(:review)
|
110
|
+
#
|
111
|
+
# @return [Hash] the exit status (in integer format) for each command run
|
112
|
+
def perform(command_type, clear_screen: false)
|
113
|
+
output.clear if clear_screen
|
114
|
+
|
115
|
+
results = Batch.new(command_type, tools.current).run
|
38
116
|
|
39
|
-
|
40
|
-
|
117
|
+
# Return the largest exit status
|
118
|
+
exit results.values.max
|
119
|
+
end
|
41
120
|
end
|
42
121
|
end
|
data/reviewer.gemspec
CHANGED
@@ -1,36 +1,51 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative 'lib/reviewer/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
6
|
+
spec.name = 'reviewer'
|
7
7
|
spec.version = Reviewer::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
8
|
+
spec.authors = ['Garrett Dimon']
|
9
|
+
spec.email = ['email@garrettdimon.com']
|
10
10
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new(
|
11
|
+
spec.summary = 'Provides a unified approach to managing automated code quality tools.'
|
12
|
+
spec.description = 'Provides a unified approach to managing automated code quality tools.'
|
13
|
+
spec.homepage = 'https://github.com/garrettdimon/reviewer'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.9')
|
16
16
|
|
17
|
-
spec.metadata[
|
18
|
-
spec.metadata[
|
19
|
-
spec.metadata[
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/garrettdimon/reviewer/issues'
|
19
|
+
spec.metadata['changelog_uri'] = 'https://github.com/garrettdimon/reviewer/CHANGELOG.md'
|
20
|
+
spec.metadata['documentation_uri'] = 'https://www.rubydoc.info/gems/reviewer'
|
21
|
+
spec.metadata['source_code_uri'] = 'https://github.com/garrettdimon/reviewer'
|
22
|
+
spec.metadata['wiki_uri'] = 'https://github.com/garrettdimon/reviewer/wiki'
|
23
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
20
24
|
|
21
25
|
# Specify which files should be added to the gem when it is released.
|
22
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
27
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
28
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
25
29
|
end
|
26
|
-
spec.bindir =
|
30
|
+
spec.bindir = 'exe'
|
27
31
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
28
|
-
spec.require_paths = [
|
32
|
+
spec.require_paths = ['lib']
|
29
33
|
|
30
|
-
|
31
|
-
spec.add_dependency
|
32
|
-
spec.add_dependency "slop"
|
34
|
+
spec.add_dependency 'rainbow'
|
35
|
+
spec.add_dependency 'slop'
|
33
36
|
|
34
|
-
|
35
|
-
|
37
|
+
spec.add_development_dependency 'bundler-audit'
|
38
|
+
spec.add_development_dependency 'codecov'
|
39
|
+
spec.add_development_dependency 'flay'
|
40
|
+
spec.add_development_dependency 'flog'
|
41
|
+
spec.add_development_dependency 'inch'
|
42
|
+
spec.add_development_dependency 'minitest'
|
43
|
+
spec.add_development_dependency 'minitest-heat'
|
44
|
+
spec.add_development_dependency 'psych'
|
45
|
+
spec.add_development_dependency 'reek'
|
46
|
+
spec.add_development_dependency 'rubocop'
|
47
|
+
spec.add_development_dependency 'rubocop-minitest'
|
48
|
+
spec.add_development_dependency 'rubocop-rake'
|
49
|
+
spec.add_development_dependency 'simplecov'
|
50
|
+
spec.add_development_dependency 'yard'
|
36
51
|
end
|
data/structure.svg
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<svg width="1000" height="1000" style="background:white;font-family:sans-serif;overflow:visible" xmlns="http://www.w3.org/2000/svg"><defs><filter id="glow" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="4" result="coloredBlur"></feGaussianBlur><feMerge><feMergeNode in="coloredBlur"></feMergeNode><feMergeNode in="SourceGraphic"></feMergeNode></feMerge></filter></defs><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(458.1684758396736, 402.8013409019584)"><circle r="352.40190201003946" style="transition:all 0.5s ease-out" stroke="#290819" opacity="0.2" stroke-width="1" fill="none"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(520.8364435594557, 806.4990877668961)"><circle r="36.11178860447648" style="transition:all 0.5s ease-out" stroke="#290819" opacity="0.2" stroke-width="1" fill="none"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(409.6517236116371, 402.8013409019584)"><circle r="294.1473077312859" style="transition:all 0.5s ease-out" stroke="#290819" opacity="0.2" stroke-width="1" fill="none"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(757.1847045963179, 402.8013409019584)"><circle style="transition:all 0.5s ease-out" r="43.64783120267789" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#6473F2;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(687.4299657134559, 856.9423846447222)"><circle style="transition:all 0.5s ease-out" r="51.31612086796417" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(788.9846757350268, 859.3421087760426)"><circle style="transition:all 0.5s ease-out" r="46.2472197118418" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(726.4250919182904, 947.0721172937218)"><circle style="transition:all 0.5s ease-out" r="42.86782312801615" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(726.687090398783, 755.9238323654778)"><circle style="transition:all 0.5s ease-out" r="35.01102176297566" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(656.2776843121794, 774.053081197875)"><circle style="transition:all 0.5s ease-out" r="34.05582985803832" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#6473F2;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(646.3075304917123, 935.5086582680074)"><circle style="transition:all 0.5s ease-out" r="33.36112099562045" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#6473F2;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(792.4478568898579, 778.7047877445898)"><circle style="transition:all 0.5s ease-out" r="30.75334019375212" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(795.2808076405827, 932.7721040738809)"><circle style="transition:all 0.5s ease-out" r="23.450700366199015" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(628.2012046638729, 818.8498773291199)"><circle style="transition:all 0.5s ease-out" r="15.087376074028514" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(625.1052165805941, 879.58232371161)"><circle style="transition:all 0.5s ease-out" r="10.993857902246123" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(759.9605608023857, 807.5923921321375)"><circle style="transition:all 0.5s ease-out" r="9.032375950599938" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(740.4589615675088, 893.1073074759857)"><circle style="transition:all 0.5s ease-out" r="8.891894979240078" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(697.4389756167642, 792.4331053326879)"><circle style="transition:all 0.5s ease-out" r="7.7087773473446" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#FFC312;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(739.3959953779754, 800.9150363761469)"><circle style="transition:all 0.5s ease-out" r="7.6760435377025455" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(754.6373603648877, 899.7098713097646)"><circle style="transition:all 0.5s ease-out" r="2.7484644755615304" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(688.9313125250869, 914.8390531135157)"><circle style="transition:all 0.5s ease-out" r="2.5586811792341817" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(506.1084751770936, 806.4990877668961)"><circle style="transition:all 0.5s ease-out" r="16.95752838087938" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(540.0071178609526, 806.4990877668961)"><circle style="transition:all 0.5s ease-out" r="12.514822461744519" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(355.4184691733666, 395.8977440745981)"><circle style="transition:all 0.5s ease-out" r="48.297958480594644" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(453.66003516638904, 395.8977440745981)"><circle style="transition:all 0.5s ease-out" r="45.517315671192776" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(407.83945742807794, 501.6014766854548)"><circle r="65.2640503586534" style="transition:all 0.5s ease-out" stroke="#290819" opacity="0.2" stroke-width="1" fill="none"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(408.44899912286195, 266.8449117959501)"><circle r="86.7994775020254" style="transition:all 0.5s ease-out" stroke="#290819" opacity="0.2" stroke-width="1" fill="none"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(277.6542041828907, 480.50667705487933)"><circle r="62.19290440091251" style="transition:all 0.5s ease-out" stroke="#290819" opacity="0.2" stroke-width="1" fill="none"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(578.9817228671643, 482.6836693665573)"><circle r="102.49432161596253" style="transition:all 0.5s ease-out" stroke="#290819" opacity="0.2" stroke-width="1" fill="none"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(231.7281199383259, 318.8649338109235)"><circle r="92.99244862172178" style="transition:all 0.5s ease-out" stroke="#290819" opacity="0.2" stroke-width="1" fill="none"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(523.1975630378445, 335.21636724206417)"><circle style="transition:all 0.5s ease-out" r="42.347764114422745" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(176.26520220161186, 445.3500189745872)"><circle style="transition:all 0.5s ease-out" r="40.692128091001564" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(605.0441527585806, 342.75082556501854)"><circle style="transition:all 0.5s ease-out" r="35.41859767673708" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(327.59590900349434, 569.4790692623358)"><circle style="transition:all 0.5s ease-out" r="35.41148765003155" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(534.3474887230652, 253.8625225793911)"><circle style="transition:all 0.5s ease-out" r="35.34030870841474" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(476.4643386600166, 578.911911443936)"><circle style="transition:all 0.5s ease-out" r="33.68411134954049" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(299.4858839094448, 207.73782607508076)"><circle style="transition:all 0.5s ease-out" r="32.73635414382169" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(390.0098532010105, 598.7827521061267)"><circle style="transition:all 0.5s ease-out" r="29.11297292304826" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(440.3851018289799, 634.7060029474101)"><circle style="transition:all 0.5s ease-out" r="28.332745267196174" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(598.6034010548337, 275.2555582441296)"><circle style="transition:all 0.5s ease-out" r="27.956986512323546" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(502.704659203589, 194.16981738111775)"><circle style="transition:all 0.5s ease-out" r="27.79439199698623" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(266.51867408166913, 567.6833977935446)"><circle style="transition:all 0.5s ease-out" r="21.265846110817378" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(346.18721110272986, 174.45592016501854)"><circle style="transition:all 0.5s ease-out" r="20.184535485530812" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(523.0058458149439, 583.8411735366119)"><circle style="transition:all 0.5s ease-out" r="8.691407810834628" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(351.1758829983302, 609.7245028990388)"><circle style="transition:all 0.5s ease-out" r="6.806728247623728" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(383.5814103897357, 501.6014766854548)"><circle style="transition:all 0.5s ease-out" r="36.57971147907614" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(446.6323148277716, 501.6014766854548)"><circle style="transition:all 0.5s ease-out" r="22.044901117724688" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(370.84570420293034, 266.8449117959501)"><circle style="transition:all 0.5s ease-out" r="44.76989074085872" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(455.4320357843382, 266.8449117959501)"><circle style="transition:all 0.5s ease-out" r="35.39014899931409" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(265.3052220935813, 480.50667705487933)"><circle style="transition:all 0.5s ease-out" r="45.41763047036804" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(325.2849805738762, 480.50667705487933)"><circle style="transition:all 0.5s ease-out" r="10.135836168691887" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(544.5152135162864, 471.920566006636)"><circle r="61.960071361511915" style="transition:all 0.5s ease-out" stroke="#290819" opacity="0.2" stroke-width="1" fill="none"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(643.5300677882587, 471.920566006636)"><circle style="transition:all 0.5s ease-out" r="32.62849106922531" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(618.710163320952, 535.9504578797049)"><circle style="transition:all 0.5s ease-out" r="31.617298105357957" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(191.4503126965002, 309.1431465377067)"><circle style="transition:all 0.5s ease-out" r="47.13169160962506" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(281.17799339890166, 309.1431465377067)"><circle style="transition:all 0.5s ease-out" r="38.16969725154132" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(244.21679860063716, 373.9896454048579)"><circle style="transition:all 0.5s ease-out" r="32.04447135758986" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(519.6457545955952, 464.8290172745834)"><circle style="transition:all 0.5s ease-out" r="31.672997427945933" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(578.5313449242576, 464.8290172745834)"><circle style="transition:all 0.5s ease-out" r="22.78630105948141" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(556.9214342696687, 507.08309517374425)"><circle style="transition:all 0.5s ease-out" r="20.246814360728305" stroke-width="0" stroke="#374151"></circle></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(757.1847045963179, 402.8013409019584)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">reviewer.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">reviewer.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">reviewer.rb</text></g><g style="fill:#6473F2;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(687.4299657134559, 856.9423846447222)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">CODE_OF_CONDU...</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">CODE_OF_CONDU...</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">CODE_OF_CONDU...</text></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(788.9846757350268, 859.3421087760426)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">.reviewer.exa...</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">.reviewer.exa...</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">.reviewer.exa...</text></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(726.4250919182904, 947.0721172937218)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">.reviewer.yml</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">.reviewer.yml</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">.reviewer.yml</text></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(726.687090398783, 755.9238323654778)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">Gemfile.lock</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">Gemfile.lock</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">Gemfile.lock</text></g><g style="fill:#CED6E0;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(656.2776843121794, 774.053081197875)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">reviewer.gemspec</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">reviewer.gemspec</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">reviewer.gemspec</text></g><g style="fill:#6473F2;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(646.3075304917123, 935.5086582680074)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">CHANGELOG.md</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">CHANGELOG.md</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">CHANGELOG.md</text></g><g style="fill:#6473F2;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(792.4478568898579, 778.7047877445898)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">README.md</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">README.md</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">README.md</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(355.4184691733666, 395.8977440745981)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">tool.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">tool.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">tool.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(453.66003516638904, 395.8977440745981)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">tool/settings.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">tool/settings.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">tool/settings.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(523.1975630378445, 335.21636724206417)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">command.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">command.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">command.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(176.26520220161186, 445.3500189745872)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">tools.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">tools.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">tools.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(605.0441527585806, 342.75082556501854)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">guidance.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">guidance.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">guidance.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(327.59590900349434, 569.4790692623358)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">history.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">history.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">history.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(534.3474887230652, 253.8625225793911)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">arguments.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">arguments.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">arguments.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(476.4643386600166, 578.911911443936)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">output.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">output.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">output.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(299.4858839094448, 207.73782607508076)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">runner.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">runner.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">runner.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(383.5814103897357, 501.6014766854548)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">result.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">result.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">result.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(370.84570420293034, 266.8449117959501)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">quiet.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">quiet.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">quiet.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(455.4320357843382, 266.8449117959501)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">verbose.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">verbose.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">verbose.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(265.3052220935813, 480.50667705487933)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">git/staged.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">git/staged.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">git/staged.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(643.5300677882587, 471.920566006636)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">verbosity.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">verbosity.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">verbosity.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(618.710163320952, 535.9504578797049)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">string.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">string.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">string.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(191.4503126965002, 309.1431465377067)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">keywords.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">keywords.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">keywords.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(281.17799339890166, 309.1431465377067)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">files.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">files.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">files.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(244.21679860063716, 373.9896454048579)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">tags.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">tags.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">tags.rb</text></g><g style="fill:#eb4d4b;transition:transform 0s ease-out, fill 0.1s ease-out" transform="translate(519.6457545955952, 464.8290172745834)"><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;transition:all 0.5s ease-out" fill="#4B5563" text-anchor="middle" dominant-baseline="middle" stroke="white" stroke-width="3" stroke-linejoin="round">verbosity.rb</text><text style="pointer-events:none;opacity:1;font-size:14px;font-weight:500;transition:all 0.5s ease-out" text-anchor="middle" dominant-baseline="middle">verbosity.rb</text><text style="pointer-events:none;opacity:0.9;font-size:14px;font-weight:500;mix-blend-mode:color-burn;transition:all 0.5s ease-out" fill="#110101" text-anchor="middle" dominant-baseline="middle">verbosity.rb</text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(458.1684758396736, 402.8013409019584)"><path fill="none" d="M 0 349.40190201003946 A 349.40190201003946 349.40190201003946 0 0 1 0 -349.40190201003946 A 349.40190201003946 349.40190201003946 0 0 1 0 349.40190201003946" id="CircleText--1" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--1" startOffset="50%">lib</textPath></text><path fill="none" d="M 0 349.40190201003946 A 349.40190201003946 349.40190201003946 0 0 1 0 -349.40190201003946 A 349.40190201003946 349.40190201003946 0 0 1 0 349.40190201003946" id="CircleText--2" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--2" startOffset="50%">lib</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(520.8364435594557, 806.4990877668961)"><path fill="none" d="M 0 33.11178860447648 A 33.11178860447648 33.11178860447648 0 0 1 0 -33.11178860447648 A 33.11178860447648 33.11178860447648 0 0 1 0 33.11178860447648" id="CircleText--3" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--3" startOffset="50%">.github/workf...</textPath></text><path fill="none" d="M 0 33.11178860447648 A 33.11178860447648 33.11178860447648 0 0 1 0 -33.11178860447648 A 33.11178860447648 33.11178860447648 0 0 1 0 33.11178860447648" id="CircleText--4" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--4" startOffset="50%">.github/workf...</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(409.6517236116371, 402.8013409019584)"><path fill="none" d="M 0 291.1473077312859 A 291.1473077312859 291.1473077312859 0 0 1 0 -291.1473077312859 A 291.1473077312859 291.1473077312859 0 0 1 0 291.1473077312859" id="CircleText--5" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--5" startOffset="50%">reviewer</textPath></text><path fill="none" d="M 0 291.1473077312859 A 291.1473077312859 291.1473077312859 0 0 1 0 -291.1473077312859 A 291.1473077312859 291.1473077312859 0 0 1 0 291.1473077312859" id="CircleText--6" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--6" startOffset="50%">reviewer</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(407.83945742807794, 501.6014766854548)"><path fill="none" d="M 0 62.26405035865341 A 62.26405035865341 62.26405035865341 0 0 1 0 -62.26405035865341 A 62.26405035865341 62.26405035865341 0 0 1 0 62.26405035865341" id="CircleText--7" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--7" startOffset="50%">shell</textPath></text><path fill="none" d="M 0 62.26405035865341 A 62.26405035865341 62.26405035865341 0 0 1 0 -62.26405035865341 A 62.26405035865341 62.26405035865341 0 0 1 0 62.26405035865341" id="CircleText--8" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--8" startOffset="50%">shell</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(408.44899912286195, 266.8449117959501)"><path fill="none" d="M 0 83.7994775020254 A 83.7994775020254 83.7994775020254 0 0 1 0 -83.7994775020254 A 83.7994775020254 83.7994775020254 0 0 1 0 83.7994775020254" id="CircleText--9" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--9" startOffset="50%">runner/strate...</textPath></text><path fill="none" d="M 0 83.7994775020254 A 83.7994775020254 83.7994775020254 0 0 1 0 -83.7994775020254 A 83.7994775020254 83.7994775020254 0 0 1 0 83.7994775020254" id="CircleText--10" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--10" startOffset="50%">runner/strate...</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(277.6542041828907, 480.50667705487933)"><path fill="none" d="M 0 59.19290440091251 A 59.19290440091251 59.19290440091251 0 0 1 0 -59.19290440091251 A 59.19290440091251 59.19290440091251 0 0 1 0 59.19290440091251" id="CircleText--11" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--11" startOffset="50%">keywords</textPath></text><path fill="none" d="M 0 59.19290440091251 A 59.19290440091251 59.19290440091251 0 0 1 0 -59.19290440091251 A 59.19290440091251 59.19290440091251 0 0 1 0 59.19290440091251" id="CircleText--12" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--12" startOffset="50%">keywords</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(578.9817228671643, 482.6836693665573)"><path fill="none" d="M 0 99.49432161596253 A 99.49432161596253 99.49432161596253 0 0 1 0 -99.49432161596253 A 99.49432161596253 99.49432161596253 0 0 1 0 99.49432161596253" id="CircleText--13" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--13" startOffset="50%">command</textPath></text><path fill="none" d="M 0 99.49432161596253 A 99.49432161596253 99.49432161596253 0 0 1 0 -99.49432161596253 A 99.49432161596253 99.49432161596253 0 0 1 0 99.49432161596253" id="CircleText--14" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--14" startOffset="50%">command</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(231.7281199383259, 318.8649338109235)"><path fill="none" d="M 0 89.99244862172178 A 89.99244862172178 89.99244862172178 0 0 1 0 -89.99244862172178 A 89.99244862172178 89.99244862172178 0 0 1 0 89.99244862172178" id="CircleText--15" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--15" startOffset="50%">arguments</textPath></text><path fill="none" d="M 0 89.99244862172178 A 89.99244862172178 89.99244862172178 0 0 1 0 -89.99244862172178 A 89.99244862172178 89.99244862172178 0 0 1 0 89.99244862172178" id="CircleText--16" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--16" startOffset="50%">arguments</textPath></text></g><g style="pointer-events:none;transition:all 0.5s ease-out" transform="translate(544.5152135162864, 471.920566006636)"><path fill="none" d="M 0 58.960071361511915 A 58.960071361511915 58.960071361511915 0 0 1 0 -58.960071361511915 A 58.960071361511915 58.960071361511915 0 0 1 0 58.960071361511915" id="CircleText--17" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151" stroke="white" stroke-width="6"><textPath href="#CircleText--17" startOffset="50%">string</textPath></text><path fill="none" d="M 0 58.960071361511915 A 58.960071361511915 58.960071361511915 0 0 1 0 -58.960071361511915 A 58.960071361511915 58.960071361511915 0 0 1 0 58.960071361511915" id="CircleText--18" transform="rotate(0)" style="pointer-events:none"></path><text text-anchor="middle" style="font-size:14px;transition:all 0.5s ease-out" fill="#374151"><textPath href="#CircleText--18" startOffset="50%">string</textPath></text></g><g transform="translate(920, 935)"><g transform="translate(0, 0)"><circle r="5" fill="#6473F2"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.md</text></g><g transform="translate(0, 15)"><circle r="5" fill="#eb4d4b"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.rb</text></g><g transform="translate(0, 30)"><circle r="5" fill="#FFC312"></circle><text x="10" style="font-size:14px;font-weight:300" dominant-baseline="middle">.svg</text></g><div class="w-20 whitespace-nowrap text-sm text-gray-500 font-light italic">each dot sized by file size</div></g></svg>
|