raindeer 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8783b509655bf58e51f0e7afc0aa320832d8aee1b298d50771d4121c418b28d1
4
- data.tar.gz: 1eaf600341059527fc7dc013df6cc24a3bc1ba7d606a34b5544b73630e10b0ea
3
+ metadata.gz: 8d79ce92ce79c7e46122adb4e9ba39968d9bf220cca424deba580f3a74ac26c6
4
+ data.tar.gz: 6970876678afd4bf8395135d52a9c1ff20858170282e3c97c540f1458338d4ea
5
5
  SHA512:
6
- metadata.gz: 6328d1ed634f9e501e8abd946deccfe13e39ee68b863273bc5c6aa8b4822e449b9462bf3027a5147382802f0af2367995af807ac2144a18e66247f0c2603ceb0
7
- data.tar.gz: 2268752ea3dbb8e0eb8190f007fa8263ac37e0eff6f4d1e737fbf04fc9760788e15af59e426d46e4bdd2105075a3795396f95a5d837136f6138a61c4263dc8db
6
+ metadata.gz: 947dd01220faa492c9abf83e78aae9ec07d5e6c5794724aa24dda43be39e8fe82822734c068612f1176246c64b3e5f34e205d5b2fbb7d5517be598d3e927b1f2
7
+ data.tar.gz: bb4fff4358eae10a7b3ee1085ad9bd35bd7ac795c639dcb48b8e7c7deea3055e592a1f196931fc98ad64161631b5107bd1ca75fe29086d415891e7cfc23d84d3
data/lib/boot.rb CHANGED
@@ -1,13 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'low_dependency'
4
3
  require 'low_event'
5
- require 'low_loop'
6
4
  require 'low_node'
7
5
  require 'low_type'
8
- require 'lowload'
6
+ require 'providers'
9
7
 
10
- require_relative 'matrix/matrix'
11
8
  require_relative 'support/config_loader'
12
9
 
