rage_flip 1.0.1 → 1.2.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.
data/Rakefile CHANGED
@@ -1,36 +1,36 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rspec/core/rake_task'
4
- require_relative 'lib/rage_flip/version'
1
+ require "rake"
2
+ require "rake/testtask"
3
+ require "rspec/core/rake_task"
4
+ require_relative "lib/rage_flip/version"
5
5
 
6
6
  # Define the default task
7
- task :default => :test
7
+ task default: :test
8
8
 
9
9
  # Define a task for running tests with RSpec
10
10
  RSpec::Core::RakeTask.new(:test) do |t|
11
- t.pattern = 'spec/**/*_spec.rb'
11
+ t.pattern = "spec/**/*_spec.rb"
12
12
  end
13
13
 
14
14
  # Alias for backwards compatibility
15
- task :spec => :test
15
+ task spec: :test
16
16
 
17
17
  # Define a task for building the gem
18
18
  task :build do
19
- sh 'gem build rage_flip.gemspec'
19
+ sh "gem build rage_flip.gemspec"
20
20
  end
21
21
 
22
22
  # Define a task for installing the gem
23
23
  task :install do
24
- sh 'gem install rage_flip-*.gem'
24
+ sh "gem install rage_flip-*.gem"
25
25
  end
26
26
 
27
27
  # Define a task for cleaning up generated files
28
28
  task :clean do
29
- rm_rf Dir['*.gem']
29
+ rm_rf Dir["*.gem"]
30
30
  end
31
31
 
32
32
  # Define a task for running all tasks
33
- task :all => [:build, :install, :test]
33
+ task all: [:build, :install, :test]
34
34
 
35
35
  # Version management tasks
36
36
  namespace :version do
@@ -60,12 +60,12 @@ namespace :version do
60
60
  puts "Usage: rake version:set[1.2.3]"
61
61
  exit 1
62
62
  end
63
-
63
+
64
64
  unless args[:version].match?(/^\d+\.\d+\.\d+$/)
65
65
  puts "Error: Version must be in format X.Y.Z (e.g., 1.2.3)"
66
66
  exit 1
67
67
  end
68
-
68
+
69
69
  update_version_file(args[:version])
70
70
  puts "Version set to #{args[:version]}"
71
71
  end
@@ -101,8 +101,8 @@ end
101
101
  # Helper method to bump version
102
102
  def bump_version(type)
103
103
  current_version = read_current_version
104
- current = current_version.split('.').map(&:to_i)
105
-
104
+ current = current_version.split(".").map(&:to_i)
105
+
106
106
  case type
107
107
  when :patch
108
108
  current[2] += 1
@@ -114,28 +114,28 @@ def bump_version(type)
114
114
  current[1] = 0
115
115
  current[2] = 0
116
116
  end
117
-
118
- new_version = current.join('.')
117
+
118
+ new_version = current.join(".")
119
119
  update_version_file(new_version)
120
120
  puts "Version bumped from #{current_version} to #{new_version}"
121
121
  end
122
122
 
123
123
  # Helper method to read current version from file
124
124
  def read_current_version
125
- version_file = 'lib/rage_flip/version.rb'
125
+ version_file = "lib/rage_flip/version.rb"
126
126
  content = File.read(version_file)
127
127
  content.match(/VERSION = "([^"]+)"/)[1]
128
128
  end
129
129
 
130
130
  # Helper method to update version file
131
131
  def update_version_file(new_version)
132
- version_file = 'lib/rage_flip/version.rb'
132
+ version_file = "lib/rage_flip/version.rb"
133
133
  content = File.read(version_file)
134
-
134
+
135
135
  updated_content = content.gsub(
136
- /VERSION = "[^"]+"/,
136
+ /VERSION = "[^"]+"/,
137
137
  "VERSION = \"#{new_version}\""
138
138
  )
139
-
139
+
140
140
  File.write(version_file, updated_content)
141
- end
141
+ end
data/exe/chaos CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/rage_flip'
3
+ require_relative "../lib/rage_flip"
4
4
 
