gollum_rails 0.0.2.8 → 0.0.5
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 +7 -0
- data/Gemfile +6 -4
- data/Gemfile.lock +151 -151
- data/HISTORY.md +43 -15
- data/LICENSE +661 -0
- data/README.md +75 -185
- data/Rakefile +170 -160
- data/examples/rails/initializer.rb +0 -0
- data/gollum_rails.gemspec +72 -57
- data/lib/gollum_rails.rb +35 -18
- data/lib/gollum_rails/adapters/activemodel.rb +46 -0
- data/lib/gollum_rails/adapters/activemodel/boolean.rb +15 -0
- data/lib/gollum_rails/adapters/activemodel/callback.rb +61 -0
- data/lib/gollum_rails/adapters/activemodel/error.rb +27 -0
- data/lib/gollum_rails/adapters/activemodel/naming.rb +42 -0
- data/lib/gollum_rails/adapters/activemodel/validation.rb +188 -0
- data/lib/gollum_rails/adapters/gollum.rb +61 -0
- data/lib/gollum_rails/adapters/gollum/.gitkeep +0 -0
- data/lib/gollum_rails/adapters/gollum/committer.rb +9 -0
- data/lib/gollum_rails/adapters/gollum/error.rb +19 -0
- data/lib/gollum_rails/adapters/gollum/page.rb +177 -0
- data/lib/gollum_rails/adapters/gollum/wiki.rb +43 -0
- data/lib/gollum_rails/initializer.rb +8 -0
- data/lib/gollum_rails/{hash.rb → modules/hash.rb} +33 -20
- data/lib/gollum_rails/modules/loader.rb +5 -0
- data/lib/gollum_rails/page.rb +283 -406
- data/lib/gollum_rails/setup.rb +68 -0
- metadata +56 -99
- data/LICENSE.md +0 -7
- data/lib/generators/gollum_rails/model/model_generator.rb +0 -10
- data/lib/gollum_rails/config.rb +0 -36
- data/lib/gollum_rails/dependency_injector.rb +0 -24
- data/lib/gollum_rails/engine.rb +0 -12
- data/lib/gollum_rails/file.rb +0 -9
- data/lib/gollum_rails/messages.yml +0 -8
- data/lib/gollum_rails/validations.rb +0 -10
- data/lib/gollum_rails/versions.rb +0 -79
- data/lib/gollum_rails/wiki.rb +0 -36
File without changes
|
data/gollum_rails.gemspec
CHANGED
@@ -1,57 +1,72 @@
|
|
1
|
-
Gem::Specification.new do |s|
|
2
|
-
s.rubygems_version = '1.3.5'
|
3
|
-
|
4
|
-
s.
|
5
|
-
|
6
|
-
|
7
|
-
s.
|
8
|
-
|
9
|
-
|
10
|
-
s.
|
11
|
-
|
12
|
-
|
13
|
-
s.add_dependency
|
14
|
-
s.add_dependency
|
15
|
-
|
16
|
-
s.
|
17
|
-
s.
|
18
|
-
|
19
|
-
s.add_development_dependency
|
20
|
-
s.add_development_dependency
|
21
|
-
|
22
|
-
s.
|
23
|
-
|
24
|
-
s.
|
25
|
-
s.
|
26
|
-
s.
|
27
|
-
|
28
|
-
|
29
|
-
s.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
lib/gollum_rails
|
42
|
-
lib/gollum_rails/
|
43
|
-
lib/gollum_rails/
|
44
|
-
lib/gollum_rails/
|
45
|
-
lib/gollum_rails/
|
46
|
-
lib/gollum_rails/
|
47
|
-
lib/gollum_rails/
|
48
|
-
lib/gollum_rails/
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.rubygems_version = '>= 1.3.5'
|
3
|
+
|
4
|
+
s.name = 'gollum_rails'
|
5
|
+
s.rubyforge_project = s.name
|
6
|
+
|
7
|
+
s.version = '0.0.5'
|
8
|
+
|
9
|
+
s.summary = 'Combines the benefits from Gollum and Rails'
|
10
|
+
s.description= 'Use all the benefits from Rails and combine them with the awesome Gollum wiki'
|
11
|
+
#File.read(File.join(File.dirname(__FILE__), 'README.md'))
|
12
|
+
|
13
|
+
s.add_dependency 'activemodel', '~> 3.2.13'
|
14
|
+
s.add_dependency 'gollum-lib', '~> 0.0.1'
|
15
|
+
#s.add_dependency 'grit', '~> 2.5.0'
|
16
|
+
s.add_dependency 'builder', '~> 3.0.0'
|
17
|
+
s.add_dependency 'rack', '~> 1.4.5'
|
18
|
+
|
19
|
+
s.add_development_dependency 'rspec', '~> 2.13.0'
|
20
|
+
s.add_development_dependency 'rails', '~> 3.2.13'
|
21
|
+
s.add_development_dependency 'rr', '~> 1.0.4'
|
22
|
+
s.add_development_dependency 'rails', '~> 3.2.13'
|
23
|
+
|
24
|
+
s.author = 'Florian Kasper'
|
25
|
+
s.email = 'mosny@zyg.li'
|
26
|
+
s.homepage = 'http://gollum.zyg.li'
|
27
|
+
s.license = 'AGPL'
|
28
|
+
s.platform = Gem::Platform::RUBY
|
29
|
+
s.required_ruby_version = '>=1.9.3'
|
30
|
+
|
31
|
+
# = MANIFEST =
|
32
|
+
s.files = %w[
|
33
|
+
Gemfile
|
34
|
+
Gemfile.lock
|
35
|
+
HISTORY.md
|
36
|
+
LICENSE
|
37
|
+
README.md
|
38
|
+
Rakefile
|
39
|
+
examples/rails/initializer.rb
|
40
|
+
gollum_rails.gemspec
|
41
|
+
lib/gollum_rails.rb
|
42
|
+
lib/gollum_rails/adapters/activemodel.rb
|
43
|
+
lib/gollum_rails/adapters/activemodel/boolean.rb
|
44
|
+
lib/gollum_rails/adapters/activemodel/callback.rb
|
45
|
+
lib/gollum_rails/adapters/activemodel/error.rb
|
46
|
+
lib/gollum_rails/adapters/activemodel/naming.rb
|
47
|
+
lib/gollum_rails/adapters/activemodel/validation.rb
|
48
|
+
lib/gollum_rails/adapters/gollum.rb
|
49
|
+
lib/gollum_rails/adapters/gollum/.gitkeep
|
50
|
+
lib/gollum_rails/adapters/gollum/committer.rb
|
51
|
+
lib/gollum_rails/adapters/gollum/error.rb
|
52
|
+
lib/gollum_rails/adapters/gollum/page.rb
|
53
|
+
lib/gollum_rails/adapters/gollum/wiki.rb
|
54
|
+
lib/gollum_rails/initializer.rb
|
55
|
+
lib/gollum_rails/modules/hash.rb
|
56
|
+
lib/gollum_rails/modules/loader.rb
|
57
|
+
lib/gollum_rails/page.rb
|
58
|
+
lib/gollum_rails/setup.rb
|
59
|
+
]
|
60
|
+
# = MANIFEST =
|
61
|
+
|
62
|
+
|
63
|
+
s.require_paths = %w[lib]
|
64
|
+
s.post_install_message = "Important: \n\n" \
|
65
|
+
"**********************************************\n\n" \
|
66
|
+
"To use the 'autoinitializer' just run the following command:\n\n"\
|
67
|
+
"\t\trails g gollum_rails:install\n\n"\
|
68
|
+
"To generate a new Page model just run:\n\n"\
|
69
|
+
"\t\rails g gollum_rails:model MODEL_NAME"\
|
70
|
+
"**********************************************"
|
71
|
+
end
|
72
|
+
|
data/lib/gollum_rails.rb
CHANGED
@@ -1,18 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
require 'gollum-lib'
|
3
|
+
|
4
|
+
# GollumRails is a RubyGem for extending Rails and the Gollum wiki powered by github
|
5
|
+
# It has the ability to combine the benefits from a git powered wiki with Rails.
|
6
|
+
#
|
7
|
+
# Example solutions:
|
8
|
+
# * Gollum Wiki pages - Devise authentication - GollumRails connector - Haml layouting
|
9
|
+
# * Gollum Wiki pages - Ember.js - Handlebars layout - Rails REST API
|
10
|
+
# * ...
|
11
|
+
#
|
12
|
+
module GollumRails
|
13
|
+
|
14
|
+
# GollumRails version string
|
15
|
+
VERSION = '0.0.5'
|
16
|
+
|
17
|
+
# Simplified error
|
18
|
+
class Error < StandardError; end
|
19
|
+
|
20
|
+
# For use with internal gollumGem exceptions
|
21
|
+
#
|
22
|
+
class GollumInternalError < Error
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
require File.expand_path '../gollum_rails/adapters/activemodel', __FILE__
|
29
|
+
require File.expand_path '../gollum_rails/adapters/gollum', __FILE__
|
30
|
+
require File.expand_path '../gollum_rails/setup', __FILE__
|
31
|
+
require File.expand_path '../gollum_rails/page', __FILE__
|
32
|
+
# load extensions
|
33
|
+
require File.expand_path '../gollum_rails/modules/loader', __FILE__
|
34
|
+
|
35
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
module GollumRails
|
3
|
+
|
4
|
+
# Adapter class. To be documented
|
5
|
+
module Adapters
|
6
|
+
|
7
|
+
# ActiveModel improvements and own connectors
|
8
|
+
#
|
9
|
+
# including:
|
10
|
+
# * validation
|
11
|
+
# * callbacks
|
12
|
+
# * naming
|
13
|
+
# * error handling
|
14
|
+
#
|
15
|
+
# The following files are involved:
|
16
|
+
# * boolean.rb -> Boolean features for validation
|
17
|
+
# * callback.rb -> Callback functionality
|
18
|
+
# * naming.rb -> Conversion and Naming
|
19
|
+
# * error.rb -> Active Model error handling
|
20
|
+
# * validation.rb -> Object validation
|
21
|
+
#
|
22
|
+
# Released under the AGPL License. For further information see the LICENSE file distributed
|
23
|
+
# with this package.
|
24
|
+
#
|
25
|
+
# TODO:
|
26
|
+
# * a lot of testing
|
27
|
+
# * implementing the rest of the error class
|
28
|
+
# * deleting the model template out
|
29
|
+
# * move into own gem
|
30
|
+
#
|
31
|
+
# FIXME:
|
32
|
+
# none a.t.m.
|
33
|
+
#
|
34
|
+
module ActiveModel
|
35
|
+
|
36
|
+
# connector version
|
37
|
+
VERSION="0.0.4"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
require File.expand_path '../activemodel/boolean', __FILE__
|
43
|
+
require File.expand_path '../activemodel/callback', __FILE__
|
44
|
+
require File.expand_path '../activemodel/naming', __FILE__
|
45
|
+
require File.expand_path '../activemodel/error', __FILE__
|
46
|
+
require File.expand_path '../activemodel/validation', __FILE__
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module GollumRails
|
2
|
+
module Adapters
|
3
|
+
module ActiveModel
|
4
|
+
|
5
|
+
# Own implemented Boolean method for validating
|
6
|
+
module Boolean; end
|
7
|
+
|
8
|
+
# inherit
|
9
|
+
class ::TrueClass; include Boolean; end
|
10
|
+
|
11
|
+
# inherit
|
12
|
+
class ::FalseClass; include Boolean; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module GollumRails
|
2
|
+
module Adapters
|
3
|
+
module ActiveModel
|
4
|
+
|
5
|
+
# Callback handling class
|
6
|
+
class Callback
|
7
|
+
extend ::ActiveModel::Callbacks
|
8
|
+
|
9
|
+
define_model_callbacks :create, :only => [:after, :before]
|
10
|
+
define_model_callbacks :update, :only => [:after, :before]
|
11
|
+
define_model_callbacks :save, :only => [:after, :before]
|
12
|
+
define_model_callbacks :delete, :only => [:after, :before]
|
13
|
+
define_model_callbacks :find, :only => [:after, :before]
|
14
|
+
|
15
|
+
before_create :before_create
|
16
|
+
before_update :before_update
|
17
|
+
before_save :before_save
|
18
|
+
before_delete :before_delete
|
19
|
+
before_find :before_find
|
20
|
+
|
21
|
+
after_create :after_create
|
22
|
+
after_update :after_update
|
23
|
+
after_save :after_save
|
24
|
+
after_delete :after_delete
|
25
|
+
after_find :after_find
|
26
|
+
|
27
|
+
# Before create action
|
28
|
+
def before_create; end
|
29
|
+
|
30
|
+
# Before update action
|
31
|
+
def before_update; end
|
32
|
+
|
33
|
+
# Before save action
|
34
|
+
def before_save; end
|
35
|
+
|
36
|
+
# Before delete action
|
37
|
+
def before_delete; end
|
38
|
+
|
39
|
+
# Before find action
|
40
|
+
def before_find; end
|
41
|
+
|
42
|
+
# After create action
|
43
|
+
def after_create; end
|
44
|
+
|
45
|
+
# After update action
|
46
|
+
def after_update; end
|
47
|
+
|
48
|
+
# After save action
|
49
|
+
def after_save; end
|
50
|
+
|
51
|
+
# After delete action
|
52
|
+
def after_delete; end
|
53
|
+
|
54
|
+
# After find action
|
55
|
+
def after_find; end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module GollumRails
|
2
|
+
module Adapters
|
3
|
+
module ActiveModel
|
4
|
+
|
5
|
+
# Error handling class, with several exception types and debug / info messages
|
6
|
+
class Error < ::GollumRails::GollumInternalError
|
7
|
+
extend ::ActiveModel::Naming
|
8
|
+
|
9
|
+
######
|
10
|
+
public
|
11
|
+
######
|
12
|
+
|
13
|
+
# Gets/Sets the Error
|
14
|
+
attr_reader :errors
|
15
|
+
|
16
|
+
# Initializes a new Exception
|
17
|
+
#
|
18
|
+
def initialize(name, message = nil, priority = :crit)
|
19
|
+
super("Error thrown: #{name},\n\n #{(message)}")
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module GollumRails
|
3
|
+
module Adapters
|
4
|
+
module ActiveModel
|
5
|
+
|
6
|
+
# Naming class for all Classes, extending the AdtiveModel::Naming module
|
7
|
+
#
|
8
|
+
# provides base functionality like filenames, classnames, variable-, instancenames
|
9
|
+
module Naming
|
10
|
+
|
11
|
+
# Outputs the currents class name
|
12
|
+
#
|
13
|
+
# Returns a String
|
14
|
+
def class_name
|
15
|
+
self.class.name
|
16
|
+
end
|
17
|
+
|
18
|
+
# Gets the pluralized filename for an object
|
19
|
+
#
|
20
|
+
# Returns a String
|
21
|
+
def plural_filename_for_class(name)
|
22
|
+
return ::ActiveModel::Naming.plural name if name.model_name
|
23
|
+
return nil
|
24
|
+
end
|
25
|
+
|
26
|
+
# Gets the singularized filename for an object
|
27
|
+
#
|
28
|
+
# Returns a String
|
29
|
+
def singular_filename_for_class(name)
|
30
|
+
return ::ActiveModel::Naming.singular name if name.model_name
|
31
|
+
return nil
|
32
|
+
end
|
33
|
+
|
34
|
+
# dummy namespace class
|
35
|
+
class NameSpace
|
36
|
+
extend ::ActiveModel::Naming
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module GollumRails
|
2
|
+
module Adapters
|
3
|
+
module ActiveModel
|
4
|
+
|
5
|
+
# General Validation Class including validations
|
6
|
+
class Validation
|
7
|
+
include ::ActiveModel::Validations
|
8
|
+
|
9
|
+
#########
|
10
|
+
protected
|
11
|
+
#########
|
12
|
+
|
13
|
+
# Sets the variable, used to validate
|
14
|
+
attr_writer :variable
|
15
|
+
|
16
|
+
# Sets the Filter
|
17
|
+
attr_accessor :filter
|
18
|
+
|
19
|
+
# Sets all instance errors to this variable
|
20
|
+
attr_writer :error
|
21
|
+
|
22
|
+
######
|
23
|
+
public
|
24
|
+
######
|
25
|
+
|
26
|
+
# Gets the variable, used to validate
|
27
|
+
attr_reader :variable
|
28
|
+
|
29
|
+
# Gets the error messages
|
30
|
+
attr_reader :error
|
31
|
+
|
32
|
+
# Checks for errors and returns either true or false
|
33
|
+
#
|
34
|
+
# Examples:
|
35
|
+
# @validator.valid?
|
36
|
+
# # => true
|
37
|
+
# or
|
38
|
+
# # => false
|
39
|
+
#
|
40
|
+
def valid?(errors = {})
|
41
|
+
super
|
42
|
+
return true if self.errors.messages == Hash.new and errors == Hash.new
|
43
|
+
self.error = errors
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
|
47
|
+
# Initializes the Validator
|
48
|
+
# You can pass in a block with validators, which will be used to validate given attributes
|
49
|
+
#
|
50
|
+
# Blocks look like:
|
51
|
+
#
|
52
|
+
# "#{variable} : type=String : max=200"
|
53
|
+
# "#{textvariable} : type=Hash"
|
54
|
+
# "#{integer} : min=100 : max=200"
|
55
|
+
#
|
56
|
+
# They have always the following format:
|
57
|
+
#
|
58
|
+
# KEY=VALUE or KEY!VALUE
|
59
|
+
#
|
60
|
+
# key=value explains itself. It validates the variable <b>variable</b> with the given <b>key<b> validator
|
61
|
+
# and checks if it matches the given <b>value</b>
|
62
|
+
#
|
63
|
+
# key!value is the negociation of key=value
|
64
|
+
#
|
65
|
+
#
|
66
|
+
# The following keys are currently available:
|
67
|
+
# * type
|
68
|
+
# * max
|
69
|
+
# * present
|
70
|
+
# * min
|
71
|
+
#
|
72
|
+
# Following:
|
73
|
+
# * contribute yourself
|
74
|
+
#
|
75
|
+
# Usage:
|
76
|
+
# variable = "This is a simple test"
|
77
|
+
# validator = GollumRails::Adapters::ActiveModel::Validation.new
|
78
|
+
# validator.validate! do |a|
|
79
|
+
# a.validate(variable, "type=String,max=100,present=true")
|
80
|
+
# end
|
81
|
+
# validator.valid?
|
82
|
+
# # => true
|
83
|
+
#
|
84
|
+
# Params:
|
85
|
+
# block - Block to use
|
86
|
+
#
|
87
|
+
# Returns:
|
88
|
+
def validate(&block)
|
89
|
+
bla = block.call(self)
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# Aliasing test method
|
94
|
+
alias_method :validate!, :test
|
95
|
+
|
96
|
+
# Tests given variable for conditions
|
97
|
+
#
|
98
|
+
# Params:
|
99
|
+
# variable - variable to validate
|
100
|
+
# statement - validation statement, seperated by coma
|
101
|
+
#
|
102
|
+
#
|
103
|
+
def test(variable,statement)
|
104
|
+
validation = {}
|
105
|
+
if statement.include? ',' and statement.include? '='
|
106
|
+
statement.split(',').each{|equalized|
|
107
|
+
key,value = split_equalized_string equalized
|
108
|
+
validation[key.to_s.downcase.to_sym] = value if not key.nil?
|
109
|
+
}
|
110
|
+
elsif statement.include? '='
|
111
|
+
key,value = split_equalized_string statement
|
112
|
+
validation[key.to_s.downcase.to_sym] = value if not key.nil?
|
113
|
+
else
|
114
|
+
raise Error, 'Syntax error! '
|
115
|
+
end
|
116
|
+
self.instance_variable_set("@variable", variable)
|
117
|
+
|
118
|
+
validation.each_with_index do |k|
|
119
|
+
if k.first.to_s.match /^type$/i
|
120
|
+
code = <<-END
|
121
|
+
self.singleton_class.class_exec do attr_accessor :type end
|
122
|
+
self.instance_variable_set("@type", "#{k[1]}")
|
123
|
+
validates_with ValidateType, :fields => [:variable]
|
124
|
+
END
|
125
|
+
elsif k.first.to_s.match /^(present|presence|pres)$/i
|
126
|
+
code = <<-END
|
127
|
+
validates_presence_of :variable
|
128
|
+
END
|
129
|
+
elsif k.first.to_s.match /^(min|max)$/i
|
130
|
+
code = <<-END
|
131
|
+
validates_length_of :variable, :#{k.first.to_s}imum => #{k[1].to_i}
|
132
|
+
END
|
133
|
+
else
|
134
|
+
puts <<-END
|
135
|
+
WARNING: no validator matches! This will cause an Error in the next release
|
136
|
+
END
|
137
|
+
next
|
138
|
+
end
|
139
|
+
self.instance_eval(code) if code
|
140
|
+
end
|
141
|
+
errors = self.errors.messages
|
142
|
+
self.errors.instance_variable_set("@messages", {})
|
143
|
+
valid? errors
|
144
|
+
end
|
145
|
+
|
146
|
+
#######
|
147
|
+
private
|
148
|
+
#######
|
149
|
+
|
150
|
+
# Splits given by "="
|
151
|
+
#
|
152
|
+
# string - String to be split
|
153
|
+
#
|
154
|
+
# Returns splitted string or raise an error
|
155
|
+
def split_equalized_string(string)
|
156
|
+
if string.match /\w+\=(\w+|\d+)/i
|
157
|
+
return string.split(/\=/,2)
|
158
|
+
else
|
159
|
+
raise Error, <<-END
|
160
|
+
Syntax error in given String #{string}. Equal sign is missing
|
161
|
+
END
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
# Validation helper for type:
|
169
|
+
#
|
170
|
+
# <b>Type</b>
|
171
|
+
class ValidateType < ::ActiveModel::Validator
|
172
|
+
|
173
|
+
# Validate given Data with given validation object
|
174
|
+
#
|
175
|
+
# sets error or returns true
|
176
|
+
def validate(record)
|
177
|
+
if record.type.match(/^\w+$/i)
|
178
|
+
name = eval "#{record.type.to_s}"
|
179
|
+
return true if record.variable.is_a? name
|
180
|
+
record.errors.add :type, "not a kind of given class #{record.type}"
|
181
|
+
else
|
182
|
+
record.errors.add :type ,"invalid input detected"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|