lelylan-rb 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG.md +6 -2
- data/Gemfile +1 -3
- data/Guardfile +1 -1
- data/README.md +155 -84
- data/Rakefile +2 -15
- data/images/bg_hr.png +0 -0
- data/images/blacktocat.png +0 -0
- data/images/icon_download.png +0 -0
- data/images/sprite_download.png +0 -0
- data/index.html +74 -0
- data/javascripts/main.js +1 -0
- data/lelylan_rb.gemspec +12 -13
- data/lib/lelylan/client.rb +20 -23
- data/lib/lelylan/client/device.rb +121 -0
- data/lib/lelylan/client/function.rb +73 -0
- data/lib/lelylan/client/history.rb +28 -0
- data/lib/lelylan/client/location.rb +62 -0
- data/lib/lelylan/client/physical.rb +34 -0
- data/lib/lelylan/client/profile.rb +17 -0
- data/lib/lelylan/client/property.rb +75 -0
- data/lib/lelylan/client/status.rb +74 -0
- data/lib/lelylan/client/subscription.rb +62 -0
- data/lib/lelylan/client/type.rb +73 -0
- data/lib/lelylan/configuration.rb +4 -4
- data/lib/lelylan/connection.rb +9 -2
- data/lib/lelylan/request.rb +2 -16
- data/lib/lelylan/version.rb +1 -1
- data/spec/fixtures/profile.json +8 -0
- data/spec/fixtures/subscription.json +10 -0
- data/spec/fixtures/subscriptions.json +10 -0
- data/spec/lelylan/client/device_spec.rb +234 -0
- data/spec/lelylan/client/function_spec.rb +158 -0
- data/spec/lelylan/client/history_spec.rb +48 -0
- data/spec/lelylan/client/location_spec.rb +122 -0
- data/spec/lelylan/client/physical_spec.rb +27 -0
- data/spec/lelylan/client/profile_spec.rb +27 -0
- data/spec/lelylan/client/property_spec.rb +159 -0
- data/spec/lelylan/client/status_spec.rb +158 -0
- data/spec/lelylan/client/subscription_spec.rb +144 -0
- data/spec/lelylan/client/type_spec.rb +158 -0
- data/spec/lelylan/oauth2_spec.rb +13 -19
- data/stylesheets/pygment_trac.css +70 -0
- data/stylesheets/stylesheet.css +431 -0
- metadata +75 -114
- data/lib/lelylan/client/categories.rb +0 -112
- data/lib/lelylan/client/consumptions.rb +0 -93
- data/lib/lelylan/client/devices.rb +0 -211
- data/lib/lelylan/client/functions.rb +0 -118
- data/lib/lelylan/client/histories.rb +0 -42
- data/lib/lelylan/client/locations.rb +0 -92
- data/lib/lelylan/client/properties.rb +0 -115
- data/lib/lelylan/client/statuses.rb +0 -110
- data/lib/lelylan/client/types.rb +0 -109
- data/spec/lelylan/client/categories_spec.rb +0 -178
- data/spec/lelylan/client/consumptions_spec.rb +0 -150
- data/spec/lelylan/client/devices_spec.rb +0 -342
- data/spec/lelylan/client/functions_spec.rb +0 -184
- data/spec/lelylan/client/histories_spec.rb +0 -64
- data/spec/lelylan/client/locations_spec.rb +0 -155
- data/spec/lelylan/client/properties_spec.rb +0 -184
- data/spec/lelylan/client/statuses_spec.rb +0 -184
- data/spec/lelylan/client/types_spec.rb +0 -184
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
guard 'rspec', cli: '--format Fuubar --color', all_after_pass: false
|
1
|
+
guard 'rspec', cli: '--format Fuubar --color', all_after_pass: false do
|
2
2
|
watch(%r{^spec/.+_spec\.rb})
|
3
3
|
watch(%r{^lib/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
|
4
4
|
watch('spec/spec_helper.rb') { "spec" }
|
data/README.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
Ruby client library for [Lelylan API](http://dev.lelylan.com)
|
4
4
|
|
5
|
+
## What is Lelylan
|
6
|
+
|
7
|
+
Lelylan makes it easy for developers to monitor and control all devices in
|
8
|
+
your house providing a simple, self descriptive and consistent representation of them. Lelylan
|
9
|
+
maps every device in your house to a unique URI which will provide a simple access over it.
|
10
|
+
|
11
|
+
With Lelylan developers can build secure applications and services that use real-time data
|
12
|
+
coming from the real world to create the future connected house.
|
5
13
|
|
6
14
|
## Requirements
|
7
15
|
|
@@ -10,131 +18,169 @@ Ruby client library is tested against MRI 1.9.3.
|
|
10
18
|
|
11
19
|
## Installation
|
12
20
|
|
13
|
-
Install
|
21
|
+
Install the client using Bundler.
|
14
22
|
|
15
|
-
|
23
|
+
```ruby
|
24
|
+
gem 'lelylan-rb', require: 'lelylan'
|
25
|
+
gem 'oauth2'
|
26
|
+
```
|
16
27
|
|
17
28
|
Development version.
|
18
29
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
## Resources
|
23
|
-
|
24
|
-
* [Ruby gem documentation](http://rdoc.info/gems/lelylan-rb)
|
25
|
-
* [Lelylan API](http://dev.lelylan.com)
|
26
|
-
|
30
|
+
```ruby
|
31
|
+
gem 'lelylan-rb', require: 'lelylan', git: 'https://github.com/lelylan/lelylan-rb', branch: 'master'
|
32
|
+
```
|
27
33
|
|
28
34
|
## Getting started
|
29
35
|
|
30
|
-
Require
|
36
|
+
### Require Gem
|
31
37
|
|
32
|
-
|
33
|
-
|
38
|
+
```ruby
|
39
|
+
require 'rubygems'
|
40
|
+
require 'lelylan-rb'
|
41
|
+
require 'oauth2'
|
42
|
+
```
|
34
43
|
|
44
|
+
### Get an access token
|
35
45
|
|
36
|
-
|
46
|
+
First of all you need an access token to authoraze your requests in
|
47
|
+
Lelylan. To get one use the [OAuth2 gem](https://github.com/intridea/oauth2/)
|
48
|
+
and if you are not used to OAuth2 concepts, take 10 minutes and read the
|
49
|
+
related documentation in the [dev center](http://dev.lelylan.com/api/oauth#language=node).
|
37
50
|
|
38
|
-
Create a client (uses the [OAuth2 gem](https://github.com/intridea/oauth2/)).
|
39
51
|
|
40
|
-
|
52
|
+
```ruby
|
53
|
+
# Create a client
|
54
|
+
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
41
55
|
|
42
|
-
Redirect the application to the Lelylan authorization page
|
56
|
+
# Redirect the application to the Lelylan authorization page
|
57
|
+
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
58
|
+
# => http://people.lelylan.com/oauth/authorize?redirect_uri=http://localhost:3000/callback&scope=devices&response_type=code&client_id=<client-id>
|
43
59
|
|
44
|
-
|
60
|
+
# Get the access token object (authorization code is given from the previous step)
|
61
|
+
token = oauth.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
|
62
|
+
```
|
45
63
|
|
46
|
-
|
47
|
-
code created from Lelylan and sent to the redirect_uri.
|
64
|
+
### Lelylan access
|
48
65
|
|
49
|
-
|
66
|
+
Once you have the access token you can access to the Lelylan API. The
|
67
|
+
following example shows how to print in the console a list of owned devices.
|
50
68
|
|
51
|
-
|
69
|
+
```ruby
|
70
|
+
# Initialize Lelylan client
|
71
|
+
lelylan = Lelylan::Client.new(token: token)
|
52
72
|
|
53
|
-
|
73
|
+
# Get the first device where the name matches with Dimmer
|
74
|
+
device = lelylan.devices(name: 'Dimmer').first
|
75
|
+
```
|
54
76
|
|
55
|
-
###
|
77
|
+
### Realtime services
|
56
78
|
|
57
|
-
|
79
|
+
When using the [subscription](http://dev.lelylan.com/api/realtime#language=node) services
|
80
|
+
you don't need an access token. In this case what you need is to set the client credentials.
|
58
81
|
|
59
|
-
|
82
|
+
```ruby
|
83
|
+
lelylan = Lelylan::Client.new(client_id:'<client-id>', client_secret: '<client-secret>')
|
84
|
+
subscriptions = lelylan.subscriptions
|
85
|
+
```
|
60
86
|
|
61
|
-
|
87
|
+
## Authorization flows
|
62
88
|
|
63
|
-
|
89
|
+
Lelylan support three OAuth2 authorization flows.
|
64
90
|
|
65
|
-
|
91
|
+
### Authorization code flows
|
66
92
|
|
67
|
-
|
93
|
+
```ruby
|
94
|
+
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
95
|
+
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
96
|
+
token = oauth.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
|
97
|
+
```
|
68
98
|
|
69
|
-
|
99
|
+
### Implicit grant flow
|
70
100
|
|
71
|
-
|
101
|
+
```ruby
|
102
|
+
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
103
|
+
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
104
|
+
token = OAuth2::AccessToken.from_kvform(client, params)
|
105
|
+
```
|
72
106
|
|
73
|
-
|
107
|
+
### Resource owner password credentials flow
|
74
108
|
|
75
|
-
|
109
|
+
```ruby
|
110
|
+
oauth = OAuth2::Client.new(client_id, client_secret, site: site)
|
111
|
+
token = oauth.password.get_token('email', 'password')
|
112
|
+
```
|
76
113
|
|
77
|
-
|
78
|
-
with a token is not needed.
|
114
|
+
Access tokens, when expired, are automatically refreshed.
|
79
115
|
|
80
|
-
Lelylan.type('http://api.lelylan.com/types/:id')
|
81
116
|
|
117
|
+
## Lelylan Services
|
82
118
|
|
83
|
-
|
119
|
+
### Devices
|
84
120
|
|
85
|
-
|
121
|
+
The Device API defines a set of services to monitor and control every existing device.
|
122
|
+
Its final goal is to map every device to a unique URI which provides control over it.
|
123
|
+
[See examples](http://dev.lelylan.com/api/devices#ruby).
|
86
124
|
|
87
|
-
|
88
|
-
* [Consumption examples](docs/Lelylan/Client/Consumptions)
|
89
|
-
* [Hisotry examples](docs/Lelylan/Client/Histories)
|
90
|
-
* [Types examples](docs/Lelylan/Client/Types)
|
91
|
-
* [Properties examples](docs/Lelylan/Client/Properties)
|
92
|
-
* [Functions examples](docs/Lelylan/Client/Functions)
|
93
|
-
* [Statuses examples](docs/Lelylan/Client/Statuses)
|
94
|
-
* [Categories examples](docs/Lelylan/Client/Categories)
|
95
|
-
* [Locations examples](docs/Lelylan/Client/Locations)
|
125
|
+
### Histories
|
96
126
|
|
97
|
-
|
127
|
+
When a device updates its properties or executes a function a new history resource with
|
128
|
+
a snapshot of all device properties is created by Lelylan, also the ones that has not been
|
129
|
+
updated. This makes it easy to recreate previous device status and extract usage patterns
|
130
|
+
to improve the way people live their house.
|
131
|
+
[See examples](http://dev.lelylan.com/api/devices/histories#ruby).
|
98
132
|
|
99
|
-
|
133
|
+
### Types
|
100
134
|
|
101
|
-
|
135
|
+
A type describes the structure of a device. In its simplest form every type can be defined
|
136
|
+
as the combination of three key elements: properties (what vary during time), functions
|
137
|
+
(what a device can do), statuses (what a device is in a specific time of its life).
|
138
|
+
[See examples](http://dev.lelylan.com/api/types#ruby).
|
102
139
|
|
103
|
-
|
104
|
-
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
105
|
-
token = oauth.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
|
140
|
+
### Properties
|
106
141
|
|
107
|
-
|
142
|
+
A property is whatever vary in a device during time. It can be the intensity in a dimmer,
|
143
|
+
the temperature in a cooling system or the volume in a television.
|
144
|
+
[See examples](http://dev.lelylan.com/api/types/properties#ruby).
|
108
145
|
|
109
|
-
|
110
|
-
redirect oauth.auth_code.authorize_url(redirect_uri: redirect_uri)
|
111
|
-
token = OAuth2::AccessToken.from_kvform(client, params)
|
146
|
+
### Functions
|
112
147
|
|
113
|
-
|
148
|
+
Functions defines the daily interactions you have with the devices in your house, for
|
149
|
+
example when you turn on a light, close a door or raise the temperature in a room.
|
150
|
+
With functions you can control any device in the same way you do everyday of your life.
|
151
|
+
[See examples](http://dev.lelylan.com/api/types/functions#ruby).
|
114
152
|
|
115
|
-
|
116
|
-
token = oauth.password.get_token('email', 'password')
|
153
|
+
### Statuses
|
117
154
|
|
118
|
-
|
155
|
+
Properties are not always enough to describe the status of a device. Think at a roller
|
156
|
+
shutter for example. It has the property aperture that is 100 when open or 0 when closed.
|
157
|
+
But what if the roller shutter is opening? It is nether open or close. To have a complete
|
158
|
+
control over the device status in a specific moment of its life is to use the status API.
|
159
|
+
[See examples](http://dev.lelylan.com/api/types/statuses#ruby).
|
119
160
|
|
120
|
-
|
161
|
+
### Locations
|
121
162
|
|
122
|
-
|
163
|
+
Locations are the places we live in and where physical devices are placed. Lelylan identifies
|
164
|
+
three types of locations usually organized in a hierarchical structure: houses, floors and
|
165
|
+
rooms.
|
166
|
+
[See examples](http://dev.lelylan.com/api/locations#ruby).
|
123
167
|
|
168
|
+
### Physical devices
|
124
169
|
|
125
|
-
|
170
|
+
Physical devices are the real objects you physically interact with everyday of your life
|
171
|
+
like lights, appliances, alarms and more. To enable the communication between Lelylan and
|
172
|
+
physical devices they should provide a simple set of web services.
|
173
|
+
[See examples](http://dev.lelylan.com/api/physicals#ruby).
|
126
174
|
|
127
|
-
###
|
175
|
+
### Subscriptions
|
128
176
|
|
129
|
-
|
130
|
-
|
131
|
-
Lelylan.configure { |c| c.endpoint = 'https://lelylan.yourhouse.com' }
|
132
|
-
@client = Lelylan::Client.new(token: token)
|
177
|
+
Get real-time updates by subscribing to a resource and its related event.
|
178
|
+
[See examples](http://dev.lelylan.com/api/realtime#ruby).
|
133
179
|
|
134
|
-
|
180
|
+
### Authenticated User Profile
|
135
181
|
|
136
|
-
|
137
|
-
|
182
|
+
Returns extended information for the authenticated user.
|
183
|
+
[See examples](http://dev.lelylan.com/api/core#get-a-user-ruby).
|
138
184
|
|
139
185
|
|
140
186
|
## Errors
|
@@ -152,18 +198,41 @@ Exceptions are raised when a 4xx or 5xx status code is returned.
|
|
152
198
|
|
153
199
|
Through the error message attribute you can access the error information.
|
154
200
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
201
|
+
```ruby
|
202
|
+
begin
|
203
|
+
@type = Lelylan::Type.type("https://type.lelylan.com/types/wrong")
|
204
|
+
rescue Lelylan::NotFound => e
|
205
|
+
puts "The resource #{e.message.error.uri} was not found"
|
206
|
+
end
|
207
|
+
```
|
208
|
+
|
209
|
+
Learn more about the [error response structure](http://dev.lelylan.com/api/core#errors).
|
210
|
+
|
211
|
+
|
212
|
+
## Configurations
|
213
|
+
|
214
|
+
### API endpoint
|
215
|
+
|
216
|
+
Configuration block.
|
217
|
+
|
218
|
+
```ruby
|
219
|
+
Lelylan.configure { |c| c.endpoint = 'https://localhost:8000' }
|
220
|
+
lelylan = Lelylan::Client.new(token: token)
|
221
|
+
```
|
222
|
+
|
223
|
+
Client instance.
|
224
|
+
|
225
|
+
```ruby
|
226
|
+
lelylan = Lelylan::Client.new(token: token)
|
227
|
+
lelylan.endpoint = 'https://lelylan.yourhouse.com'
|
228
|
+
```
|
160
229
|
|
161
|
-
Learn more about the [error response structure](http://dev.lelylan.com/
|
230
|
+
Learn more about the [error response structure](http://dev.lelylan.com/api/core#errors).
|
162
231
|
|
163
232
|
|
164
233
|
## Contributing
|
165
234
|
|
166
|
-
Fork the repo on github and send a pull requests with topic branches. Do not forget to
|
235
|
+
Fork the repo on github and send a pull requests with topic branches. Do not forget to
|
167
236
|
provide specs to your contribution.
|
168
237
|
|
169
238
|
|
@@ -177,7 +246,7 @@ provide specs to your contribution.
|
|
177
246
|
|
178
247
|
## Spec guidelines
|
179
248
|
|
180
|
-
Follow [rspec best practices](
|
249
|
+
Follow [rspec best practices](http://betterspecs.org) guidelines.
|
181
250
|
|
182
251
|
|
183
252
|
## Coding guidelines
|
@@ -191,9 +260,10 @@ Use the [issue tracker](http://github.com/lelylan/lelylan-rb/issues) for bugs.
|
|
191
260
|
[Mail](mailto:touch@lelylan.com) or [Tweet](http://twitter.com/lelylan) us for any idea that can improve the project.
|
192
261
|
|
193
262
|
|
194
|
-
## Links
|
263
|
+
## Links
|
195
264
|
|
196
265
|
* [GIT Repository](http://github.com/lelylan/lelylan-rb)
|
266
|
+
* [Lelylan Ruby Website](http://lelylan.github.com/lelylan-rb).
|
197
267
|
* [Lelylan Dev Center](http://dev.lelylan.com)
|
198
268
|
* [Lelylan Site](http://lelylan.com)
|
199
269
|
|
@@ -210,9 +280,10 @@ Special thanks to the following people for submitting patches.
|
|
210
280
|
|
211
281
|
## Changelog
|
212
282
|
|
213
|
-
See [CHANGELOG](
|
283
|
+
See [CHANGELOG](https://github.com/lelylan/lelylan-rb/blob/master/CHANGELOG.md)
|
214
284
|
|
215
285
|
|
216
286
|
## Copyright
|
217
287
|
|
218
|
-
Copyright (c) 2013 [Lelylan](http://lelylan.com).
|
288
|
+
Copyright (c) 2013 [Lelylan](http://lelylan.com).
|
289
|
+
See [LICENSE](https://github.com/lelylan/lelylan-rb/blob/master/LICENSE.md) for details.
|
data/Rakefile
CHANGED
@@ -4,18 +4,5 @@ Bundler::GemHelper.install_tasks
|
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
RSpec::Core::RakeTask.new(:spec)
|
6
6
|
|
7
|
-
task :
|
8
|
-
task :
|
9
|
-
|
10
|
-
namespace :doc do
|
11
|
-
require 'yard'
|
12
|
-
YARD::Rake::YardocTask.new do |task|
|
13
|
-
task.files = ['README.md', 'CHANGELOG.md', 'lib/lelylan/client/**/*.rb']
|
14
|
-
task.options = [
|
15
|
-
'--plugin', 'yard-tomdoc',
|
16
|
-
'--markup-provider', 'redcarpet',
|
17
|
-
'--markup', 'markdown',
|
18
|
-
'--output-dir', 'doc'
|
19
|
-
]
|
20
|
-
end
|
21
|
-
end
|
7
|
+
task test: :spec
|
8
|
+
task default: :spec
|
data/images/bg_hr.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/index.html
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta charset='utf-8' />
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
|
7
|
+
<meta name="description" content="Lelylan-rb : Ruby wrapper for Lelylan API" />
|
8
|
+
|
9
|
+
<link rel="stylesheet" type="text/css" media="screen" href="stylesheets/stylesheet.css">
|
10
|
+
|
11
|
+
<title>Lelylan-rb</title>
|
12
|
+
</head>
|
13
|
+
|
14
|
+
<body>
|
15
|
+
|
16
|
+
<!-- HEADER -->
|
17
|
+
<div id="header_wrap" class="outer">
|
18
|
+
<header class="inner">
|
19
|
+
<a id="forkme_banner" href="https://github.com/lelylan/lelylan-rb">View on GitHub</a>
|
20
|
+
|
21
|
+
<h1 id="project_title">Lelylan-rb</h1>
|
22
|
+
<h2 id="project_tagline">Ruby wrapper for Lelylan API</h2>
|
23
|
+
|
24
|
+
<section id="downloads">
|
25
|
+
<a class="zip_download_link" href="https://github.com/lelylan/lelylan-rb/zipball/master">Download this project as a .zip file</a>
|
26
|
+
<a class="tar_download_link" href="https://github.com/lelylan/lelylan-rb/tarball/master">Download this project as a tar.gz file</a>
|
27
|
+
</section>
|
28
|
+
</header>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<!-- MAIN CONTENT -->
|
32
|
+
<div id="main_content_wrap" class="outer">
|
33
|
+
<section id="main_content" class="inner">
|
34
|
+
<h3>Welcome to GitHub Pages.</h3>
|
35
|
+
|
36
|
+
<p>This automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here using GitHub Flavored Markdown, select a template crafted by a designer, and publish. After your page is generated, you can check out the new branch:</p>
|
37
|
+
|
38
|
+
<pre><code>$ cd your_repo_root/repo_name
|
39
|
+
$ git fetch origin
|
40
|
+
$ git checkout gh-pages
|
41
|
+
</code></pre>
|
42
|
+
|
43
|
+
<p>If you're using the GitHub for Mac, simply sync your repository and you'll see the new branch.</p>
|
44
|
+
|
45
|
+
<h3>Designer Templates</h3>
|
46
|
+
|
47
|
+
<p>We've crafted some handsome templates for you to use. Go ahead and continue to layouts to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved if it remained markdown format.</p>
|
48
|
+
|
49
|
+
<h3>Rather Drive Stick?</h3>
|
50
|
+
|
51
|
+
<p>If you prefer to not use the automatic generator, push a branch named <code>gh-pages</code> to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator written by our own Tom Preston-Werner. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.</p>
|
52
|
+
|
53
|
+
<h3>Authors and Contributors</h3>
|
54
|
+
|
55
|
+
<p>You can <a href="https://github.com/blog/821" class="user-mention">@mention</a> a GitHub username to generate a link to their profile. The resulting <code><a></code> element will link to the contributor's GitHub Profile. For example: In 2007, Chris Wanstrath (<a href="https://github.com/defunkt" class="user-mention">@defunkt</a>), PJ Hyett (<a href="https://github.com/pjhyett" class="user-mention">@pjhyett</a>), and Tom Preston-Werner (<a href="https://github.com/mojombo" class="user-mention">@mojombo</a>) founded GitHub.</p>
|
56
|
+
|
57
|
+
<h3>Support or Contact</h3>
|
58
|
+
|
59
|
+
<p>Having trouble with Pages? Check out the documentation at <a href="http://help.github.com/pages">http://help.github.com/pages</a> or contact <a href="mailto:support@github.com">support@github.com</a> and we’ll help you sort it out.</p>
|
60
|
+
</section>
|
61
|
+
</div>
|
62
|
+
|
63
|
+
<!-- FOOTER -->
|
64
|
+
<div id="footer_wrap" class="outer">
|
65
|
+
<footer class="inner">
|
66
|
+
<p class="copyright">Lelylan-rb maintained by <a href="https://github.com/lelylan">lelylan</a></p>
|
67
|
+
<p>Published with <a href="http://pages.github.com">GitHub Pages</a></p>
|
68
|
+
</footer>
|
69
|
+
</div>
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
</body>
|
74
|
+
</html>
|