5
- text = ARGV.join(' ')
5
+ text = ARGV.join(" ")
6
6
 
7
7
  if text.empty?
8
8
  puts "Usage: chaos <text_to_chaos>"
@@ -12,8 +12,7 @@ end
12
12
  result = RageFlip::Chaos.process(text)
13
13
 
14
14
  if RageFlip::Clipboard.copy(result)
15
- puts result
16
15
  else
17
16
  puts "Failed to copy to clipboard, but here's your chaotic text:"
18
- puts result
19
- end
17
+ end
18
+ puts result
data/exe/chaos_level CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/rage_flip'
3
+ require_relative "../lib/rage_flip"
4
4
 
5
5
  if ARGV.length == 0
6
6
  puts "Current chaos level: #{RageFlip::Chaos.current_chaos_level}"
@@ -9,7 +9,7 @@ elsif ARGV.length != 1
9
9
  puts "Usage: chaos_level [more|less|number|show]"
10
10
  puts " (no args) - Show current chaos level"
11
11
  puts " more - Increase chaos level by 1"
12
- puts " less - Decrease chaos level by 1"
12
+ puts " less - Decrease chaos level by 1"
13
13
  puts " number - Set chaos level to specific number"
14
14
  puts " show - Show current chaos level"
15
15
  exit 1
@@ -17,9 +17,9 @@ end
17
17
 
18
18
  instruction = ARGV[0]
19
19
 
20
- if instruction == 'show'
20
+ if instruction == "show"
21
21
  puts "Current chaos level: #{RageFlip::Chaos.current_chaos_level}"
22
22
  else
23
23
  result = RageFlip::Chaos.set_chaos_level(instruction)
24
24
  puts result
25
- end
25
+ end
data/exe/disapproval ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/rage_flip"
4
+
5
+ SUBSTITUTION_NAME = File.basename($0)
6
+ result = RageFlip::TextSubstitution.process(SUBSTITUTION_NAME)
7
+
8
+ if result
9
+ if RageFlip::Clipboard.copy(result)
10
+ else
11
+ puts "Failed to copy to clipboard, but here's your text substitution:"
12
+ end
13
+ puts result
14
+ else
15
+ puts "Unknown substitution: #{SUBSTITUTION_NAME}"
16
+ exit 1
17
+ end
data/exe/doubleunderline CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/rage_flip'
3
+ require_relative "../lib/rage_flip"
4
4
 
5
- text = ARGV.join(' ')
5
+ text = ARGV.join(" ")
6
6
 
7
7
  if text.empty?
8
8
  puts "Usage: doubleunderline <text_to_double_underline>"
@@ -12,8 +12,7 @@ end
12
12
  result = RageFlip::Underline.double_underline(text)
13
13
 
14
14
  if RageFlip::Clipboard.copy(result)
15
- puts result
16
15
  else
17
16
  puts "Failed to copy to clipboard, but here's your double underlined text:"