13
10
  env = {
@@ -20,16 +17,20 @@ env = {
20
17
 
21
18
  config = Rain::ConfigLoader.load('./config/config.yaml', env)
22
19
 
23
- LowDependency.provide('rain.router') do
20
+ Providers.define('rain.router') do
21
+ require_relative 'router/router'
24
22
  Rain::Router.new
25
23
  end
26
24
 
27
- LowDependency.provide('rain.matrix') do
28
- Rain::Matrix.new(event_pool: Low::Providers['low.event.pool'])
25
+ Providers.define('rain.matrix') do
26
+ require_relative 'matrix/matrix'
27
+ Rain::Matrix.new(event_pool: Providers['low.event.pool'])
29
28
  end
30
29
 
31
- LowDependency.provide('low.loop') do
32
- LowLoop.new(config:, router: Low::Providers['rain.router'], renderer: Low::Providers['rain.matrix'])
30
+ Providers.define('low.loop') do
31
+ require 'low_loop'
32
+ LowLoop.new(config:, router: Providers['rain.router'], renderer: Providers['rain.matrix'])
33
33
  end
34
34
 
35
- LowLoad.dirload(File.expand_path('../system', __FILE__))
35
+ require 'lowload'
36
+ LowLoad.dirload(File.expand_path('system', __dir__))
data/lib/matrix/cursor.rb CHANGED
@@ -10,19 +10,38 @@ module Rain
10
10
  @last_update = now
11
11
  end
12
12
 
13
+ # Unit tests use "duration" to skip forward in time, while feature tests and the real world use old fashioned linear time.
13
14
  def increment(delays:, inputs:, duration: nil)
14
- next_index = @index + 1
15
- duration = now - @last_update if duration.nil?
15
+ next_index = next_index(loop_count: inputs.count)
16
+
17
+ return unless delays[next_index] && (duration || now - @last_update) >= delays[next_index]
18
+
19
+ @index = next_index
20
+ @last_update = now
21
+
22
+ yield index
23
+ end
16
24
 
17
- if delays[next_index] && duration >= delays[next_index]
25
+ def iterate(inputs:, loop_count:)
26
+ inputs.each do |input|
18
27
  @index += 1
19
- @index = 0 if index >= inputs.count
20
- @last_update = now
28
+ @index = 0 if index >= loop_count
21
29
 
22
- yield index
30
+ yield index, input
23
31
  end
24
32
  end
25
33
 
34
+ def increase_index(loop_count:)
35
+ @index += 1
36
+ @index = 0 if @index >= loop_count
37
+ end
38
+
39
+ def next_index(loop_count:)
40
+ next_index = @index + 1
41
+ next_index = 0 if next_index >= loop_count
42
+ next_index
43
+ end
44
+
26
45
  private
27
46
 
28
47
  def now
data/lib/matrix/matrix.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'paint'
4
3
  require 'low_event'
5
4
  require 'observers'
5
+ require 'paint'
6
6
 
7
7
  require_relative '../support/config_loader'
8
8
  require_relative 'stream'
@@ -11,77 +11,101 @@ module Rain
11
11
  class Matrix
12
12
  include Observers
13
13
 
14
- observe Low::Events::EventPool
15
-
16
- def initialize(event_pool:, config: Rain::ConfigLoader.load('./config/matrix.yaml'))
14
+ def initialize(event_pool:, config: ConfigLoader.load('./config/matrix.yaml'))
17
15
  @event_pool = event_pool
18
16
  @config = config
19
17
 
20
18
  @screen_size = nil
21
19
 
22
20
  @last_stream_index = -1
23
- @streams = {}
21
+ @streams = {} # TODO: Could be a "stream pool" like event pool (a pool hash).
24
22
  @columns = []
25
23
  end
26
24
 
25
+ def redraw(screen_size:)
26
+ @setup ||= setup
27
+
28
+ @streams.each_value do |stream|
29
+ stream.redraw(cell_count: screen_size[:row_count])
30
+ end
31
+ end
32
+
27
33
  def render(screen_size:, show_output: true)
28
34
  if screen_size != @screen_size
29
35
  @screen_size = screen_size
30
- redraw_streams
36
+ redraw(screen_size:)
31
37
  end
32
38
 
33
39
  render_streams(show_output:)
34
40
  end
35
41
 
36
- def update(stream_id:, event_tree:)
37
- upsert_stream(stream_id:, event_tree:)
42
+ # TODO: Introduce "on :new_event_tree do |event|" block construct in LowEvent for making event handlers more obvious.
43
+ # TODO: Observers should allow arbitrary params when triggering and observing.
44
+ def new_event_tree(event: Low::Events::EventTree)
45
+ stream = upsert_stream(event_tree: event)
46
+ stream.redraw(cell_count: @screen_size[:row_count])
38
47
  end
39
48
 
40
49
  private
41
50
 
42
- def redraw_streams
43
- @event_pool.event_trees.each do |stream_id, event_tree|
44
- stream = upsert_stream(stream_id:, event_tree:)
45
- stream.redraw(cell_count: @screen_size[:row_count])
46
-
47
- @columns[stream.index] = upsert_stream(stream_id:, event_tree:)
51
+ def setup
52
+ @event_pool.event_trees.each_value do |event_tree|
53
+ upsert_stream(event_tree:)
48
54
  end
55
+
56
+ observe @event_pool
57
+
58
+ true
49
59
  end
50
60
 
51
- def render_streams(show_output:)
52
- @streams.each_value { |stream| stream.render }
61
+ def upsert_stream(event_tree:)
62
+ stream = @streams[event_tree.request_id] ||= Stream.new(index: generate_index, config: @config, event_tree:)
63
+ @columns[stream.index] = stream
64
+ stream
65
+ end
66
+
67
+ def render_streams(show_output: true) # rubocop:disable Metrics/AbcSize
68
+ @streams.each_value(&:render)
69
+
70
+ return unless show_output
71
+
72
+ output = ''.dup
53
73
 
54
74
  (0...@screen_size[:row_count]).each do |row_index|
55
75
  cell_outputs = []
56
76
  cell_colors = []
57
77
 
58
- # Rendering streams can happen before redrawing streams and @columns haven't been populated yet (empty event pool).
59
- (0...@screen_size[:column_count]).each do |column_index|
78
+ # Rendering streams can happen before redrawing streams, so @columns may not be populated yet.
79
+ (0...column_count).each do |column_index|
60
80
  cell_colors << (@columns[column_index].nil? ? nil : @columns[column_index].colors[row_index])
61
81
  cell_outputs << (@columns[column_index].nil? ? nil : @columns[column_index].outputs[row_index])
62
82
  end
63
83
 
64
- output = cell_outputs.zip(cell_colors).map do |cell, color|
65
- cell ? Paint[cell, color] : Paint[' ', nil]
84
+ output << "\n" + cell_outputs.zip(cell_colors).map do |cell, color| # rubocop:disable Style/StringConcatenation
85
+ cell ? Paint[cell, color] : Paint[' ']
66
86
  end.join(' ')
67
-
68
- puts output if show_output
69
87
  end
70
- end
71
88
 
72
- def upsert_stream(stream_id:, event_tree:)
73
- @streams[stream_id] ||= Stream.new(index:, config: @config, event_tree:)
89
+ system 'clear'
90
+ print output.delete_prefix("\n").delete_suffix("\n")
74
91
  end
75
92
 
76
- def index
93
+ def generate_index
77
94
  case @config.start_col
78
95
  when :random
79
- rand(0...@screen_size[:column_count])
96
+ rand(0...column_count)
80
97
  when :latest
81
98
  @last_stream_index += 1
82
- return @last_stream_index = 0 if @last_stream_index >= @screen_size[:column_count]
99
+ return @last_stream_index = 0 if @last_stream_index >= column_count
100
+
83
101
  @last_stream_index
84
102
  end
85
103
  end
104
+
105
+ def column_count
106
+ return @screen_size[:column_count] if @screen_size[:column_count] < 10
107
+
108
+ (@screen_size[:column_count] / 2).to_i.clamp(1, nil)
109
+ end
86
110
  end
87
111
  end
data/lib/matrix/stream.rb CHANGED
@@ -1,35 +1,58 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'low_event'
4
+ require 'observers'
5
+
3
6
  require_relative 'cursor'
4
7
 
5
8
  module Rain
6
9
  class Stream
7
- attr_reader :index, :colors, :outputs
10
+ include Observers
11
+ attr_reader :index, :inputs, :outputs, :delays, :colors, :head_cursor, :tail_cursor
8
12
 
9
- ARROW = ['│', '▼']
13
+ ARROW = ['│', '▼'].freeze
10
14
 
11
15
  def initialize(index:, config:, event_tree:)
12
16
  @index = index
13
17
  @config = config
14
-
15
18
  @event_tree = event_tree
16
- @event_cursor = 0
17
- @redraw_cursor = 0
18
19
 
19
20
  @inputs = []
20
21
  @delays = []
21
22
  @colors = []
22
23
  @outputs = []
23
24
 
25
+ @event_cursor = 0
24
26
  @head_cursor = Cursor.new
25
27
  @tail_cursor = Cursor.new
28
+ @tail_cursor.index = 0
29
+
30
+ @show_cursor = Cursor.new
31
+ @hide_cursor = Cursor.new
32
+
33
+ observe event_tree
34
+ end
35
+
36
+ # TODO: Use "on :branch do |event|" syntax.
37
+ def branch(event: Low::Events::BranchEvent) # rubocop:disable Lint/UnusedMethodArgument
38
+ redraw(cell_count: @inputs.count)
26
39
  end
27
40
 
28
- # Layout cells to fit the current cell count. Called on matrix initialization, screen size changes and on new events.
41
+ # Draw event names onto the current amount of cells in a stream, using cursors. Called when there's a new event.
42
+ #
43
+ # INPUT DELAY OUTPUT
44
+ # ┌─────┬─────┬─────┐
45
+ # │ R │ 75 │ │ ◀── 2. Tail Cursor begins at index zero or a random starting index.
46
+ # │ e │ 75 │ │ A Head Cursor that wraps around will push the Tail Cursor down to be just beneath it.
47
+ # │ q │ 75 │ │ The Show Cursor will start at the Tail Cursor index.
48
+ # │ u │ 75 │ │
49
+ # │ │ 75 │ │ ◀── 1. Head Cursor begins at index zero or a random starting index.
50
+ # │ │ 75 │ │ It populates input for every character in an event name.
51
+ # │ │ 75 │ │ Then sets a "75" delay for the Show Cursor.
52
+ # └─────┴─────┴─────┘
29
53
  def redraw(cell_count:)
30
- @inputs.fill(nil, 0...cell_count)[0...cell_count]
31
- @delays.fill(@config.min_delay, 0...cell_count)[0...cell_count]
32
- @colors.fill(@config.cell_color, 0...cell_count)[0...cell_count]
54
+ randomize_start_index if first_cell_redraw? && @config.start_row == :random
55
+ resize_cells(cell_count:) if cell_count != @inputs.count
33
56
 
34
57
  (@event_cursor...@event_tree.sequence.count).each do |event_index|
35
58
  current_event = @event_tree.sequence[event_index]
@@ -38,24 +61,27 @@ module Rain
38
61
  redraw_event(current_event:, past_event:)
39
62
  @event_cursor += 1
40
63
  end
41
-
42
- @inputs
43
64
  end
44
65
 
45
66
  # Render a cell's input as output after a delay, using cursors. Called on every frame.
46
- # ┌─┐
47
- # │R│ <-- Each cell is represented as an input, delay and output.
48
- # │e│
49
- # │q│ <-- The head cursor outputs the cell's input after a delay and colors the leading cell white.
50
- # │ │
51
- # │ │ <-- The tail cursor does the same thing but the input (and therefore output) will be empty.
52
- # └─┘ The tail cursor can be before or after the head cursor depending on whether events wrap around.
53
67
  #
54
- # Unit tests use "duration" to skip forwards in time, while matrix spec and the real world use old fashioned linear time.
55
- def render(duration: nil)
56
- @head_cursor.increment(delays:, inputs:, duration:) do |index|
57
- prev_index = (index - 1).clamp(0, nil)
58
- next_index = index >= @inputs.count ? 0 : index + 1
68
+ # INPUT DELAY OUTPUT
69
+ # ┌─────┬─────┬─────┐
70
+ # │ │ 0 │ │ ◀── 2. Hide Cursor moves the input to the output after a delay.
71
+ # │ │ 250 │ e │ The nil input replaces the previous output of "R".
72
+ # │ │ 250 │ q │
73
+ # │ │ 250 │ u │ ◀── 1. Show Cursor moves the input to the output after a delay.
74
+ # │ e │ 75 │ │ Leaving behind nil input.
75
+ # │ s │ 75 │ │ Then sets a "250" delay for the Hide Cursor.
76
+ # │ t │ 75 │ │
77
+ # └─────┴─────┴─────┘
78
+ #
79
+ # TODO: Refactor "@colors" into an Effect that happens dynamically on render rather than stored as a column of data.
80
+ # This will reduce the "Metrics/AbcSize" complexity.
81
+ def render(duration: nil) # rubocop:disable Metrics/AbcSize
82
+ @show_cursor.increment(delays:, inputs:, duration:) do |index|
83
+ prev_index = index.zero? ? @inputs.count - 1 : index - 1
84
+ next_index = index + 1 >= @inputs.count ? 0 : index + 1
59
85
 
60
86
  if @inputs[index]
61
87
  @outputs[index] = @inputs[index]
@@ -71,17 +97,14 @@ module Rain
71
97
 
72
98
  private
73
99
 
74
- attr_reader :inputs, :delays
75
-
76
100
  def fade(duration: nil)
77
- fade_start = rand(5_000..10_000)
78
-
79
- if (now - @head_cursor.first_update) >= fade_start || (duration && duration >= fade_start)
80
- @tail_cursor.increment(delays:, inputs:, duration:) do |index|
81
- if @inputs[index].nil? && @outputs[index]
82
- @outputs[index] = @inputs[index]
83
- @delays[index] = 0
84
- end
101
+ fade_start_delay = rand(5_000..10_000)
102
+ return unless (now - @show_cursor.first_update) >= fade_start_delay || duration
103
+
104
+ @hide_cursor.increment(delays:, inputs:, duration:) do |index|
105
+ if @inputs[index].nil? && @outputs[index]
106
+ @outputs[index] = @inputs[index]
107
+ @delays[index] = 0
85
108
  end
86
109
  end
87
110
  end
@@ -95,37 +118,42 @@ module Rain
95
118
  # │R│ FIRST EVENT
96
119
  # │e│ Each cell will render input as output after a minimum delay (since there's no prior event).
97
120
  # │q│
98
- # │u│
121
+ # │u│
99
122
  # │e│
100
123
  # │s│
101
124
  # │t│
102
- # └─┘ <-- Time has passed between events.
125
+ # └─┘ ◀── Time has passed between events.
103
126
  # ┌─┐
104
127
  # │││ SECOND EVENT
105
128
  # │▼│ The next event has data to work with, it can represent the time it took to get from the previous event to the next.
106
- # │R│ Each cell will render after the largest duration of the following values:
129
+ # │R│ Each cell will delay render for the larger duration of either:
107
130
  # │o│ 1. The minimum delay
108
- # │u│ 2. The time elapsed between events divided by the number of inputs
131
+ # │u│ 2. The time elapsed between events divided by the number of cells
109
132
  # │t│
110
- # │e│ <-- A cursor moves to the next cell after a delay and colors the leading cell white.
133
+ # │e│ ◀── A cursor moves to the next cell after a delay and colors the leading cell white.
111
134
  # └─┘
112
135
  def redraw_event(current_event:, past_event:)
113
- if @event_cursor == 0
114
- inputs = event_name(current_event:)
115
- delay = @config.min_delay
116
- randomize_start_row
117
- else
118
- inputs = [*ARROW, *event_name(current_event:)]
119
- difference = current_event.created_at - past_event.created_at
120
- delay = difference == 0 ? @config.min_delay : (difference / inputs.count).to_i.clamp(@config.min_delay, nil)
136
+ variable_delay = variable_delay(current_event:, past_event:)
137
+
138
+ characters = event_name(current_event:)
139
+ characters = [*ARROW, *characters] if @event_cursor > 0
140
+
141
+ @head_cursor.iterate(inputs: characters, loop_count: @inputs.count) do |index, input|
142
+ @inputs[index] = input
143
+ @delays[index] = first_cell_redraw? ? 0 : variable_delay # Don't add delay to the first cell, looks stuck.
144
+
145
+ @tail_cursor.increase_index(loop_count: @inputs.count) if @head_cursor.index == @tail_cursor.index
121
146
  end
122
147
 
123
- inputs.each do |character|
124
- @inputs[@redraw_cursor] = character
125
- @delays[@redraw_cursor] = @redraw_cursor == 0 ? 0 : delay # Don't add delay to the first cell, looks stuck.
148
+ @hide_cursor.index = @head_cursor.index # Everything after me is old so it can fade away.
149
+ end
126
150
 
127
- @redraw_cursor += 1
128
- @redraw_cursor = 0 if @redraw_cursor >= @inputs.count
151
+ def variable_delay(current_event:, past_event:)
152
+ if @event_cursor.zero?
153
+ @config.min_delay
154
+ else
155
+ difference = current_event.created_at - past_event.created_at
156
+ difference.zero? ? @config.min_delay : (difference / inputs.count).to_i.clamp(@config.min_delay, nil)
129
157
  end
130
158
  end
131
159
 
@@ -133,12 +161,26 @@ module Rain
133
161
  current_event.class.name.split('::').last.delete_suffix('Event').chars
134
162
  end
135
163
 
136
- def randomize_start_row
137
- return unless @config.start_row == :random
164
+ def first_cell_redraw?
165
+ @head_cursor.index == -1
166
+ end
167
+
168
+ def resize_cells(cell_count:)
169
+ old_index = (@inputs.count - 1).clamp(0, nil)
170
+
171
+ @inputs = @inputs.fill(nil, old_index...cell_count)[0...cell_count]
172
+ @outputs = @outputs.fill(nil, old_index...cell_count)[0...cell_count]
173
+ @delays = @delays.fill(@config.min_delay, old_index...cell_count)[0...cell_count]
174
+ @colors = @colors.fill(@config.cell_color, old_index...cell_count)[0...cell_count]
175
+ end
176
+
177
+ def randomize_start_index
178
+ random_index = rand(0..2)
179
+
180
+ @head_cursor.index = random_index
181
+ @tail_cursor.index = random_index
138
182
 
139
- random_index = rand(0..2)
140
- @redraw_cursor = random_index
141
- @head_cursor.index = random_index - 1 # Head cursor always 1 index behind to make "increment" method's logic simple.
183
+ @show_cursor.index = random_index
142
184
  end
143
185
  end
144
186
  end
data/lib/raindeer.rb CHANGED
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'low_dependency'
4
3
  require 'low_event'
5
4
  require 'low_node'
6
5
  require 'low_type'
7
6
  require 'observers'
7
+ require 'providers'
8
8
 
9
9
  require_relative 'router/router'
10
10
 
11
11
  module Raindeer
12
12
  class << self
13
13
  def router(&block)
14
- Low::Providers['rain.router'].instance_eval(&block)
14
+ Providers['rain.router'].instance_eval(&block)
15
15
  end
16
16
  end
17
17
  end
data/lib/router/router.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'low_dependency'
4
3
  require 'low_event'
4
+ require 'providers'
5
5
 
6
6
  require_relative 'route'
7
7
  require_relative 'route_event'
@@ -4,7 +4,7 @@ class RoutesNode < LowNode
4
4
  observe '/system/routes'
5
5
 
6
6
  def initialize(event:)
7
- @routes = Low::Providers['rain.router'].routes
7
+ @routes = Providers['rain.router'].routes
8
8
  end
9
9
 
10
10
  def render(event:)
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Raindeer
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raindeer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi
@@ -38,21 +38,21 @@ dependencies:
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
40
  - !ruby/object:Gem::Dependency
41
- name: low_dependency
41
+ name: low_event
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - ">="
44
+ - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '0'
46
+ version: '0.5'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ">="
51
+ - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0'
53
+ version: '0.5'
54
54
  - !ruby/object:Gem::Dependency
55
- name: low_event
55
+ name: lowload
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - ">="
@@ -69,16 +69,16 @@ dependencies:
69
69
  name: low_loop
70
70
  requirement: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - ">="
72
+ - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '0'
74
+ version: '0.5'
75
75
  type: :runtime
76
76
  prerelease: false
77
77
  version_requirements: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ">="
79
+ - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '0'
81
+ version: '0.5'
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: low_node
84
84
  requirement: !ruby/object:Gem::Requirement
@@ -122,7 +122,7 @@ dependencies:
122
122
  - !ruby/object:Gem::Version
123
123
  version: '1.0'
124
124
  - !ruby/object:Gem::Dependency
125
- name: lowload
125
+ name: antlers
126
126
  requirement: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - ">="
@@ -136,7 +136,7 @@ dependencies:
136
136
  - !ruby/object:Gem::Version
137
137
  version: '0'
138
138
  - !ruby/object:Gem::Dependency
139
- name: antlers
139
+ name: expressions
140
140
  requirement: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - ">="
@@ -150,7 +150,7 @@ dependencies:
150
150
  - !ruby/object:Gem::Version
151
151
  version: '0'
152
152
  - !ruby/object:Gem::Dependency
153
- name: expressions
153
+ name: observers
154
154
  requirement: !ruby/object:Gem::Requirement
155
155
  requirements:
156
156
  - - ">="
@@ -164,7 +164,7 @@ dependencies:
164
164
  - !ruby/object:Gem::Version
165
165
  version: '0'
166
166
  - !ruby/object:Gem::Dependency
167
- name: observers
167
+ name: providers
168
168
  requirement: !ruby/object:Gem::Requirement
169
169
  requirements:
170
170
  - - ">="