assoc_whisperer 1.2.1 → 2.0.1
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 +4 -4
- data/app/assets/javascripts/assoc_whisp.js +48 -46
- data/app/helpers/action_view/helpers/assoc_whisperer_helper.rb +16 -41
- data/app/helpers/action_view/helpers/tags/assoc_whisperer_field.rb +13 -32
- data/app/views/assoc_whisperer/list.html.erb +2 -2
- data/lib/assoc_whisperer/template.rb +39 -22
- data/lib/assoc_whisperer/version.rb +1 -1
- data/lib/assoc_whisperer.rb +4 -17
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c12d3a84dff2b3fcedf60c2abd790d235626c566
|
4
|
+
data.tar.gz: aacfc5036d39c470b1301cc6b7f853f0dded41d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 760054c15cc9fc0aea5357f11db45cfb81e5245a3747f574ba6fccc1abeb3a50aac045d17a08e26a09122f238e5744ea18239fb4775977ef388cc82bc481c9ce
|
7
|
+
data.tar.gz: 6309409f36c8087a4460dc542eaaf2b3d05fa1850f0df4cd5f2d20a4dd145eb97812a5cd4eafb542d946b9f9658576e0233bfb9c0f4917f75e33d0c45939c3bc
|
@@ -15,7 +15,7 @@ document.AssocWhisperer = (function () {
|
|
15
15
|
|
16
16
|
// This is where Whisperer Object is created - with all hidden inner methods.
|
17
17
|
function createWhisperer(dom_node) {
|
18
|
-
var el, w,
|
18
|
+
var el, w, opts, _nodes, _timer;
|
19
19
|
|
20
20
|
el = $(dom_node);
|
21
21
|
_nodes = {
|
@@ -25,22 +25,25 @@ document.AssocWhisperer = (function () {
|
|
25
25
|
list: null
|
26
26
|
};
|
27
27
|
opts = el.data('opts');
|
28
|
-
if (!opts['action']) throw 'Missing action in '+JSON.stringify(opts);
|
29
|
-
if (!opts['url']) throw 'Missing url in '+JSON.stringify(opts);
|
28
|
+
if (!opts['action']) throw 'Missing action path in '+JSON.stringify(opts);
|
30
29
|
if (typeof opts['params']!=='object') opts['params'] = {};
|
30
|
+
// opts['cs'] = parseInt(opts['cs']);
|
31
31
|
|
32
32
|
w = Object.create(proto, {
|
33
33
|
nodes: {value: _nodes},
|
34
|
-
action: {value: opts['action']},
|
35
|
-
url: {value: opts['url']},
|
36
|
-
params: {value: opts['params']},
|
37
34
|
focused: {value: false, writable: true},
|
38
35
|
filled: {value: _nodes['value_field'].val()!=='', writable: true},
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
// setting
|
37
|
+
action: {value: opts['action']},
|
38
|
+
params: {value: opts['params']}
|
42
39
|
});
|
43
|
-
|
40
|
+
// if (!isNaN(opts['cs'])) {
|
41
|
+
// // client side
|
42
|
+
// Object.defineProperties({
|
43
|
+
// client_side: {value: opts['cs']},
|
44
|
+
// full_data: {value: null, writable: true}
|
45
|
+
// });
|
46
|
+
// }
|
44
47
|
|
45
48
|
_nodes.text_field.on('keyup', function(e){
|
46
49
|
var input_text;
|
@@ -67,11 +70,11 @@ document.AssocWhisperer = (function () {
|
|
67
70
|
}
|
68
71
|
_timer = setTimeout(function () {
|
69
72
|
if (w.client_side) {
|
70
|
-
if (!w.full_data) query(w, null, function (html_text) {
|
71
|
-
w.full_data = $(html_text);
|
72
|
-
showList(digest(input_text));
|
73
|
-
});
|
74
|
-
else showList(digest(input_text));
|
73
|
+
// if (!w.full_data) query(w, null, function (html_text) {
|
74
|
+
// w.full_data = $(html_text);
|
75
|
+
// showList(digest(input_text));
|
76
|
+
// });
|
77
|
+
// else showList(digest(input_text));
|
75
78
|
}
|
76
79
|
else query(w, input_text, function (html_text) {
|
77
80
|
showList($(html_text));
|
@@ -86,20 +89,20 @@ document.AssocWhisperer = (function () {
|
|
86
89
|
var f;
|
87
90
|
if (_timer) clearTimeout(_timer);
|
88
91
|
if (w.client_side) {
|
89
|
-
f = function () {
|
90
|
-
var input_text;
|
91
|
-
if (w.filled) showList(w.full_data);
|
92
|
-
else {
|
93
|
-
input_text = _nodes['text_field'].val();
|
94
|
-
showList(digest(input_text==='' ? null : input_text));
|
95
|
-
}
|
96
|
-
_nodes['list'].focus();
|
97
|
-
};
|
98
|
-
if (!w.full_data) query(w, null, function (html_text) {
|
99
|
-
w.full_data = $(html_text);
|
100
|
-
f();
|
101
|
-
});
|
102
|
-
else f();
|
92
|
+
// f = function () {
|
93
|
+
// var input_text;
|
94
|
+
// if (w.filled) showList(w.full_data);
|
95
|
+
// else {
|
96
|
+
// input_text = _nodes['text_field'].val();
|
97
|
+
// showList(digest(input_text==='' ? null : input_text));
|
98
|
+
// }
|
99
|
+
// _nodes['list'].focus();
|
100
|
+
// };
|
101
|
+
// if (!w.full_data) query(w, null, function (html_text) {
|
102
|
+
// w.full_data = $(html_text);
|
103
|
+
// f();
|
104
|
+
// });
|
105
|
+
// else f();
|
103
106
|
}
|
104
107
|
else {
|
105
108
|
query(w, (w.filled ? null : _nodes['text_field'].val()), function (html_text) {
|
@@ -110,19 +113,19 @@ document.AssocWhisperer = (function () {
|
|
110
113
|
});
|
111
114
|
el.children('.dropdown_button').removeClass('querying'); // css class is set, hence gif gets pre-loaded
|
112
115
|
|
113
|
-
// For local full_data finds matching rows and shows them.
|
114
|
-
function digest(input_text) {
|
115
|
-
var narrowed_list = w.full_data;
|
116
|
-
if (input_text && input_text!=='') {
|
117
|
-
input_text = input_text.toLowerCase();
|
118
|
-
narrowed_list = $(narrowed_list[0].cloneNode());
|
119
|
-
w.full_data.children().each(function () {
|
120
|
-
if (this.innerText.toLowerCase().indexOf(input_text)!==-1)
|
121
|
-
narrowed_list.append($(this).clone());
|
122
|
-
});
|
123
|
-
}
|
124
|
-
return narrowed_list;
|
125
|
-
}
|
116
|
+
// // For local full_data finds matching rows and shows them.
|
117
|
+
// function digest(input_text) {
|
118
|
+
// var narrowed_list = w.full_data;
|
119
|
+
// if (input_text && input_text!=='') {
|
120
|
+
// input_text = input_text.toLowerCase();
|
121
|
+
// narrowed_list = $(narrowed_list[0].cloneNode());
|
122
|
+
// w.full_data.children().each(function () {
|
123
|
+
// if (this.innerText.toLowerCase().indexOf(input_text)!==-1)
|
124
|
+
// narrowed_list.append($(this).clone());
|
125
|
+
// });
|
126
|
+
// }
|
127
|
+
// return narrowed_list;
|
128
|
+
// }
|
126
129
|
|
127
130
|
// Attaches a List sent by html string within Whisperer's tag. Positions it underneath the text field.
|
128
131
|
function showList (list) {
|
@@ -187,8 +190,8 @@ document.AssocWhisperer = (function () {
|
|
187
190
|
klass.querying = true;
|
188
191
|
btn = w.nodes['base'].find('.dropdown_button');
|
189
192
|
btn.addClass('querying');
|
190
|
-
w.params['input'] = input
|
191
|
-
$.ajax(w.
|
193
|
+
w.params['input'] = input;
|
194
|
+
$.ajax(w.action, {
|
192
195
|
type: 'GET',
|
193
196
|
dataType: 'html',
|
194
197
|
data: w.params,
|
@@ -206,7 +209,6 @@ document.AssocWhisperer = (function () {
|
|
206
209
|
// public interface //
|
207
210
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
208
211
|
|
209
|
-
|
210
212
|
klass = Object.create(Object, {querying: {value: false, writable: true}});
|
211
213
|
|
212
214
|
// Return a Whisperer instance by its data-action attribute.
|
@@ -214,7 +216,7 @@ document.AssocWhisperer = (function () {
|
|
214
216
|
var i, w;
|
215
217
|
for (i = 0; i < all_array.length; i += 1) {
|
216
218
|
w = all_array[i];
|
217
|
-
if (w.action===action) return w;
|
219
|
+
if (w.params['action']===action || w.action.indexOf(action)!==-1) return w;
|
218
220
|
}
|
219
221
|
return null;
|
220
222
|
}
|
@@ -3,54 +3,29 @@ module ActionView
|
|
3
3
|
|
4
4
|
module AssocWhispererHelper
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# ==== Examples
|
10
|
-
# assoc_whisperer :task, :worker, :workers, size: 25, url: '/whisp'
|
11
|
-
# # => <span class="assoc_whisperer" data-action="workers" data-url="/whisp">
|
12
|
-
# <input class="value_field" id="task_worker_id" name="task[worker_id]" type="hidden" value="">
|
13
|
-
# <input autocomplete="off" class="text_field unfilled" id="task_worker_txt" name="task[worker_txt]" size="25" type="text" value="">
|
14
|
-
# <span class="dropdown_button">▾</span></span>
|
15
|
-
#
|
16
|
-
# Let's say your association looks like this:
|
17
|
-
#
|
18
|
-
# class Task
|
19
|
-
# belongs_to :worker, class_name: 'Worker', foreign_key: :manager
|
20
|
-
# end
|
21
|
-
# class Worker
|
22
|
-
# def full_name; end
|
23
|
-
# def manager_id; end
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# assoc_whisperer :task, :worker, :workers, name: :manager, value_method: :manager_id, text_method: :full_name
|
27
|
-
# # => <span class="assoc_whisperer" data-action="workers" data-url="">
|
28
|
-
# <input class="value_field" id="task_manager" name="task[manager]" type="hidden" value="">
|
29
|
-
# <input autocomplete="off" class="text_field unfilled" id="task_manager_txt" name="task[manager_txt]" size="12" type="text" value="">
|
30
|
-
# <span class="dropdown_button">▾</span></span>
|
31
|
-
#
|
32
|
-
# And the 'value_field' would be filled by +manager_id+ of +worker+ associated to +task+, 'text_field' by his +full_name+
|
33
|
-
#
|
34
|
-
def assoc_whisperer(object_name, method, data_action, options={})
|
35
|
-
raise "Helper '#assoc_whisperer' is for Rails >= 4.x. Use '#assoc_whisperer_tag' instead." if Rails::VERSION::STRING.to_i < 4
|
36
|
-
wrapper_assoc_whisperer_assets
|
6
|
+
def whisperer(object_name, method, template, field_attrs={})
|
7
|
+
raise "Helper '#whisperer' cannot be used in Rails < 4.x. Use '#whisperer_tag' instead." if Rails::VERSION::STRING.to_i < 4
|
8
|
+
wrapper_whisperer_assets
|
37
9
|
|
38
|
-
Tags::AssocWhispererField.new(object_name, method, self,
|
10
|
+
Tags::AssocWhispererField.new(object_name, method, self, template, field_attrs).render
|
39
11
|
end
|
40
12
|
|
41
|
-
def
|
42
|
-
|
13
|
+
def whisperer_tag(name, template, field_attrs={})
|
14
|
+
wrapper_whisperer_assets
|
43
15
|
|
44
|
-
|
45
|
-
|
46
|
-
|
16
|
+
content_tag :span, template.tag_contents(name, field_attrs).html_safe, 'class' => 'assoc_whisperer',
|
17
|
+
'data-opts' => template.whisperer_settings.to_json
|
18
|
+
end
|
19
|
+
|
20
|
+
def whisperer_template(action, opts={})
|
21
|
+
AssocWhisperer::Template.new action, opts
|
47
22
|
end
|
48
23
|
|
49
24
|
private
|
50
25
|
|
51
|
-
def
|
26
|
+
def wrapper_whisperer_assets
|
52
27
|
unless @assoc_whisp_attached
|
53
|
-
attach_method = AssocWhisperer.
|
28
|
+
attach_method = AssocWhisperer.attach_assets
|
54
29
|
self.send attach_method if attach_method && self.respond_to?(attach_method)
|
55
30
|
@assoc_whisp_attached = true
|
56
31
|
end
|
@@ -59,8 +34,8 @@ module ActionView
|
|
59
34
|
end
|
60
35
|
|
61
36
|
class FormBuilder
|
62
|
-
def
|
63
|
-
@template.assoc_whisperer @object_name, method,
|
37
|
+
def whisperer(method, template, field_attrs={})
|
38
|
+
@template.assoc_whisperer @object_name, method, template, objectify_options(field_attrs)
|
64
39
|
end
|
65
40
|
end
|
66
41
|
|
@@ -3,20 +3,20 @@ module ActionView
|
|
3
3
|
module Tags # :nodoc:
|
4
4
|
class AssocWhispererField < Base # :nodoc:
|
5
5
|
|
6
|
-
def initialize(object_name, method_name, template_object,
|
7
|
-
|
8
|
-
options[:text_method] = AssocWhisperer.def_text_method unless options.has_key? :text_method
|
6
|
+
def initialize(object_name, method_name, template_object, whisp_template, options={})
|
7
|
+
@whisp_template = whisp_template
|
9
8
|
super object_name, method_name, template_object, options
|
10
|
-
@template = AssocWhisperer::Template.new action, @options
|
11
9
|
end
|
12
10
|
|
13
11
|
def render
|
14
|
-
|
15
|
-
|
16
|
-
contents
|
12
|
+
@whisp_template.value_text whispered_object
|
13
|
+
|
14
|
+
contents = @whisp_template.value_field_tag value_tag_id, value_tag_name
|
15
|
+
contents += @whisp_template.text_field_tag text_tag_id, text_tag_name, @options
|
16
|
+
contents += @whisp_template.dropdown_button_tag
|
17
17
|
|
18
18
|
content_tag :span, contents.html_safe, 'class' => 'assoc_whisperer',
|
19
|
-
'data-opts' => @
|
19
|
+
'data-opts' => @whisp_template.whisperer_settings.to_json
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
@@ -25,11 +25,6 @@ module ActionView
|
|
25
25
|
@whispered_object ||= value @object
|
26
26
|
end
|
27
27
|
|
28
|
-
def whispered_object_attribute(method)
|
29
|
-
wo = whispered_object
|
30
|
-
wo.send method if wo && wo.respond_to?(method)
|
31
|
-
end
|
32
|
-
|
33
28
|
def text_tag_name
|
34
29
|
"#{@object_name}[#{text_sanitized_method_name}]"
|
35
30
|
end
|
@@ -38,18 +33,8 @@ module ActionView
|
|
38
33
|
"#{sanitized_object_name}_#{text_sanitized_method_name}"
|
39
34
|
end
|
40
35
|
|
41
|
-
def text_tag_value
|
42
|
-
text = @template.opts[:text_method]
|
43
|
-
text = if text.respond_to? :call
|
44
|
-
text.call whispered_object
|
45
|
-
else
|
46
|
-
whispered_object_attribute(text)
|
47
|
-
end
|
48
|
-
ERB::Util.html_escape text
|
49
|
-
end
|
50
|
-
|
51
36
|
def text_sanitized_method_name
|
52
|
-
@text_sanitized_method_name ||= "#{@
|
37
|
+
@text_sanitized_method_name ||= "#{@whisp_template.opts[:name] || @method_name}_txt".sub(/\?$/,"")
|
53
38
|
end
|
54
39
|
|
55
40
|
def value_tag_name
|
@@ -60,18 +45,14 @@ module ActionView
|
|
60
45
|
"#{sanitized_object_name}_#{value_sanitized_method_name}"
|
61
46
|
end
|
62
47
|
|
63
|
-
def value_tag_value
|
64
|
-
whispered_object_attribute @template.opts[:value_method]
|
65
|
-
end
|
66
|
-
|
67
48
|
def value_sanitized_method_name
|
68
49
|
return @value_sanitized_method_name if defined? @value_sanitized_method_name
|
69
|
-
|
70
|
-
@
|
50
|
+
name = if @whisp_template.opts[:name]
|
51
|
+
@whisp_template.opts[:name].to_s
|
71
52
|
else
|
72
|
-
"#{@method_name}_#{@template.opts[:
|
53
|
+
"#{@method_name}_#{@template.opts[:value]}"
|
73
54
|
end
|
74
|
-
@value_sanitized_method_name =
|
55
|
+
@value_sanitized_method_name = name.sub(/\?$/, '')
|
75
56
|
end
|
76
57
|
|
77
58
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<%
|
2
2
|
text_method = local_assigns[:text] || :to_s
|
3
|
-
|
3
|
+
value_method = local_assigns[:value] || :id
|
4
4
|
%>
|
5
5
|
<div tabindex=0 class="list">
|
6
6
|
<% @objects.each do |o| %>
|
7
|
-
<div data-value="<%= o.send
|
7
|
+
<div data-value="<%= o.send value_method %>"><%= o.send text_method %></div>
|
8
8
|
<% end %>
|
9
9
|
</div>
|
@@ -2,47 +2,64 @@
|
|
2
2
|
|
3
3
|
module AssocWhisperer
|
4
4
|
class Template
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :opts
|
6
6
|
|
7
7
|
def initialize(action, opts={})
|
8
|
-
@action = action
|
8
|
+
@action = action[0]=='/' ? action : "#{AssocWhisperer.def_url}/#{action}"
|
9
9
|
@opts = opts
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
12
|
+
def params(params)
|
13
|
+
@params = params
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def value_text(object_or_params, name=nil)
|
18
|
+
if object_or_params.is_a?(Hash) && name
|
19
|
+
@value = object_or_params[name]
|
20
|
+
@text = object_or_params["#{name}_txt"]
|
21
|
+
elsif object_or_params
|
22
|
+
value = @opts[:value] || AssocWhisperer.def_value
|
23
|
+
text = @opts[:text] || AssocWhisperer.def_text
|
24
|
+
@value = (object_or_params.send value if object_or_params.respond_to? value)
|
25
|
+
@text = (object_or_params.send text if object_or_params.respond_to? text)
|
26
|
+
else
|
27
|
+
@value = nil
|
28
|
+
@text = nil
|
29
|
+
end
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def tag_contents(input_name, field_attrs={})
|
13
34
|
input_name = input_name.to_s
|
14
35
|
sanitized_id = input_name.dup.delete(']').gsub(/[^-a-zA-Z0-9:.]/, "_")
|
15
36
|
text_tag_name = input_name.dup
|
16
37
|
text_tag_name.insert (text_tag_name[-1]==']' ? -2 : -1), '_txt'
|
17
38
|
|
18
|
-
contents = value_field_tag sanitized_id, input_name
|
19
|
-
contents += text_field_tag "#{sanitized_id}_txt", text_tag_name,
|
39
|
+
contents = value_field_tag sanitized_id, input_name
|
40
|
+
contents += text_field_tag "#{sanitized_id}_txt", text_tag_name, field_attrs
|
20
41
|
contents + dropdown_button_tag
|
21
42
|
end
|
22
43
|
|
23
|
-
def
|
24
|
-
h = {
|
25
|
-
h
|
26
|
-
h[:params] = @
|
44
|
+
def whisperer_settings
|
45
|
+
h = {action: @action}
|
46
|
+
# h[:cs] = @opts[:client_side] if @opts[:client_side]
|
47
|
+
h[:params] = @params if @params
|
27
48
|
h
|
28
49
|
end
|
29
50
|
|
30
|
-
def value_field_tag(id, name
|
31
|
-
%(<input type="hidden" id="#{id}" name="#{name}" value="#{value}" class="value_field">)
|
51
|
+
def value_field_tag(id, name)
|
52
|
+
%(<input type="hidden" id="#{id}" name="#{name}" value="#{@value}" class="value_field">)
|
32
53
|
end
|
33
54
|
|
34
|
-
def text_field_tag(id, name,
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
arr << %(#{k}="#{opts[k]}")
|
41
|
-
arr
|
42
|
-
end
|
43
|
-
opts = opts * ' '
|
55
|
+
def text_field_tag(id, name, attrs={})
|
56
|
+
attrs[:size] = 12 unless attrs.has_key? :size
|
57
|
+
keys_whitelist = (attrs.keys & [:size, :placeholder, :maxlength, :title])
|
58
|
+
attrs = keys_whitelist.inject [] do |arr, k|
|
59
|
+
arr << %(#{k}="#{attrs[k]}")
|
60
|
+
arr
|
44
61
|
end
|
45
|
-
%(<input type="text" autocomplete="off" id="#{id}" name="#{name}" value="#{
|
62
|
+
%(<input type="text" autocomplete="off" id="#{id}" name="#{name}" value="#{@text}" class="text_field#{' unfilled' unless @value}"#{attrs * ' '}>)
|
46
63
|
end
|
47
64
|
|
48
65
|
def dropdown_button_tag
|
data/lib/assoc_whisperer.rb
CHANGED
@@ -5,7 +5,7 @@ require 'assoc_whisperer/template'
|
|
5
5
|
module AssocWhisperer
|
6
6
|
|
7
7
|
class << self
|
8
|
-
attr_accessor :def_url, :
|
8
|
+
attr_accessor :def_url, :attach_assets, :def_value, :def_text
|
9
9
|
end
|
10
10
|
|
11
11
|
module Rails
|
@@ -13,23 +13,10 @@ module AssocWhisperer
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def self.value_field_html(id, name, value)
|
17
|
-
%(<input type="hidden" id="#{id}" name="#{name}" value="#{value}" class="value_field">)
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.text_field_html(id, name, value, unfilled=true, opts={})
|
21
|
-
opts = opts.keys.inject([]){|arr, k| arr << %(#{k}="#{opts[k]}"); arr }*' '
|
22
|
-
%(<input type="text" id="#{id}" name="#{name}" value="#{value} class="text_field#{' unfilled' if unfilled}"#{opts}>)
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.dropdown_button_html
|
26
|
-
@dropdown_button_html ||= "<span class=\"dropdown_button\">\u25BE</span>"
|
27
|
-
end
|
28
|
-
|
29
16
|
end
|
30
17
|
|
31
18
|
AssocWhisperer.def_url = '/whisp'
|
32
|
-
AssocWhisperer.
|
19
|
+
AssocWhisperer.attach_assets = :attach_whisperer_assets
|
33
20
|
|
34
|
-
AssocWhisperer.
|
35
|
-
AssocWhisperer.
|
21
|
+
AssocWhisperer.def_value = :id
|
22
|
+
AssocWhisperer.def_text = :to_s
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: assoc_whisperer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ondřej Želazko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|