18
- puts result
19
- end
17
+ end
18
+ puts result
data/exe/emote ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/rage_flip"
4
+
5
+ if ARGV.length == 0
6
+ puts RageFlip::Emote.list_emotes
7
+ exit 0
8
+ end
9
+
10
+ emote_name = ARGV[0].downcase
11
+
12
+ if emote_name == "list"
13
+ puts RageFlip::Emote.list_emotes
14
+ exit 0
15
+ end
16
+
17
+ result = RageFlip::Emote.process(emote_name)
18
+
19
+ if result
20
+ # Copy to clipboard
21
+ if RageFlip::Clipboard.copy(result)
22
+ else
23
+ puts "Failed to copy to clipboard, but here's your emote:"
24
+ end
25
+ puts result
26
+ else
27
+ puts "Unknown emote: #{emote_name}"
28
+ puts ""
29
+ puts RageFlip::Emote.list_emotes
30
+ exit 1
31
+ end
data/exe/flip ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/rage_flip"
4
+
5
+ SUBSTITUTION_NAME = File.basename($0)
6
+ result = RageFlip::TextSubstitution.process(SUBSTITUTION_NAME)
7
+
8
+ if result
9
+ if RageFlip::Clipboard.copy(result)
10
+ else
11
+ puts "Failed to copy to clipboard, but here's your text substitution:"
12
+ end
13
+ puts result
14
+ else
15
+ puts "Unknown substitution: #{SUBSTITUTION_NAME}"
16
+ exit 1
17
+ end
data/exe/flip_text ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/rage_flip"
4
+
5
+ text = ARGV.join(" ")
6
+
7
+ if text.empty?
8
+ puts "Usage: flip_text <text_to_flip>"
9
+ exit 1
10
+ end
11
+
12
+ # Just flip the text without any emoticons
13
+ result = RageFlip::Flipper.flip_text(text)
14
+
15
+ # Copy to clipboard
16
+ if RageFlip::Clipboard.copy(result)
17
+ else
18
+ puts "Failed to copy to clipboard, but here's your flipped text:"
19
+ end
20
+ puts result
data/exe/rage_flip CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/rage_flip'
3
+ require_relative "../lib/rage_flip"
4
4
 
5
5
  # Get the arguments passed to the script
6
- text = ARGV.join(' ')
6
+ text = ARGV.join(" ")
7
7
 
8
8
  if text.empty?
9
9
  puts "Usage: rage_flip <text_to_flip>"
@@ -15,8 +15,7 @@ result = RageFlip::Flipper.rage_flip(text)
15
15
 
16
16
  # Copy to clipboard
17
17
  if RageFlip::Clipboard.copy(result)
18
- puts result
19
18
  else
20
19
  puts "Failed to copy to clipboard, but here's your flipped text:"
21
- puts result
22
- end
20
+ end
21
+ puts result
data/exe/sarcasm CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/rage_flip'
3
+ require_relative "../lib/rage_flip"
4
4
 
5
- text = ARGV.join(' ')
5
+ text = ARGV.join(" ")
6
6
 
7
7
  if text.empty?
8
8
  puts "Usage: sarcasm <text_to_sarcasm>"
@@ -12,8 +12,7 @@ end
12
12
  result = RageFlip::Sarcasm.process(text)
13
13
 
14
14
  if RageFlip::Clipboard.copy(result)
15
- puts result
16
15
  else
17
16
  puts "Failed to copy to clipboard, but here's your sarcastic text:"
18
- puts result
19
- end
17
+ end
18
+ puts result
data/exe/strikethrough CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/rage_flip'
3
+ require_relative "../lib/rage_flip"
4
4
 
5
- text = ARGV.join(' ')
5
+ text = ARGV.join(" ")
6
6
 
7
7
  if text.empty?
8
8
  puts "Usage: strikethrough <text_to_strikethrough>"
@@ -12,8 +12,7 @@ end
12
12
  result = RageFlip::Strikethrough.process(text)
13
13
 
14
14
  if RageFlip::Clipboard.copy(result)
15
- puts result
16
15
  else
17
16
  puts "Failed to copy to clipboard, but here's your strikethrough text:"
18
- puts result
19
- end
17
+ end
18
+ puts result
data/exe/table_flip ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/rage_flip"
4
+
5
+ text = ARGV.join(" ")
6
+
7
+ if text.empty?
8
+ puts "Usage: table_flip <text_to_flip>"
9
+ exit 1
10
+ end
11
+
12
+ # Create the table flip with classic table flip emoticons
13
+ result = RageFlip::Flipper.table_flip(text)
14
+
15
+ # Copy to clipboard
16
+ if RageFlip::Clipboard.copy(result)
17
+ else
18
+ puts "Failed to copy to clipboard, but here's your table flipped text:"
19
+ end
20
+ puts result
data/exe/underline CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/rage_flip'
3
+ require_relative "../lib/rage_flip"
4
4
 
5
- text = ARGV.join(' ')
5
+ text = ARGV.join(" ")
6
6
 
