annyang-rails 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +9 -0
- data/README.md +92 -0
- data/Rakefile +14 -0
- data/annyang-rails.gemspec +29 -0
- data/app/helpers/annyang_helper.rb +34 -0
- data/init.rb +3 -0
- data/lib/annyang-rails.rb +8 -0
- data/lib/annyang-rails/version.rb +5 -0
- data/vendor/assets/javascripts/annyang.js +229 -0
- data/vendor/assets/javascripts/annyang.min.js +6 -0
- metadata +64 -0
data/Manifest
ADDED
data/README.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# annyang for Rails Asset Pipeline
|
2
|
+
|
3
|
+
[annyang](https://github.com/TalAter/annyang) is a tiny javascript SpeechRecognition library that lets your users control your site with voice commands. ([documentation](https://www.talater.com/annyang/)).
|
4
|
+
|
5
|
+
This gem makes it easy to use it with Rails Asset Pipeline.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem "annyang-rails"
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
Add the following to your `app/assets/javascripts/application.js`:
|
20
|
+
|
21
|
+
//= require annyang
|
22
|
+
|
23
|
+
To use minified version use this:
|
24
|
+
|
25
|
+
//= require annyang.min
|
26
|
+
|
27
|
+
We have created a helper function to make it easy.
|
28
|
+
|
29
|
+
init_annyang
|
30
|
+
|
31
|
+
If you want to use voice navigation in complete application then call helper function in application layout or if you want to use voice navigation in some specific pages then call helper function in your specific views.
|
32
|
+
|
33
|
+
<%= init_annyang %>
|
34
|
+
|
35
|
+
This helper will generate javascript which will redirect you to specified link for that keyword. You have to speak in microphone with prefix `go to <keyword>` and system will redirect to link which is associated with that keyword.
|
36
|
+
|
37
|
+
We have 3 different ways to define voice navigation commands:
|
38
|
+
|
39
|
+
1 - YAML File
|
40
|
+
2 - Function Parameters
|
41
|
+
3 - HTML Attribute
|
42
|
+
|
43
|
+
#### 1 - YAML File
|
44
|
+
|
45
|
+
You can create file annyang.yml in config directory (config/annyang.yml) where you can define keywords and there links:
|
46
|
+
|
47
|
+
"ruby": "https://www.ruby-lang.org"
|
48
|
+
"rubygems": "http://rubygems.org"
|
49
|
+
|
50
|
+
You can also define options for keywords like if you want to open same link for rubygem and rubygems then you can write it OR (|) operator:
|
51
|
+
|
52
|
+
"rubygem|rubygems": "http://rubygems.org"
|
53
|
+
|
54
|
+
In case `rubygem|rubygems` both voice commands `go to rubygem` and `go to rubygems` will take you to `http://rubygems.org`
|
55
|
+
|
56
|
+
#### 2 - Function Parameters
|
57
|
+
|
58
|
+
You can pass keywords in helper function's parameters:
|
59
|
+
|
60
|
+
<%= init_annyang({"ruby" => "https://www.ruby-lang.org", "rubygem|rubygems" => "http://rubygems.org"}) %>
|
61
|
+
|
62
|
+
#### 3 - HTML Attribute
|
63
|
+
|
64
|
+
You can specify your keywords in HTML tags with `data-annyang` attribute name.
|
65
|
+
You have to specify keyword in `data-annyang` attribute in anchor tag and when someone will speak specified word then system will open href link.
|
66
|
+
|
67
|
+
<a href="https://www.ruby-lang.org" data-annyang="ruby">Ruby</a>
|
68
|
+
<a href="http://rubygems.org" data-annyang="rubygem|rubygems">Ruby Gems</a>
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
If you want to use this by your own then try it like this:
|
73
|
+
|
74
|
+
````html
|
75
|
+
<script>
|
76
|
+
if (annyang) {
|
77
|
+
// Let's define a command.
|
78
|
+
var commands = {
|
79
|
+
'show tps report': function() { $('#tpsreport').show(); }
|
80
|
+
};
|
81
|
+
|
82
|
+
// Initialize annyang with our commands
|
83
|
+
annyang.init(commands);
|
84
|
+
|
85
|
+
// Start listening.
|
86
|
+
annyang.start();
|
87
|
+
}
|
88
|
+
</script>
|
89
|
+
|
90
|
+
````
|
91
|
+
|
92
|
+
**For more details, [visit the demo and docs site](https://www.talater.com/annyang).**
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('annyang-rails', '0.2.0') do |p|
|
6
|
+
p.description = "A tiny javascript SpeechRecognition library that lets your users control your site with voice commands."
|
7
|
+
p.url = "http://github.com/confiz/annyang-rails"
|
8
|
+
p.author = "Confiz Limited"
|
9
|
+
p.email = "opensource@confiz.com"
|
10
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
+
p.development_dependencies = []
|
12
|
+
end
|
13
|
+
|
14
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "annyang-rails"
|
5
|
+
s.version = "0.2.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Confiz Limited"]
|
9
|
+
s.date = "2013-12-09"
|
10
|
+
s.description = "A tiny javascript SpeechRecognition library that lets your users control your site with voice commands."
|
11
|
+
s.email = "opensource@confiz.com"
|
12
|
+
s.extra_rdoc_files = ["README.md", "lib/annyang-rails.rb", "lib/annyang-rails/version.rb"]
|
13
|
+
s.files = ["README.md", "Rakefile", "app/helpers/annyang_helper.rb", "init.rb", "lib/annyang-rails.rb", "lib/annyang-rails/version.rb", "vendor/assets/javascripts/annyang.js", "vendor/assets/javascripts/annyang.min.js", "Manifest", "annyang-rails.gemspec"]
|
14
|
+
s.homepage = "http://github.com/confiz/annyang-rails"
|
15
|
+
s.rdoc_options = ["--line-numbers", "--title", "Annyang-rails", "--main", "README.md"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = "annyang-rails"
|
18
|
+
s.rubygems_version = "1.8.24"
|
19
|
+
s.summary = "A tiny javascript SpeechRecognition library that lets your users control your site with voice commands."
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
s.specification_version = 3
|
23
|
+
|
24
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
|
+
else
|
26
|
+
end
|
27
|
+
else
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module AnnyangHelper
|
2
|
+
def init_annyang(commands = {})
|
3
|
+
commands = commands.merge(get_annyang_commands)
|
4
|
+
javascript_tag do
|
5
|
+
raw("var annyang_commands={};
|
6
|
+
var linkAnnyang = function(term){
|
7
|
+
if(annyang_commands[term]){
|
8
|
+
window.location = annyang_commands[term];
|
9
|
+
}
|
10
|
+
}
|
11
|
+
function initAnnyang(){
|
12
|
+
if (annyang) {
|
13
|
+
annyang_commands = {#{commands.collect{|k,v| k.split('|').collect {|key| "'#{key}': '#{v}'"} }.join(', ')}};
|
14
|
+
if($('a[data-annyang]').length > 0){
|
15
|
+
$('a[data-annyang]').each(function( index ) {
|
16
|
+
var link = $(this).attr('href');
|
17
|
+
var split_arr = $(this).attr('data-annyang').split('|');
|
18
|
+
for (var i=0; i < split_arr.length; i++)
|
19
|
+
annyang_commands[split_arr[i]] = link;
|
20
|
+
});
|
21
|
+
}
|
22
|
+
annyang.init({'go to *term': linkAnnyang});
|
23
|
+
annyang.start();
|
24
|
+
}
|
25
|
+
}
|
26
|
+
$(document).ready(initAnnyang);")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
def get_annyang_commands
|
30
|
+
yml_path = File.join(Rails.root,"config/annyang.yml")
|
31
|
+
commands_hash = YAML.load_file(yml_path) if yml_path && File.exist?(yml_path)
|
32
|
+
commands_hash||{}
|
33
|
+
end
|
34
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
//! annyang
|
2
|
+
//! version : 0.2.0
|
3
|
+
//! author : Tal Ater @TalAter
|
4
|
+
//! license : MIT
|
5
|
+
//! https://www.TalAter.com/annyang/
|
6
|
+
(function () {
|
7
|
+
"use strict";
|
8
|
+
|
9
|
+
// Save a reference to the global object (window in the browser)
|
10
|
+
var root = this;
|
11
|
+
|
12
|
+
// Get the SpeechRecognition object, while handling browser prefixes
|
13
|
+
var SpeechRecognition = root.webkitSpeechRecognition ||
|
14
|
+
root.mozSpeechRecognition ||
|
15
|
+
root.msSpeechRecognition ||
|
16
|
+
root.oSpeechRecognition ||
|
17
|
+
root.SpeechRecognition;
|
18
|
+
|
19
|
+
// Check browser support
|
20
|
+
// This is done as early as possible, to make it as fast as possible for unsupported browsers
|
21
|
+
if ( !SpeechRecognition ) {
|
22
|
+
root.annyang = null;
|
23
|
+
return null;
|
24
|
+
}
|
25
|
+
|
26
|
+
var commandsList;
|
27
|
+
var recognition;
|
28
|
+
var lang = 'en-US';
|
29
|
+
var callbacks = { start: [], error: [], end: [], result: [], resultMatch: [], resultNoMatch: [], errorNetwork: [], errorPermissionBlocked: [], errorPermissionDenied: [] };
|
30
|
+
var autoRestart;
|
31
|
+
var lastStartedAt = 0;
|
32
|
+
var debugState = false;
|
33
|
+
var debugStyle = 'font-weight: bold; color: #00f;';
|
34
|
+
|
35
|
+
// The command matching code is a modified version of Backbone.Router by Jeremy Ashkenas, under the MIT license.
|
36
|
+
var optionalParam = /\s*\((.*?)\)\s*/g;
|
37
|
+
var optionalRegex = /(\(\?:[^)]+\))\?/g;
|
38
|
+
var namedParam = /(\(\?)?:\w+/g;
|
39
|
+
var splatParam = /\*\w+/g;
|
40
|
+
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#]/g;
|
41
|
+
var commandToRegExp = function(command) {
|
42
|
+
command = command.replace(escapeRegExp, '\\$&')
|
43
|
+
.replace(optionalParam, '(?:$1)?')
|
44
|
+
.replace(namedParam, function(match, optional) {
|
45
|
+
return optional ? match : '([^\\s]+)';
|
46
|
+
})
|
47
|
+
.replace(splatParam, '(.*?)')
|
48
|
+
.replace(optionalRegex, '\\s*$1?\\s*');
|
49
|
+
return new RegExp('^' + command + '$', 'i');
|
50
|
+
};
|
51
|
+
|
52
|
+
// This method receives an array of callbacks to iterate over, and invokes each of them
|
53
|
+
var invokeCallbacks = function(callbacks) {
|
54
|
+
for (var j = 0, l = callbacks.length; j < l; j++) {
|
55
|
+
callbacks[j].callback.apply(callbacks[j].context);
|
56
|
+
}
|
57
|
+
};
|
58
|
+
|
59
|
+
root.annyang = {
|
60
|
+
// Initialize annyang with a list of commands to recognize.
|
61
|
+
// e.g. annyang.init({'hello :name': helloFunction})
|
62
|
+
// annyang understands commands with named variables, splats, and optional words.
|
63
|
+
init: function(commands) {
|
64
|
+
|
65
|
+
// Abort previous instances of recognition already running
|
66
|
+
if (recognition && recognition.abort) {
|
67
|
+
recognition.abort();
|
68
|
+
}
|
69
|
+
|
70
|
+
// initiate SpeechRecognition
|
71
|
+
recognition = new SpeechRecognition();
|
72
|
+
|
73
|
+
// Set the max number of alternative transcripts to try and match with a command
|
74
|
+
recognition.maxAlternatives = 5;
|
75
|
+
recognition.continuous = true;
|
76
|
+
// Sets the language to the default 'en-US'. This can be changed with annyang.setLanguage()
|
77
|
+
recognition.lang = lang;
|
78
|
+
|
79
|
+
recognition.onstart = function() { invokeCallbacks(callbacks.start); };
|
80
|
+
|
81
|
+
recognition.onerror = function(event) {
|
82
|
+
invokeCallbacks(callbacks.error);
|
83
|
+
switch (event.error) {
|
84
|
+
case 'network':
|
85
|
+
invokeCallbacks(callbacks.errorNetwork);
|
86
|
+
break;
|
87
|
+
case 'not-allowed':
|
88
|
+
case 'service-not-allowed':
|
89
|
+
// if permission to use the mic is denied, turn off auto-restart
|
90
|
+
autoRestart = false;
|
91
|
+
// determine if permission was denied by user or automatically.
|
92
|
+
if (new Date().getTime()-lastStartedAt < 200) {
|
93
|
+
invokeCallbacks(callbacks.errorPermissionBlocked);
|
94
|
+
} else {
|
95
|
+
invokeCallbacks(callbacks.errorPermissionDenied);
|
96
|
+
}
|
97
|
+
break;
|
98
|
+
}
|
99
|
+
};
|
100
|
+
|
101
|
+
recognition.onend = function() {
|
102
|
+
invokeCallbacks(callbacks.end);
|
103
|
+
// annyang will auto restart if it is closed automatically and not by user action.
|
104
|
+
if (autoRestart) {
|
105
|
+
// play nicely with the browser, and never restart annyang automatically more than once per second
|
106
|
+
var timeSinceLastStart = new Date().getTime()-lastStartedAt;
|
107
|
+
if (timeSinceLastStart < 1000) {
|
108
|
+
setTimeout(root.annyang.start, 1000-timeSinceLastStart);
|
109
|
+
} else {
|
110
|
+
root.annyang.start();
|
111
|
+
}
|
112
|
+
}
|
113
|
+
};
|
114
|
+
|
115
|
+
recognition.onresult = function(event) {
|
116
|
+
invokeCallbacks(callbacks.result);
|
117
|
+
var results = event.results[event.resultIndex];
|
118
|
+
var commandText;
|
119
|
+
// go over each of the 5 results and alternative results received (we've set maxAlternatives to 5 above)
|
120
|
+
for (var i = 0; i<results.length; i++) {
|
121
|
+
// the text recognized
|
122
|
+
commandText = results[i].transcript.trim();
|
123
|
+
if (debugState) {
|
124
|
+
root.console.log('Speech recognized: %c'+commandText, debugStyle);
|
125
|
+
}
|
126
|
+
|
127
|
+
// try and match recognized text to one of the commands on the list
|
128
|
+
for (var j = 0, l = commandsList.length; j < l; j++) {
|
129
|
+
var result = commandsList[j].command.exec(commandText);
|
130
|
+
if (result) {
|
131
|
+
var parameters = result.slice(1);
|
132
|
+
if (debugState) {
|
133
|
+
root.console.log('command matched: %c'+commandsList[j].originalPhrase, debugStyle);
|
134
|
+
if (parameters.length) {
|
135
|
+
root.console.log('with parameters', parameters);
|
136
|
+
}
|
137
|
+
}
|
138
|
+
// execute the matched command
|
139
|
+
commandsList[j].callback.apply(this, parameters);
|
140
|
+
invokeCallbacks(callbacks.resultMatch);
|
141
|
+
return true;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
145
|
+
invokeCallbacks(callbacks.resultNoMatch);
|
146
|
+
return false;
|
147
|
+
};
|
148
|
+
|
149
|
+
// build commands list
|
150
|
+
commandsList = [];
|
151
|
+
this.addCommands(commands);
|
152
|
+
},
|
153
|
+
|
154
|
+
// Start listening (asking for permission first, if needed).
|
155
|
+
// Call this after you've initialized annyang with commands.
|
156
|
+
// Receives an optional options object:
|
157
|
+
// { autoRestart: true }
|
158
|
+
start: function(options) {
|
159
|
+
options = options || {};
|
160
|
+
if (options.autoRestart !== void 0) {
|
161
|
+
autoRestart = !!options.autoRestart;
|
162
|
+
} else {
|
163
|
+
autoRestart = true;
|
164
|
+
}
|
165
|
+
lastStartedAt = new Date().getTime();
|
166
|
+
recognition.start();
|
167
|
+
},
|
168
|
+
|
169
|
+
// abort the listening session (aka stop)
|
170
|
+
abort: function() {
|
171
|
+
autoRestart = false;
|
172
|
+
recognition.abort();
|
173
|
+
},
|
174
|
+
|
175
|
+
// Turn on output of debug messages to the console. Ugly, but super-handy!
|
176
|
+
debug: function(newState) {
|
177
|
+
if (arguments.length > 0) {
|
178
|
+
debugState = !!newState;
|
179
|
+
} else {
|
180
|
+
debugState = true;
|
181
|
+
}
|
182
|
+
},
|
183
|
+
|
184
|
+
// Set the language the user will speak in. If not called, defaults to 'en-US'.
|
185
|
+
// e.g. 'fr-FR' (French-France), 'es-CR' (Español-Costa Rica)
|
186
|
+
setLanguage: function(language) {
|
187
|
+
lang = language;
|
188
|
+
if (recognition && recognition.abort) {
|
189
|
+
recognition.lang = language;
|
190
|
+
}
|
191
|
+
},
|
192
|
+
|
193
|
+
// Add additional commands that annyang will respond to. Similar in syntax to annyang.init()
|
194
|
+
addCommands: function(commands) {
|
195
|
+
var cb,
|
196
|
+
command;
|
197
|
+
for (var phrase in commands) {
|
198
|
+
if (commands.hasOwnProperty(phrase)) {
|
199
|
+
cb = root[commands[phrase]] || commands[phrase];
|
200
|
+
if (typeof cb !== 'function') {
|
201
|
+
continue;
|
202
|
+
}
|
203
|
+
//convert command to regex
|
204
|
+
command = commandToRegExp(phrase);
|
205
|
+
|
206
|
+
commandsList.push({ command: command, callback: cb, originalPhrase: phrase });
|
207
|
+
}
|
208
|
+
}
|
209
|
+
if (debugState) {
|
210
|
+
root.console.log('Commands successfully loaded: %c'+commandsList.length, debugStyle);
|
211
|
+
}
|
212
|
+
},
|
213
|
+
|
214
|
+
// Lets the user add a callback of one of 9 types:
|
215
|
+
// start, error, end, result, resultMatch, resultNoMatch, errorNetwork, errorPermissionBlocked, errorPermissionDenied
|
216
|
+
// Can also optionally receive a context for the callback function as the third argument
|
217
|
+
addCallback: function(type, callback, context) {
|
218
|
+
if (callbacks[type] === void 0) {
|
219
|
+
return;
|
220
|
+
}
|
221
|
+
var cb = root[callback] || callback;
|
222
|
+
if (typeof cb !== 'function') {
|
223
|
+
return;
|
224
|
+
}
|
225
|
+
callbacks[type].push({callback: cb, context: context || this});
|
226
|
+
}
|
227
|
+
};
|
228
|
+
|
229
|
+
}).call(this);
|
@@ -0,0 +1,6 @@
|
|
1
|
+
//! annyang
|
2
|
+
//! version : 0.2.0
|
3
|
+
//! author : Tal Ater @TalAter
|
4
|
+
//! license : MIT
|
5
|
+
//! https://www.TalAter.com/annyang/
|
6
|
+
(function(){"use strict";var a=this,b=a.webkitSpeechRecognition||a.mozSpeechRecognition||a.msSpeechRecognition||a.oSpeechRecognition||a.SpeechRecognition;if(!b)return a.annyang=null,null;var c,d,e,f="en-US",g={start:[],error:[],end:[],result:[],resultMatch:[],resultNoMatch:[],errorNetwork:[],errorPermissionBlocked:[],errorPermissionDenied:[]},h=0,i=!1,j="font-weight: bold; color: #00f;",k=/\s*\((.*?)\)\s*/g,l=/(\(\?:[^)]+\))\?/g,m=/(\(\?)?:\w+/g,n=/\*\w+/g,o=/[\-{}\[\]+?.,\\\^$|#]/g,p=function(a){return a=a.replace(o,"\\$&").replace(k,"(?:$1)?").replace(m,function(a,b){return b?a:"([^\\s]+)"}).replace(n,"(.*?)").replace(l,"\\s*$1?\\s*"),new RegExp("^"+a+"$","i")},q=function(a){for(var b=0,c=a.length;c>b;b++)a[b].callback.apply(a[b].context)};a.annyang={init:function(k){d&&d.abort&&d.abort(),d=new b,d.maxAlternatives=5,d.continuous=!0,d.lang=f,d.onstart=function(){q(g.start)},d.onerror=function(a){switch(q(g.error),a.error){case"network":q(g.errorNetwork);break;case"not-allowed":case"service-not-allowed":e=!1,(new Date).getTime()-h<200?q(g.errorPermissionBlocked):q(g.errorPermissionDenied)}},d.onend=function(){if(q(g.end),e){var b=(new Date).getTime()-h;1e3>b?setTimeout(a.annyang.start,1e3-b):a.annyang.start()}},d.onresult=function(b){q(g.result);for(var d,e=b.results[b.resultIndex],f=0;f<e.length;f++){d=e[f].transcript.trim(),i&&a.console.log("Speech recognized: %c"+d,j);for(var h=0,k=c.length;k>h;h++){var l=c[h].command.exec(d);if(l){var m=l.slice(1);return i&&(a.console.log("command matched: %c"+c[h].originalPhrase,j),m.length&&a.console.log("with parameters",m)),c[h].callback.apply(this,m),q(g.resultMatch),!0}}}return q(g.resultNoMatch),!1},c=[],this.addCommands(k)},start:function(a){a=a||{},e=void 0!==a.autoRestart?!!a.autoRestart:!0,h=(new Date).getTime(),d.start()},abort:function(){e=!1,d.abort()},debug:function(a){i=arguments.length>0?!!a:!0},setLanguage:function(a){f=a,d&&d.abort&&(d.lang=a)},addCommands:function(b){var d,e;for(var f in b)if(b.hasOwnProperty(f)){if(d=a[b[f]]||b[f],"function"!=typeof d)continue;e=p(f),c.push({command:e,callback:d,originalPhrase:f})}i&&a.console.log("Commands successfully loaded: %c"+c.length,j)},addCallback:function(b,c,d){if(void 0!==g[b]){var e=a[c]||c;"function"==typeof e&&g[b].push({callback:e,context:d||this})}}}}).call(this);
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: annyang-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Confiz Limited
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-09 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A tiny javascript SpeechRecognition library that lets your users control
|
15
|
+
your site with voice commands.
|
16
|
+
email: opensource@confiz.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files:
|
20
|
+
- README.md
|
21
|
+
- lib/annyang-rails.rb
|
22
|
+
- lib/annyang-rails/version.rb
|
23
|
+
files:
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- app/helpers/annyang_helper.rb
|
27
|
+
- init.rb
|
28
|
+
- lib/annyang-rails.rb
|
29
|
+
- lib/annyang-rails/version.rb
|
30
|
+
- vendor/assets/javascripts/annyang.js
|
31
|
+
- vendor/assets/javascripts/annyang.min.js
|
32
|
+
- Manifest
|
33
|
+
- annyang-rails.gemspec
|
34
|
+
homepage: http://github.com/confiz/annyang-rails
|
35
|
+
licenses: []
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --line-numbers
|
39
|
+
- --title
|
40
|
+
- Annyang-rails
|
41
|
+
- --main
|
42
|
+
- README.md
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '1.2'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project: annyang-rails
|
59
|
+
rubygems_version: 1.8.24
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: A tiny javascript SpeechRecognition library that lets your users control
|
63
|
+
your site with voice commands.
|
64
|
+
test_files: []
|