tty-progressbar 0.14.0 → 0.18.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 +5 -5
- data/CHANGELOG.md +98 -21
- data/LICENSE.txt +1 -1
- data/README.md +511 -119
- data/lib/tty-progressbar.rb +2 -2
- data/lib/tty/progressbar.rb +216 -87
- data/lib/tty/progressbar/configuration.rb +124 -16
- data/lib/tty/progressbar/converter.rb +16 -19
- data/lib/tty/progressbar/formats.rb +120 -0
- data/lib/tty/progressbar/formatter.rb +33 -38
- data/lib/tty/progressbar/formatter/bar.rb +87 -29
- data/lib/tty/progressbar/formatter/byte_rate.rb +6 -20
- data/lib/tty/progressbar/formatter/current.rb +4 -19
- data/lib/tty/progressbar/formatter/current_byte.rb +9 -17
- data/lib/tty/progressbar/formatter/elapsed.rb +9 -18
- data/lib/tty/progressbar/formatter/estimated.rb +14 -18
- data/lib/tty/progressbar/formatter/estimated_time.rb +37 -0
- data/lib/tty/progressbar/formatter/mean_byte.rb +6 -20
- data/lib/tty/progressbar/formatter/mean_rate.rb +6 -20
- data/lib/tty/progressbar/formatter/percent.rb +10 -16
- data/lib/tty/progressbar/formatter/rate.rb +5 -19
- data/lib/tty/progressbar/formatter/total.rb +10 -16
- data/lib/tty/progressbar/formatter/total_byte.rb +14 -18
- data/lib/tty/progressbar/formatters.rb +53 -0
- data/lib/tty/progressbar/meter.rb +2 -2
- data/lib/tty/progressbar/multi.rb +69 -23
- data/lib/tty/progressbar/pipeline.rb +13 -6
- data/lib/tty/progressbar/timer.rb +89 -0
- data/lib/tty/progressbar/version.rb +3 -1
- metadata +65 -151
- data/.codeclimate.yml +0 -11
- data/.gitignore +0 -14
- data/.rspec +0 -3
- data/.travis.yml +0 -25
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -14
- data/Rakefile +0 -8
- data/appveyor.yml +0 -21
- data/examples/color.rb +0 -18
- data/examples/failure.rb +0 -12
- data/examples/iterator.rb +0 -5
- data/examples/lazy.rb +0 -6
- data/examples/multi/main_bar.rb +0 -13
- data/examples/multi/simple.rb +0 -13
- data/examples/simple.rb +0 -7
- data/examples/slow_process.rb +0 -29
- data/examples/speed.rb +0 -11
- data/examples/threaded.rb +0 -14
- data/examples/tokens.rb +0 -12
- data/spec/spec_helper.rb +0 -50
- data/spec/unit/advance_spec.rb +0 -25
- data/spec/unit/clear_spec.rb +0 -17
- data/spec/unit/complete_spec.rb +0 -16
- data/spec/unit/converter/to_bytes_spec.rb +0 -47
- data/spec/unit/converter/to_seconds_spec.rb +0 -15
- data/spec/unit/converter/to_time_spec.rb +0 -19
- data/spec/unit/custom_formatter_spec.rb +0 -26
- data/spec/unit/custom_token_spec.rb +0 -14
- data/spec/unit/events_spec.rb +0 -33
- data/spec/unit/finish_spec.rb +0 -15
- data/spec/unit/formatter/bar_spec.rb +0 -16
- data/spec/unit/formatter/byte_rate_spec.rb +0 -32
- data/spec/unit/formatter/current_byte_spec.rb +0 -16
- data/spec/unit/formatter/current_spec.rb +0 -14
- data/spec/unit/formatter/elapsed_spec.rb +0 -58
- data/spec/unit/formatter/estimated_spec.rb +0 -27
- data/spec/unit/formatter/mean_byte_spec.rb +0 -32
- data/spec/unit/formatter/mean_rate_spec.rb +0 -31
- data/spec/unit/formatter/percent_spec.rb +0 -16
- data/spec/unit/formatter/rate_spec.rb +0 -31
- data/spec/unit/formatter/total_byte_spec.rb +0 -16
- data/spec/unit/formatter/total_spec.rb +0 -16
- data/spec/unit/frequency_spec.rb +0 -27
- data/spec/unit/head_spec.rb +0 -32
- data/spec/unit/hide_cursor_spec.rb +0 -27
- data/spec/unit/inspect_spec.rb +0 -11
- data/spec/unit/iterate_spec.rb +0 -79
- data/spec/unit/log_spec.rb +0 -29
- data/spec/unit/meter_spec.rb +0 -70
- data/spec/unit/multi/advance_spec.rb +0 -123
- data/spec/unit/multi/events_spec.rb +0 -115
- data/spec/unit/multi/finish_spec.rb +0 -41
- data/spec/unit/multi/line_inset_spec.rb +0 -65
- data/spec/unit/multi/register_spec.rb +0 -35
- data/spec/unit/multi/stop_spec.rb +0 -15
- data/spec/unit/new_spec.rb +0 -66
- data/spec/unit/pipeline_spec.rb +0 -19
- data/spec/unit/ratio_spec.rb +0 -31
- data/spec/unit/reset_spec.rb +0 -31
- data/spec/unit/resize_spec.rb +0 -35
- data/spec/unit/set_current_spec.rb +0 -43
- data/spec/unit/start_spec.rb +0 -14
- data/spec/unit/stop_spec.rb +0 -19
- data/spec/unit/update_spec.rb +0 -22
- data/spec/unit/width_spec.rb +0 -21
- data/tasks/console.rake +0 -9
- data/tasks/coverage.rake +0 -9
- data/tasks/spec.rake +0 -27
- data/tty-progressbar.gemspec +0 -30
@@ -1,27 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "../formatter"
|
4
|
+
|
3
5
|
module TTY
|
4
6
|
class ProgressBar
|
5
7
|
# Used by {Pipeline} to format bar
|
6
8
|
#
|
7
9
|
# @api private
|
8
10
|
class BarFormatter
|
9
|
-
|
10
|
-
|
11
|
-
def initialize(progress)
|
12
|
-
@progress = progress
|
13
|
-
end
|
14
|
-
|
15
|
-
# Determines whether this formatter is applied or not.
|
16
|
-
#
|
17
|
-
# @param [Object] value
|
18
|
-
#
|
19
|
-
# @return [Boolean]
|
20
|
-
#
|
21
|
-
# @api private
|
22
|
-
def matches?(value)
|
23
|
-
!!(value.to_s =~ MATCHER)
|
24
|
-
end
|
11
|
+
include TTY::ProgressBar::Formatter[/:bar/i.freeze]
|
25
12
|
|
26
13
|
# Format :bar token
|
27
14
|
#
|
@@ -29,19 +16,90 @@ module TTY
|
|
29
16
|
# the value being formatted
|
30
17
|
#
|
31
18
|
# @api public
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
19
|
+
def call(value)
|
20
|
+
without_bar = value.gsub(/:bar/, "")
|
21
|
+
available_space = [0, ProgressBar.max_columns -
|
22
|
+
ProgressBar.display_columns(without_bar) -
|
23
|
+
@progress.inset].max
|
24
|
+
width = [@progress.width.to_i, available_space].min
|
25
|
+
|
26
|
+
# When we don't know the total progress, use either user
|
27
|
+
# defined width or rely on terminal width detection
|
28
|
+
if @progress.indeterminate?
|
29
|
+
width = available_space if width.zero?
|
30
|
+
|
31
|
+
format_indeterminate(value, width)
|
32
|
+
else
|
33
|
+
format_determinate(value, width)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# @api private
|
40
|
+
def format_indeterminate(value, width)
|
41
|
+
buffer = []
|
42
|
+
possible_width = width
|
43
|
+
unknown_char_length = ProgressBar.display_columns(@progress.unknown)
|
44
|
+
complete_char_length = ProgressBar.display_columns(@progress.complete)
|
45
|
+
incomplete_char_length = ProgressBar.display_columns(@progress.incomplete)
|
46
|
+
head_char_length = ProgressBar.display_columns(@progress.head)
|
47
|
+
|
48
|
+
possible_width -= unknown_char_length
|
49
|
+
max_char_length = [complete_char_length, incomplete_char_length,
|
50
|
+
head_char_length].max
|
51
|
+
# figure out how many unicode chars would fit normally
|
52
|
+
# when the bar has total to prevent resizing
|
53
|
+
possible_width = (possible_width / max_char_length) * max_char_length
|
54
|
+
complete = (possible_width * @progress.ratio).round
|
55
|
+
incomplete = possible_width - complete
|
56
|
+
|
57
|
+
buffer << " " * complete
|
58
|
+
buffer << @progress.unknown
|
59
|
+
buffer << " " * incomplete
|
60
|
+
|
61
|
+
value.gsub(matcher, buffer.join)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
def format_determinate(value, width)
|
66
|
+
complete_bar_length = (width * @progress.ratio).round
|
67
|
+
complete_char_length = ProgressBar.display_columns(@progress.complete)
|
68
|
+
incomplete_char_length = ProgressBar.display_columns(@progress.incomplete)
|
69
|
+
head_char_length = ProgressBar.display_columns(@progress.head)
|
70
|
+
|
71
|
+
# division by char length only when unicode chars are used
|
72
|
+
# otherwise it has no effect on regular ascii chars
|
73
|
+
complete_items = [
|
74
|
+
complete_bar_length / complete_char_length,
|
75
|
+
# or see how many incomplete (unicode) items fit
|
76
|
+
(complete_bar_length / incomplete_char_length) * incomplete_char_length
|
77
|
+
].min
|
78
|
+
|
79
|
+
complete_width = complete_items * complete_char_length
|
80
|
+
incomplete_width = width - complete_width
|
81
|
+
incomplete_items = [
|
82
|
+
incomplete_width / incomplete_char_length,
|
83
|
+
# or see how many complete (unicode) items fit
|
84
|
+
(incomplete_width / complete_char_length) * complete_char_length
|
85
|
+
].min
|
86
|
+
|
87
|
+
complete = Array.new(complete_items, @progress.complete)
|
88
|
+
incomplete = Array.new(incomplete_items, @progress.incomplete)
|
89
|
+
|
90
|
+
if complete_items > 0 && head_char_length > 0 &&
|
91
|
+
(incomplete_items > 0 || incomplete_items.zero? && !@progress.clear_head)
|
92
|
+
# see how many head chars per complete char
|
93
|
+
times = (head_char_length / complete_char_length.to_f).round
|
94
|
+
if complete_items < times # not enough complete chars to fit
|
95
|
+
incomplete.pop(times - complete_items)
|
96
|
+
end
|
97
|
+
complete.pop(times)
|
98
|
+
extra_space = " " * (times * complete_char_length - head_char_length)
|
99
|
+
complete << "#{@progress.head}#{extra_space}"
|
100
|
+
end
|
101
|
+
|
102
|
+
value.gsub(matcher, "#{complete.join}#{incomplete.join}")
|
45
103
|
end
|
46
104
|
end # BarFormatter
|
47
105
|
end # ProgressBar
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../converter"
|
4
|
+
require_relative "../formatter"
|
4
5
|
|
5
6
|
module TTY
|
6
7
|
class ProgressBar
|
@@ -8,32 +9,17 @@ module TTY
|
|
8
9
|
#
|
9
10
|
# @api private
|
10
11
|
class ByteRateFormatter
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(progress)
|
14
|
-
@progress = progress
|
15
|
-
end
|
16
|
-
|
17
|
-
# Determines whether this formatter is applied or not.
|
18
|
-
#
|
19
|
-
# @param [Object] value
|
20
|
-
#
|
21
|
-
# @return [Boolean]
|
22
|
-
#
|
23
|
-
# @api private
|
24
|
-
def matches?(value)
|
25
|
-
!!(value.to_s =~ MATCHER)
|
26
|
-
end
|
12
|
+
include TTY::ProgressBar::Formatter[/:byte_rate/i.freeze]
|
27
13
|
|
28
14
|
# Format :byte_rate token
|
29
15
|
#
|
30
16
|
# @param [String] value
|
31
|
-
# the value
|
17
|
+
# the value to format
|
32
18
|
#
|
33
19
|
# @api public
|
34
|
-
def
|
20
|
+
def call(value)
|
35
21
|
formatted = Converter.to_bytes(@progress.rate)
|
36
|
-
value.gsub(
|
22
|
+
value.gsub(matcher, formatted)
|
37
23
|
end
|
38
24
|
end # ByteRateFormatter
|
39
25
|
end # ProgressBar
|
@@ -6,31 +6,16 @@ module TTY
|
|
6
6
|
#
|
7
7
|
# @api private
|
8
8
|
class CurrentFormatter
|
9
|
-
|
10
|
-
|
11
|
-
def initialize(progress)
|
12
|
-
@progress = progress
|
13
|
-
end
|
14
|
-
|
15
|
-
# Determines whether this formatter is applied or not.
|
16
|
-
#
|
17
|
-
# @param [Object] value
|
18
|
-
#
|
19
|
-
# @return [Boolean]
|
20
|
-
#
|
21
|
-
# @api private
|
22
|
-
def matches?(value)
|
23
|
-
!!(value.to_s =~ MATCHER)
|
24
|
-
end
|
9
|
+
include TTY::ProgressBar::Formatter[/:current\b/i.freeze]
|
25
10
|
|
26
11
|
# Format :current token
|
27
12
|
#
|
28
13
|
# @param [String] value
|
29
|
-
# the value
|
14
|
+
# the value to format
|
30
15
|
#
|
31
16
|
# @api public
|
32
|
-
def
|
33
|
-
value.gsub(
|
17
|
+
def call(value)
|
18
|
+
value.gsub(matcher, @progress.current.to_s)
|
34
19
|
end
|
35
20
|
end # CurrentFormatter
|
36
21
|
end # ProgressBar
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../converter"
|
4
|
+
require_relative "../formatter"
|
4
5
|
|
5
6
|
module TTY
|
6
7
|
class ProgressBar
|
@@ -8,26 +9,17 @@ module TTY
|
|
8
9
|
#
|
9
10
|
# @api private
|
10
11
|
class ByteFormatter
|
11
|
-
|
12
|
+
include TTY::ProgressBar::Formatter[/(:current_byte|:byte)\b/i.freeze]
|
12
13
|
|
13
|
-
|
14
|
-
@progress = progress
|
15
|
-
end
|
16
|
-
|
17
|
-
# Determines whether this formatter is applied or not.
|
18
|
-
#
|
19
|
-
# @param [Object] value
|
14
|
+
# Format :current_byte token
|
20
15
|
#
|
21
|
-
# @
|
16
|
+
# @param [String] value
|
17
|
+
# the value to format
|
22
18
|
#
|
23
|
-
# @api
|
24
|
-
def
|
25
|
-
!!(value.to_s =~ MATCHER)
|
26
|
-
end
|
27
|
-
|
28
|
-
def format(value)
|
19
|
+
# @api public
|
20
|
+
def call(value)
|
29
21
|
bytes = Converter.to_bytes(@progress.current)
|
30
|
-
value.gsub(
|
22
|
+
value.gsub(matcher, bytes)
|
31
23
|
end
|
32
24
|
end # ByteFormatter
|
33
25
|
end # ProgressBar
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../converter"
|
4
|
+
require_relative "../formatter"
|
4
5
|
|
5
6
|
module TTY
|
6
7
|
class ProgressBar
|
@@ -8,26 +9,16 @@ module TTY
|
|
8
9
|
#
|
9
10
|
# @api private
|
10
11
|
class ElapsedFormatter
|
11
|
-
|
12
|
+
include TTY::ProgressBar::Formatter[/:elapsed/.freeze]
|
12
13
|
|
13
|
-
|
14
|
-
@progress = progress
|
15
|
-
end
|
16
|
-
|
17
|
-
# Determines whether this formatter is applied or not.
|
18
|
-
#
|
19
|
-
# @param [Object] value
|
14
|
+
# Format :elapsed token
|
20
15
|
#
|
21
|
-
# @
|
16
|
+
# @param [String] value
|
17
|
+
# the value to format
|
22
18
|
#
|
23
|
-
# @api
|
24
|
-
def
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def format(value)
|
29
|
-
elapsed = (Time.now - @progress.start_at)
|
30
|
-
value.gsub(MATCHER, Converter.to_time(elapsed))
|
19
|
+
# @api public
|
20
|
+
def call(value)
|
21
|
+
value.gsub(matcher, Converter.to_time(@progress.elapsed_time))
|
31
22
|
end
|
32
23
|
end # ElapsedFormatter
|
33
24
|
end # ProgressBar
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../converter"
|
4
|
+
require_relative "../formatter"
|
4
5
|
|
5
6
|
module TTY
|
6
7
|
class ProgressBar
|
@@ -8,29 +9,24 @@ module TTY
|
|
8
9
|
#
|
9
10
|
# @api private
|
10
11
|
class EstimatedFormatter
|
11
|
-
|
12
|
+
include TTY::ProgressBar::Formatter[/:eta/.freeze]
|
12
13
|
|
13
|
-
|
14
|
-
@progress = progress
|
15
|
-
end
|
16
|
-
|
17
|
-
# Determines whether this formatter is applied or not.
|
14
|
+
# Format :eta token
|
18
15
|
#
|
19
|
-
# @param [
|
16
|
+
# @param [String] value
|
17
|
+
# the value to format
|
20
18
|
#
|
21
|
-
# @
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
19
|
+
# @api public
|
20
|
+
def call(value)
|
21
|
+
if @progress.indeterminate?
|
22
|
+
return value.gsub(matcher, "--s")
|
23
|
+
end
|
27
24
|
|
28
|
-
|
29
|
-
elapsed = Time.now - @progress.start_at
|
25
|
+
elapsed = @progress.elapsed_time
|
30
26
|
estimated = (elapsed / @progress.ratio).to_f - elapsed
|
31
27
|
estimated = (estimated.infinite? || estimated < 0) ? 0.0 : estimated
|
32
|
-
value.gsub(
|
28
|
+
value.gsub(matcher, Converter.to_time(estimated))
|
33
29
|
end
|
34
|
-
end #
|
30
|
+
end # EstimatedFormatter
|
35
31
|
end # ProgressBar
|
36
32
|
end # TTY
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class ProgressBar
|
5
|
+
# Used by {Pipeline} to format :eta_time token
|
6
|
+
#
|
7
|
+
# @api private
|
8
|
+
class EstimatedTimeFormatter
|
9
|
+
include TTY::ProgressBar::Formatter[/:eta_time/.freeze]
|
10
|
+
|
11
|
+
# Format :eta_time token
|
12
|
+
#
|
13
|
+
# @param [String] value
|
14
|
+
# the value to format
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
def call(value)
|
18
|
+
if @progress.indeterminate?
|
19
|
+
return value.gsub(matcher, "--:--:--")
|
20
|
+
end
|
21
|
+
|
22
|
+
elapsed = @progress.elapsed_time
|
23
|
+
estimated = (elapsed / @progress.ratio).to_f - elapsed
|
24
|
+
estimated = (estimated.infinite? || estimated < 0) ? 0.0 : estimated
|
25
|
+
|
26
|
+
time_format = if estimated >= 86_400 # longer than a day
|
27
|
+
"%Y-%m-%d %H:%M:%S"
|
28
|
+
else
|
29
|
+
"%H:%M:%S"
|
30
|
+
end
|
31
|
+
completion_time = Time.now + estimated
|
32
|
+
eta_time = completion_time.strftime(time_format)
|
33
|
+
value.gsub(matcher, eta_time)
|
34
|
+
end
|
35
|
+
end # EstimatedTimeFormatter
|
36
|
+
end # ProgressBar
|
37
|
+
end # TTY
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../converter"
|
4
|
+
require_relative "../formatter"
|
4
5
|
|
5
6
|
module TTY
|
6
7
|
class ProgressBar
|
@@ -8,32 +9,17 @@ module TTY
|
|
8
9
|
#
|
9
10
|
# @api private
|
10
11
|
class MeanByteFormatter
|
11
|
-
|
12
|
+
include TTY::ProgressBar::Formatter[/:mean_byte/i.freeze]
|
12
13
|
|
13
|
-
|
14
|
-
@progress = progress
|
15
|
-
end
|
16
|
-
|
17
|
-
# Determines whether this formatter is applied or not.
|
18
|
-
#
|
19
|
-
# @param [Object] value
|
20
|
-
#
|
21
|
-
# @return [Boolean]
|
22
|
-
#
|
23
|
-
# @api private
|
24
|
-
def matches?(value)
|
25
|
-
!!(value.to_s =~ MATCHER)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Format :rate token
|
14
|
+
# Format :mean_byte token
|
29
15
|
#
|
30
16
|
# @param [String] value
|
31
17
|
# the value being formatted
|
32
18
|
#
|
33
19
|
# @api public
|
34
|
-
def
|
20
|
+
def call(value)
|
35
21
|
formatted = Converter.to_bytes(@progress.mean_rate)
|
36
|
-
value.gsub(
|
22
|
+
value.gsub(matcher, formatted)
|
37
23
|
end
|
38
24
|
end # MeanByteFormatter
|
39
25
|
end # ProgressBar
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../converter"
|
4
|
+
require_relative "../formatter"
|
4
5
|
|
5
6
|
module TTY
|
6
7
|
class ProgressBar
|
@@ -8,32 +9,17 @@ module TTY
|
|
8
9
|
#
|
9
10
|
# @api private
|
10
11
|
class MeanRateFormatter
|
11
|
-
|
12
|
+
include TTY::ProgressBar::Formatter[/:mean_rate/i.freeze]
|
12
13
|
|
13
|
-
|
14
|
-
@progress = progress
|
15
|
-
end
|
16
|
-
|
17
|
-
# Determines whether this formatter is applied or not.
|
18
|
-
#
|
19
|
-
# @param [Object] value
|
20
|
-
#
|
21
|
-
# @return [Boolean]
|
22
|
-
#
|
23
|
-
# @api private
|
24
|
-
def matches?(value)
|
25
|
-
!!(value.to_s =~ MATCHER)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Format :rate token
|
14
|
+
# Format :mean_rate token
|
29
15
|
#
|
30
16
|
# @param [String] value
|
31
17
|
# the value being formatted
|
32
18
|
#
|
33
19
|
# @api public
|
34
|
-
def
|
20
|
+
def call(value)
|
35
21
|
formatted = Converter.to_seconds(@progress.mean_rate)
|
36
|
-
value.gsub(
|
22
|
+
value.gsub(matcher, formatted)
|
37
23
|
end
|
38
24
|
end # MeanRateFormatter
|
39
25
|
end # ProgressBar
|