7
7
  if text.empty?
8
8
  puts "Usage: underline <text_to_underline>"
@@ -12,8 +12,7 @@ end
12
12
  result = RageFlip::Underline.single_underline(text)
13
13
 
14
14
  if RageFlip::Clipboard.copy(result)
15
- puts result
16
15
  else
17
16
  puts "Failed to copy to clipboard, but here's your underlined text:"
18
- puts result
19
- end
17
+ end
18
+ puts result
@@ -2,25 +2,25 @@ module RageFlip
2
2
  class Chaos
3
3
  DEFAULT_CHAOS_LEVEL = 10
4
4
  CHAOS_LEVEL_FILE = File.expand_path("~/.chaos_level.txt")
5
-
5
+
6
6
  def self.process(text, chaos_level = nil)
7
7
  chaos_level ||= read_chaos_level
8
-
8
+
9
9
  text.each_char.map do |c|
10
10
  combining_chars = rand(1..chaos_level).times.map do
11
11
  "%c" % rand(0x300..0x36f)
12
12
  end
13
13
  [c, combining_chars]
14
- end.flatten.join
14
+ end.join
15
15
  end
16
-
16
+
17
17
  def self.set_chaos_level(instruction)
18
18
  current_level = read_chaos_level
19
-
19
+
20
20
  case instruction
21
- when 'more'
21
+ when "more"
22
22
  new_level = current_level + 1
23
- when 'less'
23
+ when "less"
24
24
  new_level = [current_level - 1, 1].max # Don't go below 1
25
25
  else
26
26
  new_level = instruction.to_i
@@ -28,26 +28,26 @@ module RageFlip
28
28
  return "Error: Chaos level must be a positive number"
29
29
  end
30
30
  end
31
-
31
+
32
32
  write_chaos_level(new_level)
33
33
  "chaos level is now #{new_level}"
34
34
  end
35
-
35
+
36
36
  def self.read_chaos_level
37
37
  if File.exist?(CHAOS_LEVEL_FILE)
38
38
  level = File.read(CHAOS_LEVEL_FILE).strip.to_i
39
- level > 0 ? level : DEFAULT_CHAOS_LEVEL
39
+ (level > 0) ? level : DEFAULT_CHAOS_LEVEL
40
40
  else
41
41
  DEFAULT_CHAOS_LEVEL
42
42
  end
43
43
  end
44
-
44
+
45
45
  def self.write_chaos_level(level)
46
46
  File.write(CHAOS_LEVEL_FILE, level.to_s)
47
47
  end
48
-
48
+
49
49
  def self.current_chaos_level
50
50
  read_chaos_level
51
51
  end
52
52
  end
53
- end
53
+ end
@@ -22,4 +22,4 @@ module RageFlip
22
22
  true
23
23
  end
24
24
  end
25
- end
25
+ end
@@ -0,0 +1,69 @@
1
+ module RageFlip
2
+ class Emote
3
+ EMOTES = {
4
+ "disapproval" => "(ಠ_ಠ)",
5
+ "bullshit" => "🐄💩",
6
+ "catshit" => "🐱💩",
7
+ "dogshit" => "🐶💩",
8
+ "pandashit" => "🐼💩",
9
+ "horseshit" => "🐴💩",
10
+ "koalashit" => "🐨💩",
11
+ "batshit" => "🦇💩",
12
+ "bugeyes" => "(⊙_◎)",
13
+ "cmd-" => "⌘-",
14
+ "cmd" => "⌘",
15
+ "command" => "⌘",
16
+ "cntl" => "⌃",
17
+ "dogshrug" => '¯\_🐶_/¯',
18
+ "facepalm" => "(-‸ლ)",
19
+ "flip" => "(╯°□°)╯︵ ┻━┻",
20
+ "fu" => "t(-__-t)",
21
+ "heresatable" => "┬─┬ ノ( ゜-゜ノ)",
22
+ "javaflip" => "(╯°□°)╯︵ ┻ɐʌɐɾ┻",
23
+ "kungfuhamster" => " ()__()\n / o o\\ ;\n |'=Y=';-/\n { \\ / }\n mmm mmm ",
24
+ "noevil" => "🙈🙉🙊",
25
+ "omw" => "On my way!",
26
+ "optn" => "⌥",
27
+ "option" => "⌥",
28
+ "rage" => "ಠ益ಠ",
29
+ "rageflip" => "(ノಠ益ಠ)ノ彡┻━┻",
30
+ "rock" => '\m/ (>_<) \m/',
31
+ "shft" => "⇧",
32
+ "shift" => "⇧",
33
+ "shrug" => '¯\_(ツ)_/¯',
34
+ "shrugtable" => '┻━┻ ︵ ¯\(ツ)/¯ ︵ ┻━┻',
35
+ "unsee" => "♨_♨",
36
+ "yuno" => "ლ(ಠ益ಠლ)"
37
+ }.freeze
38
+
39
+ def self.process(emote_name)
40
+ emote_name = emote_name.downcase
41
+
42
+ if EMOTES.key?(emote_name)
43
+ EMOTES[emote_name]
44
+ end
45
+ end
46
+
47
+ def self.list_emotes
48
+ output = ["Available emotes:"]
49
+ # Sort emotes by name for better organization
50
+ sorted_emotes = EMOTES.sort_by { |name, _| name }
51
+
52
+ # Calculate max name length for better alignment
53
+ max_name_length = sorted_emotes.map { |name, _| name.length }.max
54
+
55
+ sorted_emotes.each do |name, emote|
56
+ output << " #{name.ljust(max_name_length + 2)} - #{emote}"
57
+ end
58
+ output.join("\n")
59
+ end
60
+
61
+ def self.emote_exists?(name)
62
+ EMOTES.key?(name.downcase)
63
+ end
64
+
65
+ def self.emote_names
66
+ EMOTES.keys
67
+ end
68
+ end
69
+ end
@@ -1,33 +1,44 @@
1
1
  module RageFlip
2
2
  class Flipper
3
3
  FORWARD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-=!@#$%^&*()_+ "
4
- BACKSIDEDOWN = " +‾()*⅋^%$#@¡=-068𝘓95ߤ↋↊⇂zʎxʍʌnʇsɹbdouɯʅʞɾᴉɥƃⅎǝpɔqɐZ⅄XϺɅՈꓕSꓤꝹԀONꟽ⅂ꓘᒋIH⅁ᖵƎᗡϽꓭ∀"
5
-
4
+ BACKSIDEDOWN = " +‾()*⅋^%$#{@¡}=-068𝘓95ߤ↋↊⇂zʎxʍʌnʇsɹbdouɯʅʞɾᴉɥƃⅎǝpɔqɐZ⅄XϺɅՈꓕSꓤꝹԀONꟽ⅂ꓘᒋIH⅁ᖵƎᗡϽꓭ∀"
5
+
6
6
  def self.flip(word)
7
7
  # Create the upside down map by reversing the backsidedown string
8
8
  upsidedown = BACKSIDEDOWN.reverse
9
-
9
+
10
10
  # Create mapping from forward to upsidedown characters
11
11
  upsidedownmap = {}
12
12
  FORWARD.each_char.with_index do |char, index|
13
13
  upsidedownmap[char] = upsidedown[index] if upsidedown[index]
14
14
  end
15
-
15
+
16
16
  # Flip the word: reverse the string and map each character
17
17
  flipped = ""
18
18
  word.each_char do |char|
19
19
  mapped_char = upsidedownmap[char] || char
20
20
  flipped = mapped_char + flipped
21
21
  end
22
-
22
+
23
23
  flipped
24
24
  end
25
-
25
+
26
26
  def self.rage_flip(text)
27
27
  rageflip_front = "(ノಠ益ಠ)ノ彡┻"
28
28
  rageflip_back = "┻"
29
-
29
+
30
30
  "#{rageflip_front}#{flip(text)}#{rageflip_back}"
31
31
  end
32
+
33
+ def self.table_flip(text)
34
+ table_flip_front = "(╯°□°)╯︵ "
35
+ table_flip_back = " ┻━┻"
36
+
37
+ "#{table_flip_front}#{flip(text)}#{table_flip_back}"
38
+ end
39
+
40
+ def self.flip_text(text)
41
+ flip(text)
42
+ end
32
43
  end
33
- end
44
+ end
@@ -5,4 +5,4 @@ module RageFlip
5
5
  text.each_char.map { |c| c.send(cycle_enum.next) }.join
6
6
  end
7
7
  end
8
- end
8
+ end
@@ -1,9 +1,9 @@
1
1
  module RageFlip
2
2
  class Strikethrough
3
3
  STRIKETHROUGH_CHAR = "\u0336"
4
-
4
+
5
5
  def self.process(text)
6
- text.each_char.map { |c| [c, STRIKETHROUGH_CHAR] }.flatten.join
6
+ text.each_char.map { |c| [c, STRIKETHROUGH_CHAR] }.join
7
7
  end
8
8
  end
9
- end
9
+ end
@@ -0,0 +1,61 @@
1
+ module RageFlip
2
+ class TextSubstitution
3
+ SUBSTITUTIONS = {
4
+ "bugeyes" => "(⊙_◎)",
5
+ "cmd-" => "⌘-",
6
+ "cmd" => "⌘",
7
+ "cntl" => "⌃",
8
+ "disapproval" => "ಠ_ಠ",
9
+ "dogshrug" => '¯\_🐶_/¯',
10
+ "duck-flip" => "(╯°□°)╯︵ ┻(duckflip)┻",
11
+ "facepalm" => "(-‸ლ)",
12
+ "flip" => "(╯°□°)╯︵ ┻━┻",
13
+ "fu" => "t(-__-t)",
14
+ "heresatable" => "┬─┬ ノ( ゜-゜ノ)",
15
+ "javaflip" => "(╯°□°)╯︵ ┻ɐʌɐɾ┻",
16
+ "kungfuhamster" => ' ()__()
17
+ / o o\ ;
18
+ |\'=Y=\';-/
19
+ { \ / }
20
+ mmm mmm ',
21
+ "noevil" => "🙈🙉🙊",
22
+ "omw" => "On my way!",
23
+ "optn" => "⌥",
24
+ "rage" => "ಠ益ಠ",
25
+ "rageflip" => "(ノಠ益ಠ)ノ彡┻━┻",
26
+ "rock" => '\m/ (>_<) \m/',
27
+ "shft" => "⇧",
28
+ "shift" => "⇧",
29
+ "shrug" => '¯\_(ツ)_/¯',
30
+ "shrugtable" => '┻━┻ ︵ ¯\(ツ)/¯ ︵ ┻━┻',
31
+ "unsee" => "♨_♨",
32
+ "yuno" => "ლ(ಠ益ಠლ)"
33
+ }.freeze
34
+
35
+ def self.process(substitution_name)
36
+ substitution_name = substitution_name.downcase
37
+
38
+ if SUBSTITUTIONS.key?(substitution_name)
39
+ SUBSTITUTIONS[substitution_name]
40
+ end
41
+ end
42
+
43
+ def self.list_substitutions
44
+ output = ["Available text substitutions:"]
45
+ SUBSTITUTIONS.each do |name, text|
46
+ # Truncate long substitutions for display
47
+ display_text = (text.length > 50) ? "#{text[0..47]}..." : text
48
+ output << " #{name.ljust(15)} - #{display_text}"
49
+ end
50
+ output.join("\n")
51
+ end
52
+
53
+ def self.substitution_exists?(name)
54
+ SUBSTITUTIONS.key?(name.downcase)
55
+ end
56
+
57
+ def self.substitution_names
58
+ SUBSTITUTIONS.keys
59
+ end
60
+ end
61
+ end