summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Gruntfile.js155
-rw-r--r--Procfile3
-rw-r--r--README.md17
-rw-r--r--bower.json3
-rw-r--r--config.json.example13
-rw-r--r--package-lock.json2645
-rw-r--r--package.json42
-rwxr-xr-xpublic/assets/fonts/ionicons.eotbin101984 -> 120724 bytes
-rwxr-xr-xpublic/assets/fonts/ionicons.svg1725
-rwxr-xr-xpublic/assets/fonts/ionicons.ttfbin164548 -> 188508 bytes
-rwxr-xr-xpublic/assets/fonts/ionicons.woffbin57276 -> 67904 bytes
-rw-r--r--public/assets/javascripts/app.js34
-rw-r--r--public/assets/javascripts/defaults.js4
-rw-r--r--public/assets/javascripts/mx/extensions/mx.movements.js30
-rw-r--r--public/assets/javascripts/mx/extensions/mx.orbitCamera.js97
-rw-r--r--public/assets/javascripts/mx/mx.js16
-rw-r--r--public/assets/javascripts/mx/primitives/mx.grid.js70
-rw-r--r--public/assets/javascripts/mx/primitives/mx.image.js40
-rw-r--r--public/assets/javascripts/mx/primitives/mx.point.js17
-rw-r--r--public/assets/javascripts/mx/primitives/mx.polyline.js57
-rw-r--r--public/assets/javascripts/mx/primitives/mx.soundcloud.js5
-rw-r--r--public/assets/javascripts/mx/primitives/mx.video.js8
-rw-r--r--public/assets/javascripts/mx/primitives/mx.vimeo.js23
-rw-r--r--public/assets/javascripts/mx/primitives/mx.youtube.js8
-rw-r--r--public/assets/javascripts/rectangles/_env.js35
-rw-r--r--public/assets/javascripts/rectangles/engine/map/_map.js21
-rw-r--r--public/assets/javascripts/rectangles/engine/map/draw.js104
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/_base.js11
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/arrow.js83
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/eraser.js29
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/line.js63
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/ortho.js118
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/polyline.js73
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/position.js19
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/start.js29
-rw-r--r--public/assets/javascripts/rectangles/engine/map/ui/editor.js (renamed from public/assets/javascripts/rectangles/engine/map/ui_editor.js)8
-rw-r--r--public/assets/javascripts/rectangles/engine/map/ui/minimap.js (renamed from public/assets/javascripts/rectangles/engine/map/ui_minimap.js)0
-rw-r--r--public/assets/javascripts/rectangles/engine/map/ui/ortho.js107
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/_rooms.js41
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/_scenery.js30
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/move.js8
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/resize.js5
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/sound.js16
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/types/_object.js4
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/types/audio.js4
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/types/video.js11
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/undo.js65
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js105
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/move.js111
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/resize.js208
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/types/_object.js176
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/types/image.js38
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/ortho.js66
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/polyline.js212
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/regionlist.js240
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/shapelist.js124
-rw-r--r--public/assets/javascripts/rectangles/models/floor.js41
-rw-r--r--public/assets/javascripts/rectangles/models/rect.js12
-rw-r--r--public/assets/javascripts/rectangles/models/room.js7
-rw-r--r--public/assets/javascripts/rectangles/models/vec2.js18
-rw-r--r--public/assets/javascripts/rectangles/models/vec3.js25
-rw-r--r--public/assets/javascripts/rectangles/models/wall.js14
-rw-r--r--public/assets/javascripts/rectangles/util/constants.js5
-rw-r--r--public/assets/javascripts/rectangles/util/coords.js2
-rw-r--r--public/assets/javascripts/rectangles/util/measurement.js4
-rw-r--r--public/assets/javascripts/rectangles/util/mouse.js10
-rw-r--r--public/assets/javascripts/rectangles/util/wheel.js10
-rw-r--r--public/assets/javascripts/ui/_router.js86
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintEditor.js129
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintInfo.js92
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintNotice.js62
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintScaler.js158
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintSettings.js123
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintToolbar.js97
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintUploader.js147
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintView.js97
-rw-r--r--public/assets/javascripts/ui/builder/BuilderInfo.js4
-rw-r--r--public/assets/javascripts/ui/editor/EditorSettings.js17
-rw-r--r--public/assets/javascripts/ui/editor/EditorView.js17
-rw-r--r--public/assets/javascripts/ui/editor/SculptureEditor.js237
-rw-r--r--public/assets/javascripts/ui/lib/AnimatedView.js31
-rw-r--r--public/assets/javascripts/ui/lib/ConfirmModal.js24
-rw-r--r--public/assets/javascripts/ui/lib/FormView.js2
-rw-r--r--public/assets/javascripts/ui/lib/LabColorPicker.js26
-rw-r--r--public/assets/javascripts/ui/lib/ModalView.js5
-rw-r--r--public/assets/javascripts/ui/lib/Parser.js5
-rw-r--r--public/assets/javascripts/ui/lib/ToggleableView.js19
-rw-r--r--public/assets/javascripts/ui/lib/Toolbar.js22
-rw-r--r--public/assets/javascripts/ui/reader/MediaPlayer.js2
-rw-r--r--public/assets/javascripts/ui/reader/ReaderView.js22
-rw-r--r--public/assets/javascripts/ui/reader/Tracker.js14
-rw-r--r--public/assets/javascripts/ui/reader/_router.js24
-rw-r--r--public/assets/javascripts/ui/site/EditSubscriptionModal.js290
-rw-r--r--public/assets/javascripts/ui/site/HomeView.js2
-rw-r--r--public/assets/javascripts/ui/site/LayoutsIndex.js85
-rw-r--r--public/assets/javascripts/ui/site/LayoutsModal.js172
-rw-r--r--public/assets/javascripts/ui/site/NewProjectModal.js118
-rw-r--r--public/assets/javascripts/ui/site/StaffView.js47
-rw-r--r--public/assets/javascripts/util.js1
-rw-r--r--public/assets/javascripts/vendor/polyfill.js3
-rwxr-xr-xpublic/assets/stylesheets/app.css454
-rwxr-xr-xpublic/assets/stylesheets/ionicons.css884
-rw-r--r--public/assets/stylesheets/staff.css40
-rw-r--r--public/assets/test/bg.html1
-rw-r--r--public/assets/test/intersect.html5
-rw-r--r--public/assets/test/intersect2.html12
-rw-r--r--public/assets/test/intersect3.html12
-rw-r--r--public/assets/test/orbit.html154
-rw-r--r--public/assets/test/ortho.html290
-rw-r--r--public/assets/test/ortho2.html374
-rw-r--r--public/assets/test/ortho3.html258
-rw-r--r--public/assets/test/ortho4.html303
-rw-r--r--public/assets/test/static.html152
-rw-r--r--public/assets/test/surface.html5
-rw-r--r--server/fetch.js41
-rw-r--r--server/index.js42
-rw-r--r--server/lib/api/blueprint.js142
-rw-r--r--server/lib/api/index.js2
-rw-r--r--server/lib/api/layouts.js17
-rw-r--r--server/lib/api/profile.js1
-rw-r--r--server/lib/api/projects.js18
-rw-r--r--server/lib/api/rooms.js139
-rw-r--r--server/lib/api/subscription.js206
-rw-r--r--server/lib/auth/index.js15
-rw-r--r--server/lib/auth/mail.js2
-rw-r--r--server/lib/middleware.js84
-rw-r--r--server/lib/schemas/Blueprint.js66
-rw-r--r--server/lib/schemas/Layout.js3
-rw-r--r--server/lib/schemas/Media.js7
-rw-r--r--server/lib/schemas/Plan.js44
-rw-r--r--server/lib/schemas/Project.js4
-rw-r--r--server/lib/schemas/Subscription.js31
-rw-r--r--server/lib/schemas/User.js9
-rw-r--r--server/lib/upload.js11
-rw-r--r--server/lib/util.js4
-rw-r--r--server/lib/views/index.js60
-rw-r--r--server/lib/views/staff.js545
-rw-r--r--server/lib/views/staff/defaults.js6
-rw-r--r--server/lib/views/staff/fields.js10
-rw-r--r--server/lib/views/staff/helpers.js59
-rw-r--r--server/lib/views/staff/index.js511
-rw-r--r--server/lib/views/staff/middleware.js476
-rw-r--r--server/lib/webhook/index.js44
-rw-r--r--server/lib/webhook/recurly-config.js6
-rw-r--r--server/lib/webhook/webhook.js175
-rw-r--r--server/repl.js2
-rw-r--r--views/about/_blank.ejs4
-rw-r--r--views/about/_old_plans.ejs63
-rw-r--r--views/about/_plans.ejs121
-rw-r--r--views/about/about.ejs45
-rw-r--r--views/about/brochure.ejs25
-rw-r--r--views/about/howto.ejs4
-rw-r--r--views/about/privacy.ejs27
-rw-r--r--views/about/terms.ejs27
-rw-r--r--views/blueprint.ejs30
-rw-r--r--views/builder.ejs18
-rw-r--r--views/controls/blueprint/editor.ejs36
-rw-r--r--views/controls/blueprint/info.ejs30
-rw-r--r--views/controls/blueprint/notice.ejs4
-rw-r--r--views/controls/blueprint/scaler.ejs48
-rw-r--r--views/controls/blueprint/settings.ejs18
-rw-r--r--views/controls/blueprint/toolbar.ejs42
-rw-r--r--views/controls/builder/info.ejs4
-rw-r--r--views/controls/builder/settings.ejs2
-rw-r--r--views/controls/builder/toolbar.ejs6
-rw-r--r--views/controls/editor/media-drawer.ejs4
-rw-r--r--views/controls/editor/media-editor.ejs8
-rw-r--r--views/controls/editor/sculpture.ejs42
-rw-r--r--views/controls/editor/settings.ejs6
-rw-r--r--views/controls/editor/toolbar.ejs14
-rw-r--r--views/controls/editor/wallpaper.ejs2
-rw-r--r--views/controls/reader/about-room.ejs2
-rw-r--r--views/docs.ejs2
-rwxr-xr-xviews/editor.ejs3
-rwxr-xr-xviews/home.ejs31
-rw-r--r--views/modal.ejs4
-rw-r--r--views/partials/edit-profile.ejs2
-rw-r--r--views/partials/edit-subscription.ejs78
-rw-r--r--views/partials/footer.ejs6
-rw-r--r--views/partials/header.ejs7
-rw-r--r--views/partials/scripts.ejs47
-rw-r--r--views/profile.ejs86
-rw-r--r--views/projects/layouts-modal.ejs5
-rw-r--r--views/reader.ejs2
-rw-r--r--views/staff/_blueprints.ejs21
-rw-r--r--views/staff/_header.ejs2
-rw-r--r--views/staff/_layouts.ejs22
-rw-r--r--views/staff/_nav.ejs10
-rw-r--r--views/staff/_pagination.ejs2
-rw-r--r--views/staff/_users.ejs21
-rw-r--r--views/staff/blueprints/index.ejs13
-rw-r--r--views/staff/blueprints/show.ejs59
-rw-r--r--views/staff/blueprints/show_404.ejs9
-rw-r--r--views/staff/index.ejs6
-rw-r--r--views/staff/layouts/index.ejs13
-rw-r--r--views/staff/layouts/show.ejs61
-rw-r--r--views/staff/layouts/show_404.ejs9
-rw-r--r--views/staff/media/index.ejs7
-rw-r--r--views/staff/media/show.ejs7
-rw-r--r--views/staff/media/show_404.ejs9
-rw-r--r--views/staff/plans/_form.ejs154
-rw-r--r--views/staff/plans/edit.ejs13
-rw-r--r--views/staff/plans/index.ejs65
-rw-r--r--views/staff/plans/new.ejs13
-rw-r--r--views/staff/projects/index.ejs7
-rw-r--r--views/staff/projects/show.ejs9
-rw-r--r--views/staff/projects/show_404.ejs7
-rw-r--r--views/staff/subscriptions/index.ejs39
-rw-r--r--views/staff/subscriptions/show.ejs12
-rw-r--r--views/staff/users/index.ejs7
-rw-r--r--views/staff/users/media.ejs13
-rw-r--r--views/staff/users/show.ejs46
-rw-r--r--views/staff/users/show_404.ejs14
214 files changed, 14561 insertions, 2249 deletions
diff --git a/.gitignore b/.gitignore
index 50f54f1..701d2ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,8 @@ config.json
app.concat.js
app.min.js
+static.concat.js
+static.min.js
+
+.env
+
diff --git a/Gruntfile.js b/Gruntfile.js
index f62cc82..755e93f 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -9,10 +9,11 @@ module.exports = function(grunt) {
js: {
src: [
"public/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js",
- "public/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js",
+ "public/assets/javascripts/vendor/bower_components/lodash/lodash.min.js",
"public/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js",
"public/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js",
"public/assets/javascripts/vendor/bower_components/marked/lib/marked.js",
+ "public/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js",
"public/assets/javascripts/vendor/tube.js",
"public/assets/javascripts/vendor/loader.js",
"public/assets/javascripts/vendor/polyfill.js",
@@ -31,6 +32,7 @@ module.exports = function(grunt) {
"public/assets/javascripts/mx/primitives/mx.youtube.js",
"public/assets/javascripts/mx/primitives/mx.vimeo.js",
"public/assets/javascripts/mx/primitives/mx.soundcloud.js",
+ "public/assets/javascripts/mx/primitives/mx.grid.js",
"public/assets/javascripts/rectangles/_env.js",
@@ -68,6 +70,7 @@ module.exports = function(grunt) {
"public/assets/javascripts/rectangles/engine/scenery/move.js",
"public/assets/javascripts/rectangles/engine/scenery/resize.js",
"public/assets/javascripts/rectangles/engine/scenery/randomize.js",
+ "public/assets/javascripts/rectangles/engine/scenery/sound.js",
"public/assets/javascripts/rectangles/engine/scenery/undo.js",
"public/assets/javascripts/rectangles/engine/scenery/types/_object.js",
"public/assets/javascripts/rectangles/engine/scenery/types/image.js",
@@ -75,9 +78,15 @@ module.exports = function(grunt) {
"public/assets/javascripts/rectangles/engine/scenery/types/video.js",
"public/assets/javascripts/rectangles/engine/scenery/types/audio.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/move.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/resize.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/types/_object.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/types/image.js",
+
"public/assets/javascripts/rectangles/engine/map/_map.js",
- "public/assets/javascripts/rectangles/engine/map/ui_editor.js",
- "public/assets/javascripts/rectangles/engine/map/ui_minimap.js",
+ "public/assets/javascripts/rectangles/engine/map/ui/editor.js",
+ "public/assets/javascripts/rectangles/engine/map/ui/minimap.js",
"public/assets/javascripts/rectangles/engine/map/draw.js",
"public/assets/javascripts/ui/lib/View.js",
@@ -99,6 +108,7 @@ module.exports = function(grunt) {
"public/assets/javascripts/ui/site/LayoutsModal.js",
"public/assets/javascripts/ui/site/EditProjectModal.js",
"public/assets/javascripts/ui/site/EditProfileModal.js",
+ "public/assets/javascripts/ui/site/EditSubscriptionModal.js",
"public/assets/javascripts/ui/site/DocumentModal.js",
"public/assets/javascripts/ui/site/HomeView.js",
@@ -121,6 +131,7 @@ module.exports = function(grunt) {
"public/assets/javascripts/ui/editor/MediaUpload.js",
"public/assets/javascripts/ui/editor/MediaViewer.js",
"public/assets/javascripts/ui/editor/Presets.js",
+ "public/assets/javascripts/ui/editor/SculptureEditor.js",
"public/assets/javascripts/ui/editor/TextEditor.js",
"public/assets/javascripts/ui/editor/WallpaperPicker.js",
@@ -136,8 +147,129 @@ module.exports = function(grunt) {
"public/assets/javascripts/defaults.js",
],
dest: 'public/assets/javascripts/app.concat.js',
+ },
+
+ // this builds a static version of the vvalls code, suitable for embedding
+ // in another website. see assets/test/static.html
+ 'static': {
+ src: [
+ "public/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js",
+ "public/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js",
+ "public/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js",
+ "public/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js",
+ "public/assets/javascripts/vendor/bower_components/marked/lib/marked.js",
+ "public/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js",
+ "public/assets/javascripts/vendor/tube.js",
+ "public/assets/javascripts/vendor/loader.js",
+ "public/assets/javascripts/vendor/polyfill.js",
+ "public/assets/javascripts/vendor/froogaloop.js",
+ "public/assets/javascripts/util.js",
+
+ "public/assets/javascripts/mx/mx.js",
+ "public/assets/javascripts/mx/extensions/mx.scene.js",
+ "public/assets/javascripts/mx/extensions/mx.movements.js",
+ "public/assets/javascripts/mx/extensions/mx.movementsMobile.js",
+ "public/assets/javascripts/mx/primitives/mx.image.js",
+ "public/assets/javascripts/mx/primitives/mx.text.js",
+ "public/assets/javascripts/mx/primitives/mx.video.js",
+ "public/assets/javascripts/mx/primitives/mx.youtube.js",
+ "public/assets/javascripts/mx/primitives/mx.vimeo.js",
+ "public/assets/javascripts/mx/primitives/mx.soundcloud.js",
+ "public/assets/javascripts/mx/primitives/mx.grid.js",
+
+ "public/assets/javascripts/rectangles/_env.js",
+
+ "public/assets/javascripts/rectangles/util/constants.js",
+ "public/assets/javascripts/rectangles/util/colors.js",
+ "public/assets/javascripts/rectangles/util/coords.js",
+ "public/assets/javascripts/rectangles/util/debug.js",
+ "public/assets/javascripts/rectangles/util/keys.js",
+ "public/assets/javascripts/rectangles/util/measurement.js",
+ "public/assets/javascripts/rectangles/util/minotaur.js",
+ "public/assets/javascripts/rectangles/util/mouse.js",
+ "public/assets/javascripts/rectangles/util/permissions.js",
+ "public/assets/javascripts/rectangles/util/sort.js",
+ "public/assets/javascripts/rectangles/util/uid.js",
+ "public/assets/javascripts/rectangles/util/undostack.js",
+ "public/assets/javascripts/rectangles/util/wheel.js",
+
+ "public/assets/javascripts/rectangles/models/vec2.js",
+ "public/assets/javascripts/rectangles/models/vec3.js",
+ "public/assets/javascripts/rectangles/models/rect.js",
+ "public/assets/javascripts/rectangles/models/surface.js",
+ "public/assets/javascripts/rectangles/models/tree.js",
+ "public/assets/javascripts/rectangles/models/room.js",
+ "public/assets/javascripts/rectangles/models/wall.js",
+ "public/assets/javascripts/rectangles/models/floor.js",
+
+ "public/assets/javascripts/rectangles/engine/rooms/_rooms.js",
+ "public/assets/javascripts/rectangles/engine/rooms/_walls.js",
+ "public/assets/javascripts/rectangles/engine/rooms/builder.js",
+ "public/assets/javascripts/rectangles/engine/rooms/clipper.js",
+ "public/assets/javascripts/rectangles/engine/rooms/grouper.js",
+ "public/assets/javascripts/rectangles/engine/rooms/mover.js",
+
+ "public/assets/javascripts/rectangles/engine/scenery/_scenery.js",
+ "public/assets/javascripts/rectangles/engine/scenery/move.js",
+ "public/assets/javascripts/rectangles/engine/scenery/resize.js",
+ "public/assets/javascripts/rectangles/engine/scenery/randomize.js",
+ "public/assets/javascripts/rectangles/engine/scenery/sound.js",
+ "public/assets/javascripts/rectangles/engine/scenery/undo.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/_object.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/image.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/text.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/video.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/audio.js",
+
+ "public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/move.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/resize.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/types/_object.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/types/image.js",
+
+ "public/assets/javascripts/rectangles/engine/map/_map.js",
+ "public/assets/javascripts/rectangles/engine/map/ui/editor.js",
+ "public/assets/javascripts/rectangles/engine/map/ui/minimap.js",
+ "public/assets/javascripts/rectangles/engine/map/draw.js",
+
+ "public/assets/javascripts/ui/lib/View.js",
+ "public/assets/javascripts/ui/lib/Router.js",
+ "public/assets/javascripts/ui/lib/ModalView.js",
+
+ "public/assets/javascripts/ui/reader/ReaderView.js",
+ "public/assets/javascripts/ui/reader/ShareView.js",
+ "public/assets/javascripts/ui/reader/EmbedView.js",
+ "public/assets/javascripts/ui/reader/MediaPlayer.js",
+ "public/assets/javascripts/ui/reader/Tracker.js",
+
+ "public/assets/javascripts/ui/reader/_router.js",
+
+ "public/assets/javascripts/app.js",
+ "public/assets/javascripts/defaults.js",
+ ],
+ dest: 'public/assets/javascripts/static.concat.js',
}
+
+
},
+ copy: {
+ concat: {
+ files: [
+ {
+ src: 'public/assets/javascripts/app.concat.js',
+ dest: 'public/assets/javascripts/app.min.js',
+ },
+ ]
+ },
+ 'static': {
+ files: [
+ {
+ src: 'public/assets/javascripts/static.concat.js',
+ dest: 'public/assets/javascripts/static.min.js',
+ },
+ ]
+ },
+ },
uglify: {
options: {
banner: '/* vvalls by okfocus 2015 */\n'
@@ -145,20 +277,31 @@ module.exports = function(grunt) {
js: {
src: 'public/assets/javascripts/app.concat.js',
dest: 'public/assets/javascripts/app.min.js',
+ },
+ 'static': {
+ src: 'public/assets/javascripts/static.concat.js',
+ dest: 'public/assets/javascripts/static.min.js',
}
},
clean: {
- release: ["public/assets/javascripts/app.concat.js"],
+ release: [
+ "public/assets/javascripts/static.concat.js",
+ "public/assets/javascripts/app.concat.js",
+ ],
}
});
// Load tasks that we'll be using
grunt.loadNpmTasks('grunt-contrib-concat');
+ grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-clean');
// Default task(s).
- grunt.registerTask('js', ['concat:js', 'uglify:js', 'clean:release']);
- grunt.registerTask('default', ['js']);
+ grunt.registerTask('js', ['concat:js', 'uglify:js', 'clean:release']);
+ grunt.registerTask('js-test', ['concat:js', 'copy:concat']);
+ grunt.registerTask('static', ['concat:static', 'uglify:static', 'clean:release']);
+ grunt.registerTask('static-test', ['concat:static', 'copy:static']);
+ grunt.registerTask('default', ['js']);
};
diff --git a/Procfile b/Procfile
index 983db91..bab08fb 100644
--- a/Procfile
+++ b/Procfile
@@ -1 +1,2 @@
-web: node server \ No newline at end of file
+web: node server
+webhook: node server/lib/webhook \ No newline at end of file
diff --git a/README.md b/README.md
index 1c95b14..23dfc2c 100644
--- a/README.md
+++ b/README.md
@@ -19,3 +19,20 @@ vvalls
| | .' | |/ | | \| | `. | |
+------+' +------+ +------+ +------+ `+------+
```
+
+Installing VValls
+=================
+
+1) Install mongodb, nodejs, npm (probably comes with node) and bower
+2) `git clone git@github.com:julescarbon/vvalls.git`
+3) `cd vvalls ; git checkout subscriptions`
+4) `npm install`
+5) `bower install`
+6) `cp config.json.example config.json`
+7) Start the mongod server (if it isn't running already)
+8) `node server`
+
+Server will be running on http://lvh.me:3000/
+
+To give yourself superuser access, visit http://lvh.me:3000/staff/authorize (development mode only)
+
diff --git a/bower.json b/bower.json
index 5f35d6c..e3e83ca 100644
--- a/bower.json
+++ b/bower.json
@@ -9,6 +9,7 @@
"fiber": "",
"jquery-jsonview": "1.2.0",
"prefixfree": "",
- "marked": "0.3.2"
+ "marked": "0.3.2",
+ "hidpi-canvas": "git://github.com/julescarbon/hidpi-canvas-polyfill.git#master"
}
}
diff --git a/config.json.example b/config.json.example
index 6028021..df4b86e 100644
--- a/config.json.example
+++ b/config.json.example
@@ -1,9 +1,10 @@
{
- "host": "lvh.me:3000",
- "hostName": "lvh.me",
- "port": 3000,
- "socketPort": 1337,
+ "host": "lvh.me:3000",
+ "hostName": "lvh.me",
+ "port": 3000,
+ "socketPort": 1337,
+ "webhookPort": 5000,
"databaseHost": "lvh.me",
- "pageSize": 10,
- "env": { "development": 1 }
+ "env": { "development": 1 },
+ "basicAuth": { "user": "vv", "pass": "ok" }
}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..98a5b7c
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2645 @@
+{
+ "name": "vvalls",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
+ "accepts": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.2.13.tgz",
+ "integrity": "sha1-5fHzkoxtlf2WVYw27D2dDeSm7Oo=",
+ "requires": {
+ "mime-types": "~2.1.6",
+ "negotiator": "0.5.3"
+ }
+ },
+ "active-x-obfuscator": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/active-x-obfuscator/-/active-x-obfuscator-0.0.1.tgz",
+ "integrity": "sha1-CJuJs3FF/x2ex0r2UwvlUmyuHxo=",
+ "requires": {
+ "zeparser": "0.0.5"
+ }
+ },
+ "addressparser": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-0.3.2.tgz",
+ "integrity": "sha1-WYc/Nej89sc2HBAjkmHXbhU0i7I="
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "dev": true
+ },
+ "argparse": {
+ "version": "0.1.16",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz",
+ "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=",
+ "dev": true,
+ "requires": {
+ "underscore": "~1.7.0",
+ "underscore.string": "~2.4.0"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
+ "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=",
+ "dev": true
+ },
+ "underscore.string": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz",
+ "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=",
+ "dev": true
+ }
+ }
+ },
+ "async": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz",
+ "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=",
+ "requires": {
+ "lodash": "^4.14.0"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+ }
+ }
+ },
+ "base64-url": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/base64-url/-/base64-url-1.2.1.tgz",
+ "integrity": "sha1-GZ/WYXAqDnt9yubgaYuwicUvbXg="
+ },
+ "base64id": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz",
+ "integrity": "sha1-As4P3u4M709ACA4ec+g08LG/zj8="
+ },
+ "basic-auth": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz",
+ "integrity": "sha1-Awk1sB3nyblKgksp8/zLdQ06UpA="
+ },
+ "basic-auth-connect": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz",
+ "integrity": "sha1-/bC0OWLKe0BFanwrtI/hc9otISI="
+ },
+ "batch": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.5.3.tgz",
+ "integrity": "sha1-PzQU84AyF0O/wQQvmoP/HVgk1GQ="
+ },
+ "bluebird": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
+ "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw="
+ },
+ "body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+ }
+ }
+ },
+ "bson": {
+ "version": "0.2.22",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-0.2.22.tgz",
+ "integrity": "sha1-/NoQPybQwHTVpS1Qkn24D9ArSzk=",
+ "requires": {
+ "nan": "~1.8"
+ }
+ },
+ "buffer-shims": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+ "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E="
+ },
+ "bufferjs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/bufferjs/-/bufferjs-1.1.0.tgz",
+ "integrity": "sha1-CV/6OcXmtAoheKEWnJ7/xYSnMgE=",
+ "optional": true
+ },
+ "busboy": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
+ "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
+ "requires": {
+ "dicer": "0.2.5",
+ "readable-stream": "1.1.x"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ }
+ }
+ },
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
+ },
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "dev": true
+ },
+ "coffee-script": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz",
+ "integrity": "sha1-FQ1rTLUiiUNp7+1qIQHCC8f0pPQ=",
+ "dev": true
+ },
+ "colors": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
+ "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz",
+ "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0="
+ },
+ "compressible": {
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.13.tgz",
+ "integrity": "sha1-DRAgq5JLL9tNYnmHXH1tq6a6p6k=",
+ "requires": {
+ "mime-db": ">= 1.33.0 < 2"
+ }
+ },
+ "compression": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.5.2.tgz",
+ "integrity": "sha1-sDuNhub4rSloPLqN+R3cb/x3s5U=",
+ "requires": {
+ "accepts": "~1.2.12",
+ "bytes": "2.1.0",
+ "compressible": "~2.0.5",
+ "debug": "~2.2.0",
+ "on-headers": "~1.0.0",
+ "vary": "~1.0.1"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.1.0.tgz",
+ "integrity": "sha1-rJPEEOL/ycx89LRks4KJBn9eR7Q="
+ },
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ }
+ }
+ },
+ "connect": {
+ "version": "2.30.2",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-2.30.2.tgz",
+ "integrity": "sha1-jam8vooFTT0xjXTf7JA7XDmhtgk=",
+ "requires": {
+ "basic-auth-connect": "1.0.0",
+ "body-parser": "~1.13.3",
+ "bytes": "2.1.0",
+ "compression": "~1.5.2",
+ "connect-timeout": "~1.6.2",
+ "content-type": "~1.0.1",
+ "cookie": "0.1.3",
+ "cookie-parser": "~1.3.5",
+ "cookie-signature": "1.0.6",
+ "csurf": "~1.8.3",
+ "debug": "~2.2.0",
+ "depd": "~1.0.1",
+ "errorhandler": "~1.4.2",
+ "express-session": "~1.11.3",
+ "finalhandler": "0.4.0",
+ "fresh": "0.3.0",
+ "http-errors": "~1.3.1",
+ "method-override": "~2.3.5",
+ "morgan": "~1.6.1",
+ "multiparty": "3.3.2",
+ "on-headers": "~1.0.0",
+ "parseurl": "~1.3.0",
+ "pause": "0.1.0",
+ "qs": "4.0.0",
+ "response-time": "~2.3.1",
+ "serve-favicon": "~2.3.0",
+ "serve-index": "~1.7.2",
+ "serve-static": "~1.10.0",
+ "type-is": "~1.6.6",
+ "utils-merge": "1.0.0",
+ "vhost": "~3.0.1"
+ },
+ "dependencies": {
+ "body-parser": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.13.3.tgz",
+ "integrity": "sha1-wIzzMMM1jhUQFqBXRvE/ApyX+pc=",
+ "requires": {
+ "bytes": "2.1.0",
+ "content-type": "~1.0.1",
+ "debug": "~2.2.0",
+ "depd": "~1.0.1",
+ "http-errors": "~1.3.1",
+ "iconv-lite": "0.4.11",
+ "on-finished": "~2.3.0",
+ "qs": "4.0.0",
+ "raw-body": "~2.1.2",
+ "type-is": "~1.6.6"
+ }
+ },
+ "bytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.1.0.tgz",
+ "integrity": "sha1-rJPEEOL/ycx89LRks4KJBn9eR7Q="
+ },
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.11",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz",
+ "integrity": "sha1-LstC/SlHRJIiCaLnxATayHk9it4="
+ },
+ "qs": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz",
+ "integrity": "sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc="
+ },
+ "raw-body": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz",
+ "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=",
+ "requires": {
+ "bytes": "2.4.0",
+ "iconv-lite": "0.4.13",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
+ "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
+ },
+ "iconv-lite": {
+ "version": "0.4.13",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
+ "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI="
+ }
+ }
+ },
+ "type-is": {
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.18"
+ }
+ }
+ }
+ },
+ "connect-mongo": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-0.4.2.tgz",
+ "integrity": "sha1-qYF6miKdeQRgqwv5Ru4M6Kw8y6c=",
+ "requires": {
+ "mongodb": "1.4.x"
+ }
+ },
+ "connect-timeout": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/connect-timeout/-/connect-timeout-1.6.2.tgz",
+ "integrity": "sha1-3ppexh4zoStu2qt7XwYumMWZuI4=",
+ "requires": {
+ "debug": "~2.2.0",
+ "http-errors": "~1.3.1",
+ "ms": "0.7.1",
+ "on-headers": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ }
+ }
+ },
+ "content-disposition": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.0.tgz",
+ "integrity": "sha1-QoT+auBjCHRjnkToCkGMKTQTXp4="
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz",
+ "integrity": "sha1-5zSlwUF/zkctWu+Cw4HKu2TRpDU="
+ },
+ "cookie-parser": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.3.5.tgz",
+ "integrity": "sha1-nXVVcPtdF4kHcSJ6AjFNm+fPg1Y=",
+ "requires": {
+ "cookie": "0.1.3",
+ "cookie-signature": "1.0.6"
+ }
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "crc": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/crc/-/crc-3.3.0.tgz",
+ "integrity": "sha1-+mIuG8OIvyVzCQgta2UgDOZwkLo="
+ },
+ "csrf": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/csrf/-/csrf-3.0.6.tgz",
+ "integrity": "sha1-thEg3c7q/JHnbtUxO7XAsmZ7cQo=",
+ "requires": {
+ "rndm": "1.2.0",
+ "tsscmp": "1.0.5",
+ "uid-safe": "2.1.4"
+ }
+ },
+ "csurf": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.8.3.tgz",
+ "integrity": "sha1-I/KhO/HY/OHQyZZYg5RELLqGpWo=",
+ "requires": {
+ "cookie": "0.1.3",
+ "cookie-signature": "1.0.6",
+ "csrf": "~3.0.0",
+ "http-errors": "~1.3.1"
+ }
+ },
+ "dateformat": {
+ "version": "1.0.2-1.2.3",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz",
+ "integrity": "sha1-sCIMAt6YYXQztyhRz0fePfLNvuk=",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "depd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz",
+ "integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "dicer": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
+ "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
+ "requires": {
+ "readable-stream": "1.1.x",
+ "streamsearch": "0.1.2"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ }
+ }
+ },
+ "diff": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.7.tgz",
+ "integrity": "sha1-JLuwAcSn1VIhaefKvbLCgU7ZHPQ=",
+ "dev": true
+ },
+ "dom-serializer": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
+ "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "~1.1.1",
+ "entities": "~1.1.1"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+ "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
+ "dev": true
+ }
+ }
+ },
+ "domelementtype": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+ "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
+ "dev": true
+ },
+ "domhandler": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz",
+ "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "domutils": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+ "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "dotenv": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+ "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "ejs": {
+ "version": "0.8.8",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-0.8.8.tgz",
+ "integrity": "sha1-/9xW3MNdApJt1QrRNDm7xUBh1Zg="
+ },
+ "emailjs": {
+ "version": "0.3.16",
+ "resolved": "https://registry.npmjs.org/emailjs/-/emailjs-0.3.16.tgz",
+ "integrity": "sha1-8WJzU1LOe2YVpdgRcUBR+Q8jMx0=",
+ "requires": {
+ "addressparser": "^0.3.2",
+ "bufferjs": "=1.1.0",
+ "mimelib": "0.2.14",
+ "moment": "= 1.7.0",
+ "starttls": "0.2.1"
+ },
+ "dependencies": {
+ "moment": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-1.7.0.tgz",
+ "integrity": "sha1-bz1zpEbGvWrxuZOAHQuAce+tXig="
+ }
+ }
+ },
+ "encoding": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+ "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+ "requires": {
+ "iconv-lite": "~0.4.13"
+ }
+ },
+ "entities": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+ "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
+ "dev": true
+ },
+ "errorhandler": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.4.3.tgz",
+ "integrity": "sha1-t7cO2PNZ6duICS8tIMD4MUIK2D8=",
+ "requires": {
+ "accepts": "~1.3.0",
+ "escape-html": "~1.0.3"
+ },
+ "dependencies": {
+ "accepts": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+ "requires": {
+ "mime-types": "~2.1.18",
+ "negotiator": "0.6.1"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ }
+ }
+ },
+ "es6-promise": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
+ "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q="
+ },
+ "escape-html": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.2.tgz",
+ "integrity": "sha1-130y+pjjjC9BroXpJ44ODmuhAiw="
+ },
+ "esprima": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
+ "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz",
+ "integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg="
+ },
+ "eventemitter2": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+ "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
+ "dev": true
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+ "dev": true
+ },
+ "express": {
+ "version": "3.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-3.21.2.tgz",
+ "integrity": "sha1-DCkD7lxU5j1lqWFwdkcDVQZlo94=",
+ "requires": {
+ "basic-auth": "~1.0.3",
+ "commander": "2.6.0",
+ "connect": "2.30.2",
+ "content-disposition": "0.5.0",
+ "content-type": "~1.0.1",
+ "cookie": "0.1.3",
+ "cookie-signature": "1.0.6",
+ "debug": "~2.2.0",
+ "depd": "~1.0.1",
+ "escape-html": "1.0.2",
+ "etag": "~1.7.0",
+ "fresh": "0.3.0",
+ "merge-descriptors": "1.0.0",
+ "methods": "~1.1.1",
+ "mkdirp": "0.5.1",
+ "parseurl": "~1.3.0",
+ "proxy-addr": "~1.0.8",
+ "range-parser": "~1.0.2",
+ "send": "0.13.0",
+ "utils-merge": "1.0.0",
+ "vary": "~1.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ }
+ }
+ },
+ "express-session": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.11.3.tgz",
+ "integrity": "sha1-XMmPP1/4Ttg1+Ry/CqvQxxB0AK8=",
+ "requires": {
+ "cookie": "0.1.3",
+ "cookie-signature": "1.0.6",
+ "crc": "3.3.0",
+ "debug": "~2.2.0",
+ "depd": "~1.0.1",
+ "on-headers": "~1.0.0",
+ "parseurl": "~1.3.0",
+ "uid-safe": "~2.0.0",
+ "utils-merge": "1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "uid-safe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.0.0.tgz",
+ "integrity": "sha1-p/PGymSh9qXQTsDvPkw9U2cxcTc=",
+ "requires": {
+ "base64-url": "1.2.1"
+ }
+ }
+ }
+ },
+ "express-subdomain-handler": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/express-subdomain-handler/-/express-subdomain-handler-0.1.0.tgz",
+ "integrity": "sha1-1+M63qsJeKOX2m6knxm5JmnvblM="
+ },
+ "express-subdomains": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/express-subdomains/-/express-subdomains-0.0.5.tgz",
+ "integrity": "sha1-/6vADwkhu0g5GPF9pdOB9UWSkGQ=",
+ "requires": {
+ "sequence": "~2.1.1"
+ }
+ },
+ "express-xml-bodyparser": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/express-xml-bodyparser/-/express-xml-bodyparser-0.0.6.tgz",
+ "integrity": "sha1-iOophe14wpQVNTBp3YiCapPLygk=",
+ "requires": {
+ "xml2js": "~0.4.1"
+ }
+ },
+ "faye-websocket": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.4.4.tgz",
+ "integrity": "sha1-wUxbO/FNdBf/v9mQwKdJXNnzN7w=",
+ "dev": true
+ },
+ "finalhandler": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz",
+ "integrity": "sha1-llpS2ejQXSuFdUhUH7ibU6JJfZs=",
+ "requires": {
+ "debug": "~2.2.0",
+ "escape-html": "1.0.2",
+ "on-finished": "~2.3.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ }
+ }
+ },
+ "findup-sync": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz",
+ "integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=",
+ "dev": true,
+ "requires": {
+ "glob": "~3.2.9",
+ "lodash": "~2.4.1"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "3.2.11",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
+ "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
+ "dev": true,
+ "requires": {
+ "inherits": "2",
+ "minimatch": "0.3"
+ }
+ },
+ "minimatch": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
+ "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "2",
+ "sigmund": "~1.0.0"
+ }
+ }
+ }
+ },
+ "foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "fresh": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz",
+ "integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8="
+ },
+ "gaze": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.4.3.tgz",
+ "integrity": "sha1-5Tj0/15P5kj0c6l+HrslPS3hJ7U=",
+ "dev": true,
+ "requires": {
+ "globule": "~0.1.0"
+ }
+ },
+ "getobject": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
+ "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
+ "dev": true
+ },
+ "globule": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz",
+ "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=",
+ "dev": true,
+ "requires": {
+ "glob": "~3.1.21",
+ "lodash": "~1.0.1",
+ "minimatch": "~0.2.11"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "3.1.21",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
+ "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "~1.2.0",
+ "inherits": "1",
+ "minimatch": "~0.2.11"
+ }
+ },
+ "graceful-fs": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz",
+ "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=",
+ "dev": true
+ },
+ "inherits": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz",
+ "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=",
+ "dev": true
+ },
+ "lodash": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz",
+ "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
+ "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "2",
+ "sigmund": "~1.0.0"
+ }
+ }
+ }
+ },
+ "growl": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz",
+ "integrity": "sha1-3i1mE20ALhErpw8/EMMc98NQsto=",
+ "dev": true
+ },
+ "grunt": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz",
+ "integrity": "sha1-VpN81RlDJK3/bSB2MYMqnWuk5/A=",
+ "dev": true,
+ "requires": {
+ "async": "~0.1.22",
+ "coffee-script": "~1.3.3",
+ "colors": "~0.6.2",
+ "dateformat": "1.0.2-1.2.3",
+ "eventemitter2": "~0.4.13",
+ "exit": "~0.1.1",
+ "findup-sync": "~0.1.2",
+ "getobject": "~0.1.0",
+ "glob": "~3.1.21",
+ "grunt-legacy-log": "~0.1.0",
+ "grunt-legacy-util": "~0.2.0",
+ "hooker": "~0.2.3",
+ "iconv-lite": "~0.2.11",
+ "js-yaml": "~2.0.5",
+ "lodash": "~0.9.2",
+ "minimatch": "~0.2.12",
+ "nopt": "~1.0.10",
+ "rimraf": "~2.2.8",
+ "underscore.string": "~2.2.1",
+ "which": "~1.0.5"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.1.22",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz",
+ "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=",
+ "dev": true
+ },
+ "glob": {
+ "version": "3.1.21",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
+ "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "~1.2.0",
+ "inherits": "1",
+ "minimatch": "~0.2.11"
+ }
+ },
+ "graceful-fs": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz",
+ "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz",
+ "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=",
+ "dev": true
+ },
+ "inherits": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz",
+ "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=",
+ "dev": true
+ },
+ "lodash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz",
+ "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
+ "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "2",
+ "sigmund": "~1.0.0"
+ }
+ },
+ "nopt": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "rimraf": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
+ "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-clean": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.5.0.tgz",
+ "integrity": "sha1-9T397ghJsce0Dp67umn0jExgecU=",
+ "dev": true,
+ "requires": {
+ "rimraf": "~2.2.1"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
+ "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-concat": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-0.3.0.tgz",
+ "integrity": "sha1-SPoNQzbSm2U62CJaa9b4VrRIPjI=",
+ "dev": true
+ },
+ "grunt-contrib-copy": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-0.5.0.tgz",
+ "integrity": "sha1-QQB1rEWlhWuhkbHMclclRQ1KAhU=",
+ "dev": true
+ },
+ "grunt-contrib-uglify": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-0.2.7.tgz",
+ "integrity": "sha1-5r2lHgxAoUWfbOrUI8Ze/XJaG/c=",
+ "dev": true,
+ "requires": {
+ "grunt-lib-contrib": "~0.6.1",
+ "uglify-js": "~2.4.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "2.4.24",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.24.tgz",
+ "integrity": "sha1-+tV1XB4Vd2WLsG/5q25UjJW+vW4=",
+ "dev": true,
+ "requires": {
+ "async": "~0.2.6",
+ "source-map": "0.1.34",
+ "uglify-to-browserify": "~1.0.0",
+ "yargs": "~3.5.4"
+ }
+ }
+ }
+ },
+ "grunt-contrib-watch": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-0.5.3.tgz",
+ "integrity": "sha1-fZ61Rl1Qb6FPqspH5uh5CoLBye4=",
+ "dev": true,
+ "requires": {
+ "gaze": "~0.4.0",
+ "tiny-lr": "0.0.4"
+ }
+ },
+ "grunt-dentist": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/grunt-dentist/-/grunt-dentist-0.3.6.tgz",
+ "integrity": "sha1-AaBsICHukFi3JWWdi+sNs+Zlcrg=",
+ "dev": true,
+ "requires": {
+ "htmlparser2": "^3.9.0"
+ }
+ },
+ "grunt-legacy-log": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz",
+ "integrity": "sha1-7ClCboAwIa9ZAp+H0vnNczWgVTE=",
+ "dev": true,
+ "requires": {
+ "colors": "~0.6.2",
+ "grunt-legacy-log-utils": "~0.1.1",
+ "hooker": "~0.2.3",
+ "lodash": "~2.4.1",
+ "underscore.string": "~2.3.3"
+ },
+ "dependencies": {
+ "underscore.string": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
+ "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-legacy-log-utils": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz",
+ "integrity": "sha1-wHBrndkGThFvNvI/5OawSGcsD34=",
+ "dev": true,
+ "requires": {
+ "colors": "~0.6.2",
+ "lodash": "~2.4.1",
+ "underscore.string": "~2.3.3"
+ },
+ "dependencies": {
+ "underscore.string": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
+ "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-legacy-util": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz",
+ "integrity": "sha1-kzJIhNv343qf98Am3/RR2UqeVUs=",
+ "dev": true,
+ "requires": {
+ "async": "~0.1.22",
+ "exit": "~0.1.1",
+ "getobject": "~0.1.0",
+ "hooker": "~0.2.3",
+ "lodash": "~0.9.2",
+ "underscore.string": "~2.2.1",
+ "which": "~1.0.5"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.1.22",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz",
+ "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=",
+ "dev": true
+ },
+ "lodash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz",
+ "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-lib-contrib": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.6.1.tgz",
+ "integrity": "sha1-P1att9oG6BR5XuJBWw6+X7iQPrs=",
+ "dev": true,
+ "requires": {
+ "zlib-browserify": "0.0.1"
+ }
+ },
+ "hooker": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
+ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
+ "dev": true
+ },
+ "hooks-fixed": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.2.tgz",
+ "integrity": "sha512-YurCM4gQSetcrhwEtpQHhQ4M7Zo7poNGqY4kQGeBS6eZtOcT3tnNs01ThFa0jYBByAiYt1MjMjP/YApG0EnAvQ=="
+ },
+ "html-entities": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.0.10.tgz",
+ "integrity": "sha1-DepZEw3VDfFU6CxM9x0Iwsnclos="
+ },
+ "htmlparser2": {
+ "version": "3.9.2",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
+ "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^1.3.0",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "http-errors": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz",
+ "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=",
+ "requires": {
+ "inherits": "~2.0.1",
+ "statuses": "1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+ },
+ "indexof": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "inspect": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/inspect/-/inspect-0.0.2.tgz",
+ "integrity": "sha1-8HODi1RvnAuWo6d0TyR/iHwib4s="
+ },
+ "intro.js": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/intro.js/-/intro.js-0.9.0.tgz",
+ "integrity": "sha1-WXLZ7kfdhEaJ0pEfRGUKHM4gzhE="
+ },
+ "ipaddr.js": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz",
+ "integrity": "sha1-X6eM8wG4JceKvDBC2BJyMEnqI8c="
+ },
+ "is": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/is/-/is-0.2.7.tgz",
+ "integrity": "sha1-OzSixI81mXLzUEKEkZOucmS2NWI="
+ },
+ "is-object": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-0.1.2.tgz",
+ "integrity": "sha1-AO+8CIFsM8/ErIJR0TLhDcZQmNc="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "jade": {
+ "version": "0.26.3",
+ "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz",
+ "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=",
+ "dev": true,
+ "requires": {
+ "commander": "0.6.1",
+ "mkdirp": "0.3.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz",
+ "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz",
+ "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=",
+ "dev": true
+ }
+ }
+ },
+ "js-yaml": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz",
+ "integrity": "sha1-olrmUJmZ6X3yeMZxnaEb0Gh3Q6g=",
+ "dev": true,
+ "requires": {
+ "argparse": "~ 0.1.11",
+ "esprima": "~ 1.0.2"
+ }
+ },
+ "kareem": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.5.0.tgz",
+ "integrity": "sha1-4+QQHZ3P3imXadr0tNtk2JXRdEg="
+ },
+ "kerberos": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/kerberos/-/kerberos-0.0.11.tgz",
+ "integrity": "sha1-yymJHCHCKsGV8xQLl90SIE/qfcI=",
+ "optional": true,
+ "requires": {
+ "nan": "~1.8"
+ }
+ },
+ "knox": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/knox/-/knox-0.9.2.tgz",
+ "integrity": "sha1-NzZZNmniTwJP2vcjtqHcSv2DmnE=",
+ "requires": {
+ "debug": "^1.0.2",
+ "mime": "*",
+ "once": "^1.3.0",
+ "stream-counter": "^1.0.0",
+ "xml2js": "^0.4.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.5.tgz",
+ "integrity": "sha1-9yQSF0MPmd7EwrRz6rkiKOh0wqw=",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "stream-counter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-1.0.0.tgz",
+ "integrity": "sha1-kc8lac5NxQYf6816yyY5SloRR1E="
+ }
+ }
+ },
+ "lodash": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+ "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4="
+ },
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+ },
+ "lru-cache": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
+ "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
+ "dev": true
+ },
+ "marked": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
+ "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg=="
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.0.tgz",
+ "integrity": "sha1-IWnPdTjhsMyH+4jhUC2EdLv3mGQ="
+ },
+ "method-override": {
+ "version": "2.3.10",
+ "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.10.tgz",
+ "integrity": "sha1-49r41d7hDdLc59SuiNYrvud0drQ=",
+ "requires": {
+ "debug": "2.6.9",
+ "methods": "~1.1.2",
+ "parseurl": "~1.3.2",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ }
+ }
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "mime": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
+ "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
+ },
+ "mime-db": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
+ },
+ "mime-types": {
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "requires": {
+ "mime-db": "~1.33.0"
+ }
+ },
+ "mimelib": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.2.14.tgz",
+ "integrity": "sha1-KhqnJL0ZC4W9Um5jF6thBu39aDE=",
+ "requires": {
+ "addressparser": "~0.2.0",
+ "encoding": "~0.1"
+ },
+ "dependencies": {
+ "addressparser": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-0.2.1.tgz",
+ "integrity": "sha1-0RpbLu2gTP7+vfMZbBCuE9ts1gc="
+ }
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "mocha": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-1.20.1.tgz",
+ "integrity": "sha1-80ODLZ/gx9l8ZPxwRI9RNt+f7Vs=",
+ "dev": true,
+ "requires": {
+ "commander": "2.0.0",
+ "debug": "*",
+ "diff": "1.0.7",
+ "glob": "3.2.3",
+ "growl": "1.7.x",
+ "jade": "0.26.3",
+ "mkdirp": "0.3.5"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz",
+ "integrity": "sha1-0bhvkB+LZL2UG96tr5JFMDk76Sg=",
+ "dev": true
+ },
+ "glob": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz",
+ "integrity": "sha1-4xPusknHr/qlxHUoaw4RW1mDlGc=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "~2.0.0",
+ "inherits": "2",
+ "minimatch": "~0.2.11"
+ }
+ },
+ "graceful-fs": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz",
+ "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
+ "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "2",
+ "sigmund": "~1.0.0"
+ }
+ },
+ "mkdirp": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
+ "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=",
+ "dev": true
+ }
+ }
+ },
+ "moment": {
+ "version": "2.24.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+ "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
+ },
+ "mongodb": {
+ "version": "1.4.40",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-1.4.40.tgz",
+ "integrity": "sha1-z9gLdP3w+gU/LM+19JxHyjKjjvs=",
+ "requires": {
+ "bson": "~0.2",
+ "kerberos": "0.0.11",
+ "readable-stream": "^2.3.5"
+ }
+ },
+ "mongodb-core": {
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz",
+ "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=",
+ "requires": {
+ "bson": "~1.0.4",
+ "require_optional": "~1.0.0"
+ },
+ "dependencies": {
+ "bson": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.5.tgz",
+ "integrity": "sha512-D4SCtud6mlEb48kXdTHU31DRU0bsgOJ+4St1Dcx30uYNnf/aGc+hC9gHB/z0Eth8HYYs/hr0SFdyZViht19SwA=="
+ }
+ }
+ },
+ "mongoose": {
+ "version": "4.13.11",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.13.11.tgz",
+ "integrity": "sha512-OgXmFc3vzXwq4zWp41XfSBDnKZLqnBc4Kh7mwwGjBE5iWH5tfkixaPK0uFtpEuzDzUvAIg33bgniyTsmc00olA==",
+ "requires": {
+ "async": "2.1.4",
+ "bson": "~1.0.4",
+ "hooks-fixed": "2.0.2",
+ "kareem": "1.5.0",
+ "lodash.get": "4.4.2",
+ "mongodb": "2.2.34",
+ "mpath": "0.3.0",
+ "mpromise": "0.5.5",
+ "mquery": "2.3.3",
+ "ms": "2.0.0",
+ "muri": "1.3.0",
+ "regexp-clone": "0.0.1",
+ "sliced": "1.0.1"
+ },
+ "dependencies": {
+ "bson": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.5.tgz",
+ "integrity": "sha512-D4SCtud6mlEb48kXdTHU31DRU0bsgOJ+4St1Dcx30uYNnf/aGc+hC9gHB/z0Eth8HYYs/hr0SFdyZViht19SwA=="
+ },
+ "mongodb": {
+ "version": "2.2.34",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz",
+ "integrity": "sha1-o09Zu+thdUrsQy3nLD/iFSakTBo=",
+ "requires": {
+ "es6-promise": "3.2.1",
+ "mongodb-core": "2.1.18",
+ "readable-stream": "2.2.7"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
+ },
+ "readable-stream": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz",
+ "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=",
+ "requires": {
+ "buffer-shims": "~1.0.0",
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "string_decoder": "~1.0.0",
+ "util-deprecate": "~1.0.1"
+ }
+ }
+ }
+ },
+ "mongoose-lifecycle": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/mongoose-lifecycle/-/mongoose-lifecycle-1.0.0.tgz",
+ "integrity": "sha1-O6w/OSSoRdFHeE/GVY3ukAsBUeI="
+ },
+ "mongoose-unique-validator": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/mongoose-unique-validator/-/mongoose-unique-validator-0.3.0.tgz",
+ "integrity": "sha1-odI705NYM3fTg2u4fQFUpAmUbZk="
+ },
+ "mongoskin": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/mongoskin/-/mongoskin-0.4.4.tgz",
+ "integrity": "sha1-J8cKyG4oF6gidruG7huQkHbxmJU=",
+ "requires": {
+ "mongodb": "< 1.2.0"
+ },
+ "dependencies": {
+ "bson": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-0.1.5.tgz",
+ "integrity": "sha1-in/jHyL5sK6raDE84g4XbATaC3A="
+ },
+ "mongodb": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-1.1.11.tgz",
+ "integrity": "sha1-FFpBscgziL/rG/kDNAuUz5D3ArU=",
+ "requires": {
+ "bson": "0.1.5"
+ }
+ }
+ }
+ },
+ "monk": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/monk/-/monk-0.7.1.tgz",
+ "integrity": "sha1-kOccO7Y89b47DCJJ39PVBWqUnQE=",
+ "requires": {
+ "debug": "*",
+ "mongoskin": "0.4.4"
+ }
+ },
+ "morgan": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz",
+ "integrity": "sha1-X9gYOYxoGcuiinzWZk8pL+HAu/I=",
+ "requires": {
+ "basic-auth": "~1.0.3",
+ "debug": "~2.2.0",
+ "depd": "~1.0.1",
+ "on-finished": "~2.3.0",
+ "on-headers": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ }
+ }
+ },
+ "mpath": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.3.0.tgz",
+ "integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q="
+ },
+ "mpromise": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz",
+ "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY="
+ },
+ "mquery": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.3.tgz",
+ "integrity": "sha512-NC8L14kn+qxJbbJ1gbcEMDxF0sC3sv+1cbRReXXwVvowcwY1y9KoVZFq0ebwARibsadu8lx8nWGvm3V0Pf0ZWQ==",
+ "requires": {
+ "bluebird": "3.5.0",
+ "debug": "2.6.9",
+ "regexp-clone": "0.0.1",
+ "sliced": "0.0.5"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "sliced": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz",
+ "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8="
+ }
+ }
+ },
+ "ms": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+ "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
+ },
+ "multer": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/multer/-/multer-0.1.8.tgz",
+ "integrity": "sha1-VRuKYBUJNwG8rMlkkWsa4GV483s=",
+ "requires": {
+ "busboy": "~0.2.9",
+ "mkdirp": "~0.3.5",
+ "qs": "~1.2.2",
+ "type-is": "~1.5.2"
+ },
+ "dependencies": {
+ "mime-db": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
+ "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc="
+ },
+ "mime-types": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
+ "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=",
+ "requires": {
+ "mime-db": "~1.12.0"
+ }
+ },
+ "mkdirp": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
+ "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc="
+ },
+ "qs": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-1.2.2.tgz",
+ "integrity": "sha1-GbV/8k3CqZzh+L32r82ln472H4g="
+ },
+ "type-is": {
+ "version": "1.5.7",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.5.7.tgz",
+ "integrity": "sha1-uTaKWTzG730GReeLL0xky+zQXpA=",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.0.9"
+ }
+ }
+ }
+ },
+ "multiparty": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-3.3.2.tgz",
+ "integrity": "sha1-Nd5oBNwZZD5SSfPT473GyM4wHT8=",
+ "requires": {
+ "readable-stream": "~1.1.9",
+ "stream-counter": "~0.2.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ }
+ }
+ },
+ "muri": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/muri/-/muri-1.3.0.tgz",
+ "integrity": "sha512-FiaFwKl864onHFFUV/a2szAl7X0fxVlSKNdhTf+BM8i8goEgYut8u5P9MqQqIYwvaMxjzVESsoEm/2kfkFH1rg=="
+ },
+ "nan": {
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz",
+ "integrity": "sha1-PHa1OC6rM+RLdY0oE8qdkuk0LzQ="
+ },
+ "negotiator": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz",
+ "integrity": "sha1-Jp1cR2gQ7JLtvntsLygxY4T5p+g="
+ },
+ "node-restful": {
+ "version": "0.1.19",
+ "resolved": "https://registry.npmjs.org/node-restful/-/node-restful-0.1.19.tgz",
+ "integrity": "sha1-kUPUlWfMrSOzBr5ONQHtZ9lv0w0=",
+ "requires": {
+ "underscore": "1.6.0"
+ }
+ },
+ "noptify": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/noptify/-/noptify-0.0.3.tgz",
+ "integrity": "sha1-WPZUpz2XU98MUdlobckhBKZ/S7s=",
+ "dev": true,
+ "requires": {
+ "nopt": "~2.0.0"
+ },
+ "dependencies": {
+ "nopt": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.0.0.tgz",
+ "integrity": "sha1-ynQW8gpeP5w7hhgPlilfo9C1Lg0=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ }
+ }
+ },
+ "oauth": {
+ "version": "0.9.15",
+ "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
+ "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE="
+ },
+ "object-keys": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.2.0.tgz",
+ "integrity": "sha1-zd7AKZiwkb5CvxA1rjLknxy26mc=",
+ "requires": {
+ "foreach": "~2.0.1",
+ "indexof": "~0.0.1",
+ "is": "~0.2.6"
+ }
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "options": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
+ "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+ },
+ "passport": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/passport/-/passport-0.2.2.tgz",
+ "integrity": "sha1-nDjxe+uSnz2Br3uIOOhDDbhwPys=",
+ "requires": {
+ "passport-strategy": "1.x.x",
+ "pause": "0.0.1"
+ },
+ "dependencies": {
+ "pause": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
+ "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
+ }
+ }
+ },
+ "passport-facebook": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/passport-facebook/-/passport-facebook-1.0.3.tgz",
+ "integrity": "sha1-gqlaqwAXqxkLgVqx5kq3VILqzcc=",
+ "requires": {
+ "passport-oauth2": "1.x.x"
+ }
+ },
+ "passport-local": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
+ "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=",
+ "requires": {
+ "passport-strategy": "1.x.x"
+ }
+ },
+ "passport-oauth1": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.1.0.tgz",
+ "integrity": "sha1-p96YiiEfnPRoc3cTDqdN8ycwyRg=",
+ "requires": {
+ "oauth": "0.9.x",
+ "passport-strategy": "1.x.x",
+ "utils-merge": "1.x.x"
+ }
+ },
+ "passport-oauth2": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.4.0.tgz",
+ "integrity": "sha1-9i+BWDy+EmCb585vFguTlaJ7hq0=",
+ "requires": {
+ "oauth": "0.9.x",
+ "passport-strategy": "1.x.x",
+ "uid2": "0.0.x",
+ "utils-merge": "1.x.x"
+ }
+ },
+ "passport-strategy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
+ "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ="
+ },
+ "passport-twitter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/passport-twitter/-/passport-twitter-1.0.4.tgz",
+ "integrity": "sha1-AaeZ4fdgvy3knyul+6MigvGJMtc=",
+ "requires": {
+ "passport-oauth1": "1.x.x",
+ "xtraverse": "0.1.x"
+ }
+ },
+ "passport.socketio": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/passport.socketio/-/passport.socketio-3.0.1.tgz",
+ "integrity": "sha1-dvk5luyl8naQfORNM/scyM1AWGk=",
+ "requires": {
+ "passport": "~0.2.0",
+ "xtend": "~2.0.3"
+ }
+ },
+ "pause": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/pause/-/pause-0.1.0.tgz",
+ "integrity": "sha1-68ikqGGf8LioGsFRPDQ0/0af23Q="
+ },
+ "policyfile": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz",
+ "integrity": "sha1-1rgurZiueeviKOLa9ZAzEeyYLk0="
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+ },
+ "proxy-addr": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.10.tgz",
+ "integrity": "sha1-DUCoL4Afw1VWfS7LZe/j8HfxIcU=",
+ "requires": {
+ "forwarded": "~0.1.0",
+ "ipaddr.js": "1.0.5"
+ }
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
+ },
+ "random-bytes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
+ "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
+ },
+ "range-parser": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz",
+ "integrity": "sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU="
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz",
+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.0.3",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "redis": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz",
+ "integrity": "sha1-7le3pE0l7BWU5ENl2BZfp9HUgRo=",
+ "optional": true
+ },
+ "regexp-clone": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz",
+ "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk="
+ },
+ "require_optional": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
+ "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
+ "requires": {
+ "resolve-from": "^2.0.0",
+ "semver": "^5.1.0"
+ }
+ },
+ "resolve-from": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
+ "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
+ },
+ "response-time": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/response-time/-/response-time-2.3.2.tgz",
+ "integrity": "sha1-/6cbq5UtYvfB1Jt0NDVfvGjf/Fo=",
+ "requires": {
+ "depd": "~1.1.0",
+ "on-headers": "~1.0.1"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ }
+ }
+ },
+ "rndm": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz",
+ "integrity": "sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w="
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
+ "semver": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
+ },
+ "send": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.13.0.tgz",
+ "integrity": "sha1-UY+SGusFYK7H3KspkLFM9vPM5d4=",
+ "requires": {
+ "debug": "~2.2.0",
+ "depd": "~1.0.1",
+ "destroy": "1.0.3",
+ "escape-html": "1.0.2",
+ "etag": "~1.7.0",
+ "fresh": "0.3.0",
+ "http-errors": "~1.3.1",
+ "mime": "1.3.4",
+ "ms": "0.7.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.0.2",
+ "statuses": "~1.2.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "destroy": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz",
+ "integrity": "sha1-tDO0ck5x/YVR2YhRdIUcX8N34sk="
+ },
+ "mime": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
+ "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
+ },
+ "statuses": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz",
+ "integrity": "sha1-3e1FzBglbVHtQK7BQkidXGECbSg="
+ }
+ }
+ },
+ "sequence": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/sequence/-/sequence-2.1.1.tgz",
+ "integrity": "sha1-889YbCCsBDTitUyHZA4eOatlDQo="
+ },
+ "serve-favicon": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.3.2.tgz",
+ "integrity": "sha1-3UGeJo3gEqtysxnTN/IQUBP5OB8=",
+ "requires": {
+ "etag": "~1.7.0",
+ "fresh": "0.3.0",
+ "ms": "0.7.2",
+ "parseurl": "~1.3.1"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
+ }
+ }
+ },
+ "serve-index": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.7.3.tgz",
+ "integrity": "sha1-egV/xu4o3GP2RWbl+lexEahq7NI=",
+ "requires": {
+ "accepts": "~1.2.13",
+ "batch": "0.5.3",
+ "debug": "~2.2.0",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.3.1",
+ "mime-types": "~2.1.9",
+ "parseurl": "~1.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.10.3.tgz",
+ "integrity": "sha1-zlpuzTEB/tXsCYJ9rCKpwpv7BTU=",
+ "requires": {
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.1",
+ "send": "0.13.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "mime": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
+ "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
+ },
+ "send": {
+ "version": "0.13.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.13.2.tgz",
+ "integrity": "sha1-dl52B8gFVFK7pvCwUllTUJhgNt4=",
+ "requires": {
+ "debug": "~2.2.0",
+ "depd": "~1.1.0",
+ "destroy": "~1.0.4",
+ "escape-html": "~1.0.3",
+ "etag": "~1.7.0",
+ "fresh": "0.3.0",
+ "http-errors": "~1.3.1",
+ "mime": "1.3.4",
+ "ms": "0.7.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.0.3",
+ "statuses": "~1.2.1"
+ }
+ },
+ "statuses": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz",
+ "integrity": "sha1-3e1FzBglbVHtQK7BQkidXGECbSg="
+ }
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
+ "dev": true
+ },
+ "sliced": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
+ "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
+ },
+ "socket.io": {
+ "version": "0.9.19",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-0.9.19.tgz",
+ "integrity": "sha1-SQu1/Q3FTPAC7gTmf638Q7hIo48=",
+ "requires": {
+ "base64id": "0.1.0",
+ "policyfile": "0.0.4",
+ "redis": "0.7.3",
+ "socket.io-client": "0.9.16"
+ }
+ },
+ "socket.io-client": {
+ "version": "0.9.16",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz",
+ "integrity": "sha1-TadRXF53MEHRtCOXBBW8xDDzX8Y=",
+ "requires": {
+ "active-x-obfuscator": "0.0.1",
+ "uglify-js": "1.2.5",
+ "ws": "0.4.x",
+ "xmlhttprequest": "1.4.2"
+ }
+ },
+ "source-map": {
+ "version": "0.1.34",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.34.tgz",
+ "integrity": "sha1-p8/omux7FoLDsZjQrPtH19CQVms=",
+ "dev": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ },
+ "starttls": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/starttls/-/starttls-0.2.1.tgz",
+ "integrity": "sha1-uY0+XneNRvGZyEOmT4ifA0fG0Zo="
+ },
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
+ },
+ "stream-counter": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-0.2.0.tgz",
+ "integrity": "sha1-3tJmVWMZyLDiIoErnPOyb6fZR94=",
+ "requires": {
+ "readable-stream": "~1.1.8"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ }
+ }
+ },
+ "streamsearch": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
+ "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "tiny-lr": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.0.4.tgz",
+ "integrity": "sha1-gGGFR/Y/aX0Fy0DEwsSwg1Ia77Y=",
+ "dev": true,
+ "requires": {
+ "debug": "~0.7.0",
+ "faye-websocket": "~0.4.3",
+ "noptify": "^0.0.3",
+ "qs": "~0.5.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz",
+ "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=",
+ "dev": true
+ },
+ "qs": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-0.5.6.tgz",
+ "integrity": "sha1-MbGtBYVnZRxSaSFQa5qHk5EaA4Q=",
+ "dev": true
+ }
+ }
+ },
+ "tinycolor": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz",
+ "integrity": "sha1-MgtaUtg6u1l42Bo+iH1K77FaYWQ="
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
+ },
+ "tsscmp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz",
+ "integrity": "sha1-fcSjOvcVgatDN9qR2FylQn69mpc="
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "dependencies": {
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ }
+ }
+ },
+ "uglify-js": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.2.5.tgz",
+ "integrity": "sha1-tULCx29477NLIAsgF3Y0Mw/3ArY="
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "dev": true
+ },
+ "uid-safe": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.4.tgz",
+ "integrity": "sha1-Otbzg2jG1MjHXsF2I/t5qh0HHYE=",
+ "requires": {
+ "random-bytes": "~1.0.0"
+ }
+ },
+ "uid2": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
+ "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
+ },
+ "underscore": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+ "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag="
+ },
+ "underscore.string": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz",
+ "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "useful-string": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/useful-string/-/useful-string-0.0.1.tgz",
+ "integrity": "sha1-6FGC0mVnfO8kmdb9omZH/tNBezE="
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "utils-merge": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
+ "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
+ },
+ "vary": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz",
+ "integrity": "sha1-meSYFWaihhGN+yuBc1ffeZM3bRA="
+ },
+ "vhost": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/vhost/-/vhost-3.0.2.tgz",
+ "integrity": "sha1-L7HezUxGaqiLD5NBrzPcGv8keNU="
+ },
+ "which": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz",
+ "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=",
+ "dev": true
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "ws": {
+ "version": "0.4.32",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-0.4.32.tgz",
+ "integrity": "sha1-eHphVEFPPJntg8V3IVOyD+sM7DI=",
+ "requires": {
+ "commander": "~2.1.0",
+ "nan": "~1.0.0",
+ "options": ">=0.0.5",
+ "tinycolor": "0.x"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
+ "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E="
+ },
+ "nan": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-1.0.0.tgz",
+ "integrity": "sha1-riT4hQgY1mL8q1rPfzuVv6oszzg="
+ }
+ }
+ },
+ "xml2js": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+ "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+ "requires": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~9.0.1"
+ }
+ },
+ "xmlbuilder": {
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
+ },
+ "xmldom": {
+ "version": "0.1.27",
+ "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
+ "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk="
+ },
+ "xmlhttprequest": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.4.2.tgz",
+ "integrity": "sha1-AUU6HZvtHo8XL2SVu/TIxCYyFQA="
+ },
+ "xtend": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.0.6.tgz",
+ "integrity": "sha1-XqZXptukRwacLlnFihE4ywxebO4=",
+ "requires": {
+ "is-object": "~0.1.2",
+ "object-keys": "~0.2.0"
+ }
+ },
+ "xtraverse": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/xtraverse/-/xtraverse-0.1.0.tgz",
+ "integrity": "sha1-t0G60BjveNip0ug63gB7P3lZxzI=",
+ "requires": {
+ "xmldom": "0.1.x"
+ }
+ },
+ "yargs": {
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.5.4.tgz",
+ "integrity": "sha1-2K/49mXpTDS9JZvevRv68N3TU2E=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^1.0.2",
+ "decamelize": "^1.0.0",
+ "window-size": "0.1.0",
+ "wordwrap": "0.0.2"
+ }
+ },
+ "zeparser": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/zeparser/-/zeparser-0.0.5.tgz",
+ "integrity": "sha1-A3JlYbwmjy5URPVMZlt/1KjAKeI="
+ },
+ "zlib-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/zlib-browserify/-/zlib-browserify-0.0.1.tgz",
+ "integrity": "sha1-T6akXQDbwV8xikr6HZr8Aljhdsw=",
+ "dev": true
+ }
+ }
+}
diff --git a/package.json b/package.json
index adefb82..378d0bc 100644
--- a/package.json
+++ b/package.json
@@ -6,32 +6,36 @@
"url": "git://github.com/okfocus/vvalls.git"
},
"dependencies": {
- "express": "~3.4.8",
- "monk": "~0.7.1",
- "socket.io": "~0.9.16",
+ "body-parser": "^1.19.0",
"connect-mongo": "~0.4.1",
- "passport": "~0.2.0",
- "passport-local": "~1.0.0",
- "passport-twitter": "~1.0.2",
- "passport-facebook": "~1.0.3",
- "passport.socketio": "~3.0.1",
- "node-restful": "~0.1.14",
+ "dotenv": "^8.2.0",
"ejs": "^0.8.8",
- "useful-string": "0.0.1",
+ "emailjs": "~0.3.6",
+ "express": "^3.4.8",
"express-subdomain-handler": "~0.1.0",
"express-subdomains": "0.0.5",
+ "express-xml-bodyparser": "0.0.6",
+ "html-entities": "~1.0.10",
+ "inspect": "0.0.2",
+ "intro.js": "^0.9.0",
+ "knox": "^0.9.2",
"lodash": "~2.4.1",
- "mongoose": "~3.8.8",
- "mongoose-unique-validator": "~0.3.0",
+ "marked": "^0.7.0",
+ "mime": "^2.4.4",
+ "moment": "^2.24.0",
+ "mongoose": "^4.13.0",
"mongoose-lifecycle": "~1.0.0",
- "knox": "~0.8.10",
- "moment": "~2.6.0",
- "html-entities": "~1.0.10",
+ "mongoose-unique-validator": "~0.3.0",
+ "monk": "~0.7.1",
"multer": "~0.1.0",
- "body-parser": "1.3.0",
- "marked": "~0.3.2",
- "emailjs": "~0.3.6",
- "intro.js": "^0.9.0"
+ "node-restful": "~0.1.14",
+ "passport": "~0.2.0",
+ "passport-facebook": "~1.0.3",
+ "passport-local": "~1.0.0",
+ "passport-twitter": "~1.0.2",
+ "passport.socketio": "~3.0.1",
+ "socket.io": "~0.9.16",
+ "useful-string": "0.0.1"
},
"devDependencies": {
"grunt": "~0.4.1",
diff --git a/public/assets/fonts/ionicons.eot b/public/assets/fonts/ionicons.eot
index 52b1e57..92a3f20 100755
--- a/public/assets/fonts/ionicons.eot
+++ b/public/assets/fonts/ionicons.eot
Binary files differ
diff --git a/public/assets/fonts/ionicons.svg b/public/assets/fonts/ionicons.svg
index 5c8c909..49fc8f3 100755
--- a/public/assets/fonts/ionicons.svg
+++ b/public/assets/fonts/ionicons.svg
@@ -1,11 +1,11 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
-2014-6-16: Created.
+2014-12-4: Created.
-->
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>
-Created by FontForge 20120731 at Mon Jun 16 14:44:31 2014
+Created by FontForge 20120731 at Thu Dec 4 09:51:48 2014
By Adam Bradley
Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net)
</metadata>
@@ -19,189 +19,307 @@ Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net)
panose-1="2 0 6 3 0 0 0 0 0 0"
ascent="448"
descent="-64"
- bbox="-0.5 -64.0026 512.487 448"
+ bbox="-0.54049 -64 512.487 448"
underline-thickness="25.6"
underline-position="-51.2"
- unicode-range="U+F100-F358"
+ unicode-range="U+F100-F4F7"
/>
<missing-glyph />
<glyph glyph-name="ion-alert-circled" unicode="&#xf100;"
d="M445 26c3 -5 5 -13 2 -18s-8 -8 -14 -8h-418c-6 0 -11 3 -14 8s-1 13 2 18l207 349c3 5 8 9 14 9s11 -4 14 -9zM256 48v48h-64v-48h64zM256 128v144h-64v-144h64z" />
<glyph glyph-name="ion-alert" unicode="&#xf101;" horiz-adv-x="128"
d="M128 -32h-128v96h128v-96zM112 128h-96l-16 288h128z" />
- <glyph glyph-name="ion-android-add-contact" unicode="&#xf2c6;" horiz-adv-x="512"
-d="M258 174c59 -18 95 -58 108 -110h-366c13 52 49 92 108 110c22 -13 48 -20 75 -20s53 7 75 20zM183 184c-73 0 -132 59 -132 132s59 132 132 132s132 -59 132 -132s-59 -132 -132 -132zM276 280h-185c14 -37 50 -63 92 -63s79 26 93 63zM512 48v-32h-80v-80h-32v80h-80
-v32h80v80h32v-80h80z" />
- <glyph glyph-name="ion-android-add" unicode="&#xf2c7;" horiz-adv-x="512"
-d="M512 224v-64h-224v-224h-64v224h-224v64h224v224h64v-224h224z" />
- <glyph glyph-name="ion-android-alarm" unicode="&#xf2c8;" horiz-adv-x="512"
-d="M256 400c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM392 40c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56s100 20 136 56zM224 160l16 176h24l8 -160
-l80 -96l-16 -16zM388 432c53 -27 97 -71 124 -124l-28 -15c-12 24 -28 45 -47 64s-40 35 -64 47l15 28v0zM124 432v0l15 -28c-24 -12 -45 -28 -64 -47s-35 -40 -47 -64l-28 15c27 53 71 97 124 124z" />
- <glyph glyph-name="ion-android-archive" unicode="&#xf2c9;" horiz-adv-x="512"
-d="M432 400l80 -64v-352h-512v352l80 64h352zM256 64l112 128h-56v56h-112v-56h-56zM36 336h440l-60 48h-320z" />
- <glyph glyph-name="ion-android-arrow-back" unicode="&#xf2ca;" horiz-adv-x="256"
-d="M256 448l-144 -256l144 -256h-112l-144 256l144 256h112z" />
- <glyph glyph-name="ion-android-arrow-down-left" unicode="&#xf2cb;" horiz-adv-x="480"
-d="M0 256h80v-167l343 343l57 -57l-343 -343h167v-80h-304v304z" />
- <glyph glyph-name="ion-android-arrow-down-right" unicode="&#xf2cc;" horiz-adv-x="480"
-d="M480 256v-304h-304v80h167l-343 343l57 57l343 -343v167h80z" />
- <glyph glyph-name="ion-android-arrow-forward" unicode="&#xf30f;" horiz-adv-x="256"
-d="M0 448h112l144 -256l-144 -256h-112l144 256z" />
- <glyph glyph-name="ion-android-arrow-up-left" unicode="&#xf2cd;" horiz-adv-x="480"
-d="M304 432v-80h-167l343 -343l-57 -57l-343 343v-167h-80v304h304z" />
- <glyph glyph-name="ion-android-arrow-up-right" unicode="&#xf2ce;" horiz-adv-x="480"
-d="M176 432h304v-304h-80v167l-343 -343l-57 57l343 343h-167v80z" />
- <glyph glyph-name="ion-android-battery" unicode="&#xf2cf;" horiz-adv-x="256"
-d="M192 352h64v-32v-352h-256v352v32h64v32v32h128v-32v-32zM224 224v96h-64v64h-64v-64h-64v-96h192z" />
- <glyph glyph-name="ion-android-book" unicode="&#xf2d0;" horiz-adv-x="512"
-d="M0 448l176 -112v-384l-176 144v352zM512 448v-352l-176 -144v384zM208 -64v384h96v-384h-96zM426 442c17 0 38 -2 38 -2l-160 -96h-48h-48l-160 96s21 2 38 2s54 1 106 -26s64 -44 64 -44s12 17 64 44s89 26 106 26z" />
- <glyph glyph-name="ion-android-calendar" unicode="&#xf2d1;" horiz-adv-x="512"
-d="M502 416c6 0 10 -4 10 -10v-460c0 -6 -4 -10 -10 -10h-492c-6 0 -10 4 -10 10v460c0 6 4 10 10 10h102v32h64v-32h160v32h64v-32h102zM480 -32v416h-80v-32h-64v32h-160v-32h-64v32h-80v-416h448z" />
- <glyph glyph-name="ion-android-call" unicode="&#xf2d2;" horiz-adv-x="512"
-d="M451 98c38 -28 56 -46 60 -62c4 -19 -7 -26 -40 -64c-32 -37 -61 -36 -84 -36s-61 12 -121 48c-22 14 -49 33 -74 54c-15 12 -35 30 -52 48c-12 12 -24 25 -32 35c-21 25 -40 52 -54 74c-36 60 -54 105 -54 128s-1 52 36 84c38 33 45 44 64 40c16 -4 34 -23 62 -60
-s46 -64 40 -76c-8 -15 -25 -23 -56 -39c-11 -6 -32 -18 -28 -28c5 -13 28 -55 81 -109l13 -13v0c48 -44 84 -63 96 -68c10 -4 22 17 28 28c16 31 24 48 39 56c12 6 39 -12 76 -40zM417 353c-31 31 -71 49 -113 52v43c112 -7 201 -96 208 -208h-43c-3 42 -21 82 -52 113z
-M304 358c57 -14 103 -61 117 -118h-44c-12 34 -39 61 -73 73v45z" />
- <glyph glyph-name="ion-android-camera" unicode="&#xf2d3;" horiz-adv-x="512"
-d="M96 368l-80 -32v48h80v-16zM336 352h176v-352h-512v304l128 48h48v48h32h96h32v-48zM256 48c71 0 128 57 128 128s-57 128 -128 128s-128 -57 -128 -128s57 -128 128 -128zM156 176c0 67 33 100 100 100s100 -33 100 -100s-33 -100 -100 -100s-100 33 -100 100z" />
- <glyph glyph-name="ion-android-chat" unicode="&#xf2d4;" horiz-adv-x="480"
-d="M224 448c141 0 256 -115 256 -256s-115 -256 -256 -256v64c-124 0 -224 100 -224 224s100 224 224 224v0zM208 246v48c0 6 -4 10 -10 10h-92c-6 0 -10 -4 -10 -10v-108c0 -6 4 -10 10 -10h70v-16c0 -9 -7 -16 -16 -16v-32c26 0 48 22 48 48v26v60zM384 246v48
-c0 6 -4 10 -10 10h-92c-6 0 -10 -4 -10 -10v-108c0 -6 4 -10 10 -10h70v-16c0 -9 -7 -16 -16 -16v-32c26 0 48 22 48 48v26v60z" />
- <glyph glyph-name="ion-android-checkmark" unicode="&#xf2d5;" horiz-adv-x="512"
-d="M176 -16l-176 176l80 83l112 -107l248 248l72 -72z" />
- <glyph glyph-name="ion-android-clock" unicode="&#xf2d6;"
-d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56s100 20 136 56zM192 176l16 176h24l8 -160
-l80 -96l-16 -16z" />
- <glyph glyph-name="ion-android-close" unicode="&#xf2d7;" horiz-adv-x="407"
-d="M407 350l-158 -158l158 -158l-45 -46l-158 159l-159 -159l-45 46l158 158l-158 158l45 46l159 -159l158 159z" />
- <glyph glyph-name="ion-android-contact" unicode="&#xf2d8;" horiz-adv-x="488"
-d="M344 82c78 -24 126 -77 144 -146h-488c18 69 66 122 144 146c30 -17 64 -26 100 -26s70 9 100 26zM244 448c97 0 176 -79 176 -176s-79 -176 -176 -176s-176 79 -176 176s79 176 176 176zM244 140c56 0 104 35 123 84h-246c19 -49 67 -84 123 -84z" />
- <glyph glyph-name="ion-android-contacts" unicode="&#xf2d9;" horiz-adv-x="512"
-d="M237 85c54 -16 87 -53 99 -101h-336c12 47 45 85 99 101c20 -12 44 -19 69 -19s49 7 69 19zM168 336c67 0 121 -54 121 -121s-54 -121 -121 -121s-121 54 -121 121s54 121 121 121zM168 123c38 0 71 26 84 58h-169c13 -32 47 -58 85 -58zM332 48c-15 23 -38 42 -68 54
-c13 11 24 23 32 37c15 -6 31 -9 48 -9c25 0 49 7 69 19c54 -16 87 -53 99 -101h-180zM314 245c-9 42 -36 78 -72 99c22 34 59 56 102 56c67 0 121 -54 121 -121s-54 -121 -121 -121c-13 0 -25 2 -37 6c3 9 6 18 8 28c9 -3 19 -5 29 -5c38 0 71 26 84 58h-114z" />
- <glyph glyph-name="ion-android-data" unicode="&#xf2da;"
-d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM88 56v0v0v0zM240 1c40 3 77 18 108 44l-124 147v144l-16 47c-40 -3 -77 -18 -108 -44l28 -39l-11 -12l-39 28c-26 -31 -42 -68 -45 -108l47 -8v-16l-47 -8
-c3 -40 18 -77 44 -108l39 28l12 -11l-28 -39c31 -26 68 -42 108 -45l8 47h16z" />
- <glyph glyph-name="ion-android-developer" unicode="&#xf2db;" horiz-adv-x="512"
-d="M140 7c10 0 19 -8 20 -18v-1v-1c0 -10 -10 -19 -20 -19v0v0h-8c-46 0 -79 20 -79 77c0 15 1 31 3 46s2 31 2 45s-1 34 -36 34c-12 0 -22 10 -22 22v0v0c0 12 10 22 22 22c35 0 36 20 36 34s-1 30 -3 45s-3 31 -3 46c0 57 34 77 80 77h8v0v0c10 0 20 -9 20 -19v-1v-1
-c-1 -10 -10 -18 -20 -18h-1c-27 -2 -41 -7 -43 -41c-1 -13 0 -26 1 -40c1 -15 3 -29 4 -43c2 -32 -3 -49 -24 -61v0v0c21 -12 26 -29 24 -61c-1 -14 -3 -28 -4 -43c-1 -14 -2 -26 -1 -40c2 -34 16 -39 43 -41h1zM372 7h1c27 2 41 7 43 41c1 14 0 26 -1 40c-1 15 -3 29 -4 43
-c-2 32 3 49 24 61v0v0c-21 12 -26 29 -24 61c1 14 3 28 4 43c1 14 2 27 1 40c-2 34 -16 39 -43 41h-1c-10 0 -19 8 -20 18v1v1c0 10 10 19 20 19v0v0h7c46 0 80 -20 80 -77c0 -15 -1 -31 -3 -46s-2 -31 -2 -45s1 -34 36 -34c12 0 22 -10 22 -22v0v0c0 -12 -10 -22 -22 -22
-c-35 0 -36 -20 -36 -34s1 -30 2 -45c2 -15 3 -31 3 -46c0 -57 -34 -77 -80 -77h-7v0v0c-10 0 -20 9 -20 19v1v1c1 10 10 18 20 18z" />
- <glyph glyph-name="ion-android-display" unicode="&#xf2dc;" horiz-adv-x="501"
-d="M449 192l52 -53l-74 -29l25 -76l-79 6l-10 -78l-69 40l-44 -66l-44 66l-68 -40l-10 78l-79 -6l25 76l-74 29l52 53l-52 53l74 29l-25 76l79 -6l10 78l68 -40l44 66l44 -66l69 40l10 -78l79 6l-25 -76l74 -29zM250 32c88 0 160 72 160 160s-72 160 -160 160v-320z" />
- <glyph glyph-name="ion-android-download" unicode="&#xf2dd;"
-d="M264 256h88l-128 -128l-128 128h88v175v1h80v-1v-175zM296 404c88 -30 152 -114 152 -212c0 -124 -100 -224 -224 -224s-224 100 -224 224c0 98 64 182 152 212v-34c-24 -10 -46 -24 -64 -42c-36 -36 -56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56s100 20 136 56
-s56 85 56 136s-20 100 -56 136c-19 18 -40 32 -64 42v34zM96 80v16h256v-16h-256z" />
- <glyph glyph-name="ion-android-drawer" unicode="&#xf310;" horiz-adv-x="256"
-d="M0 320v64h256v-64h-256zM0 0v64h256v-64h-256zM0 160v64h256v-64h-256z" />
- <glyph glyph-name="ion-android-dropdown" unicode="&#xf2de;" horiz-adv-x="288"
-d="M0 32l288 288v-288h-288z" />
- <glyph glyph-name="ion-android-earth" unicode="&#xf2df;"
-d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM32 192c0 -51 20 -100 56 -136c31 -31 71 -49 113 -54c6 16 22 31 8 42c-9 7 -17 14 -25 22c-3 3 -11 21 -9 24c6 9 7 16 9 27c3 13 -4 17 -15 24c-16 10 -31 24 -47 36
-c-8 6 -18 10 -21 20s-4 22 -10 30c-15 22 -13 38 -11 64c0 7 -1 17 -2 26c-30 -35 -46 -79 -46 -125zM360 56c36 36 56 85 56 136s-20 100 -56 136c-30 30 -67 48 -108 54v-9l4 -10l-15 -14l-9 3l-11 11l-11 13l-15 6c-17 -3 -33 -8 -49 -15c0 -2 1 -4 1 -7c8 3 16 5 24 8
-c3 1 14 -7 17 -9c-4 -5 -22 -17 -23 -23c0 -2 7 -7 7 -11v-18c4 3 21 22 23 22c14 4 37 -19 39 -27s-23 -26 -35 -37c-9 -9 -26 -13 -21 -26c2 -4 11 -22 6 -26c-6 -5 -16 10 -19 13c-9 11 -28 7 -41 7c0 -19 -1 -33 16 -46c16 -12 32 -27 51 -35c14 -6 38 8 50 -1
-c17 -12 32 -24 51 -32c8 -4 36 -21 28 -33c-5 -8 -11 -16 -15 -25s-13 -20 -21 -26c-9 -7 -19 -19 -24 -32c38 7 72 25 100 53zM391 262c7 -10 4 -38 4 -50c0 -22 2 -44 -5 -65c-12 9 -23 26 -25 48c-2 23 1 41 -3 61c-3 17 -21 34 -29 50c-7 15 -15 30 -22 45
-c2 -1 6 -2 8 -3c14 -13 27 -26 41 -39c12 -12 21 -33 31 -47z" />
- <glyph glyph-name="ion-android-folder" unicode="&#xf2e0;" horiz-adv-x="512"
-d="M432 16h-432v352h144l48 -64h240v-32h-368l-40 -128l16 -16l40 128h432z" />
- <glyph glyph-name="ion-android-forums" unicode="&#xf2e1;" horiz-adv-x="512"
-d="M422 432c6 0 10 -4 10 -10v-268c0 -6 -4 -10 -10 -10h-230l-112 -112v112h-70c-6 0 -10 4 -10 10v268c0 6 4 10 10 10h412zM502 352c6 0 10 -4 10 -10v-268c0 -6 -4 -10 -10 -10h-70v-112l-112 112h-160l48 48h223c22 0 33 13 33 33v207h38z" />
- <glyph glyph-name="ion-android-friends" unicode="&#xf2e2;" horiz-adv-x="512"
-d="M325 117c54 -16 87 -53 99 -101h-336c12 48 45 85 99 101c20 -12 44 -19 69 -19s49 7 69 19zM256 368c67 0 121 -54 121 -121s-54 -121 -121 -121s-121 54 -121 121s54 121 121 121zM256 155c38 0 71 26 84 58h-169c13 -32 47 -58 85 -58zM412 86c-18 20 -42 36 -72 46
-c8 6 18 11 30 15c12 -7 26 -11 41 -11s29 4 41 11c32 -10 53 -32 60 -61h-100zM411 298c40 0 73 -33 73 -73s-33 -73 -73 -73c-18 0 -34 7 -47 18c3 5 6 10 9 16c10 -9 23 -16 38 -16c23 0 43 15 51 35h-81c4 12 6 25 6 38c0 16 -3 33 -9 47c10 5 21 8 33 8zM172 132
-c-30 -10 -54 -26 -72 -46h-100c7 29 27 51 59 61c12 -7 27 -11 42 -11s29 4 41 11c12 -4 22 -9 30 -15zM101 170c15 0 28 7 38 16c3 -6 5 -11 9 -16c-13 -11 -29 -18 -47 -18c-40 0 -73 33 -73 73s33 73 73 73c12 0 23 -3 33 -8c-6 -14 -9 -31 -9 -47c0 -13 2 -26 6 -38h-81
-c8 -20 28 -35 51 -35z" />
- <glyph glyph-name="ion-android-hand" unicode="&#xf2e3;" horiz-adv-x="473"
-d="M459 172c17 -17 19 -42 2 -59c0 0 -110 -118 -144 -139v0c-32 -24 -73 -38 -113 -38c-63 0 -117 41 -135 97v1v0c0 1 -1 3 -1 4l-66 216c-6 17 2 36 19 42s35 -3 41 -20l38 -102c2 -4 3 -1 3 2l-26 184c-3 17 9 35 26 38s34 -10 37 -27l29 -157c0 -3 2 -2 2 0l1 202
-c0 18 14 32 32 32s32 -14 32 -32l9 -200c0 -5 3 -5 4 -1l27 154c2 18 18 31 36 29s29 -19 27 -37l-24 -196c-2 -13 -4 -34 2 -41c9 -10 24 -10 36 2l48 48c17 17 41 15 58 -2z" />
- <glyph glyph-name="ion-android-image" unicode="&#xf2e4;" horiz-adv-x="512"
-d="M0 448h512v-512h-512v512zM480 -32v448h-448v-448h448zM448 88v-88h-384v136l96 64l112 -96l80 40z" />
- <glyph glyph-name="ion-android-inbox" unicode="&#xf2e5;" horiz-adv-x="512"
-d="M416 416l96 -256v-192h-512v192l96 256h320zM336 160h112l-64 216h-256l-64 -216h112c0 -44 36 -80 80 -80s80 36 80 80z" />
- <glyph glyph-name="ion-android-information" unicode="&#xf2e6;"
-d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM256 67v157h-64v-157h64zM224 272c22 0 40 18 40 40s-18 40 -40 40s-40 -18 -40 -40s18 -40 40 -40z" />
- <glyph glyph-name="ion-android-keypad" unicode="&#xf2e7;" horiz-adv-x="384"
-d="M96 362c0 -6 -4 -10 -10 -10h-76c-6 0 -10 4 -10 10v76c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76zM243 362c0 -6 -4 -10 -10 -10h-76c-6 0 -10 4 -10 10v76c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76zM384 362c0 -6 -4 -10 -10 -10h-76c-6 0 -10 4 -10 10v76
-c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76zM96 234c0 -6 -4 -10 -10 -10h-76c-6 0 -10 4 -10 10v76c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76zM243 234c0 -6 -4 -10 -10 -10h-76c-6 0 -10 4 -10 10v76c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76zM384 234c0 -6 -4 -10 -10 -10
-h-76c-6 0 -10 4 -10 10v76c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76zM96 106c0 -6 -4 -10 -10 -10h-76c-6 0 -10 4 -10 10v76c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76zM243 106c0 -6 -4 -10 -10 -10h-76c-6 0 -10 4 -10 10v76c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76z
-M243 -22c0 -6 -4 -10 -10 -10h-76c-6 0 -10 4 -10 10v76c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76zM384 106c0 -6 -4 -10 -10 -10h-76c-6 0 -10 4 -10 10v76c0 6 4 10 10 10h76c6 0 10 -4 10 -10v-76z" />
- <glyph glyph-name="ion-android-lightbulb" unicode="&#xf2e8;" horiz-adv-x="352"
-d="M176 448c97 0 176 -79 176 -176c0 -62 -24 -117 -72 -148v-156h-32v-32h-144v32h-32v156c-48 31 -72 86 -72 148c0 97 79 176 176 176zM248 0v16h-144v-16h144zM248 48v16h-144v-16h144zM262 151c37 24 58 67 58 121c0 38 -15 75 -42 102s-64 42 -102 42
-s-75 -15 -102 -42s-42 -64 -42 -102c0 -54 21 -97 58 -121l14 -9v-18v-28h144v28v18z" />
- <glyph glyph-name="ion-android-locate" unicode="&#xf2e9;" horiz-adv-x="512"
-d="M160 192c0 64 32 96 96 96s96 -32 96 -96s-32 -96 -96 -96s-96 32 -96 96zM512 208v-32h-65c-4 -47 -22 -87 -55 -120s-73 -51 -120 -55v-65h-32v65c-47 4 -87 22 -120 55s-51 73 -55 120h-65v32h65c1 13 3 26 7 39s9 24 15 35s13 22 21 32s16 18 26 26s21 15 32 21
-s22 11 35 15s26 6 39 7v65h32v-65c47 -4 87 -22 120 -55s51 -73 55 -120h65zM256 49c39 0 73 14 101 42s42 62 42 101s-14 73 -42 101s-62 42 -101 42s-73 -14 -101 -42s-42 -62 -42 -101s14 -73 42 -101s62 -42 101 -42z" />
- <glyph glyph-name="ion-android-location" unicode="&#xf2ea;" horiz-adv-x="320"
-d="M320 288c0 -20 -3 -39 -10 -57v0l-1 -1v-1c-67 -171 -149 -293 -149 -293v0s-82 121 -149 292v2l-1 1v0c-7 18 -10 37 -10 57c0 88 72 160 160 160s160 -72 160 -160zM160 256c26 0 48 22 48 48s-22 48 -48 48s-48 -22 -48 -48s22 -48 48 -48z" />
- <glyph glyph-name="ion-android-mail" unicode="&#xf2eb;" horiz-adv-x="512"
-d="M256 142l256 124v-266h-512v266zM512 310l-256 -123l-256 123v74h512v-74z" />
+ <glyph glyph-name="ion-android-add-circle" unicode="&#xf359;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM315 171v42h-86v86h-42v-86h-86v-42h86v-86h42v86h86z" />
+ <glyph glyph-name="ion-android-add" unicode="&#xf2c7;" horiz-adv-x="320"
+d="M320 171h-139v-139h-42v139h-139v42h139v139h42v-139h139v-42z" />
+ <glyph glyph-name="ion-android-alarm-clock" unicode="&#xf35a;" horiz-adv-x="428"
+d="M428 323l-28 -33l-98 82l28 33zM125 373l-97 -83l-28 33l97 83zM225 275v0v-111l85 -50l-16 -27l-101 61v127h32zM214 360c106 0 193 -86 193 -191s-87 -191 -193 -191c-107 0 -193 86 -193 191s86 191 193 191zM214 20c82 0 150 66 150 149c0 82 -68 149 -150 149
+s-150 -67 -150 -149s68 -149 150 -149z" />
+ <glyph glyph-name="ion-android-alert" unicode="&#xf35b;" horiz-adv-x="416"
+d="M208 400c114 0 208 -94 208 -208s-94 -208 -208 -208s-208 94 -208 208s94 208 208 208zM232 88v40h-48v-40h48zM232 176v128h-48v-128h48z" />
+ <glyph glyph-name="ion-android-apps" unicode="&#xf35c;" horiz-adv-x="320"
+d="M0 272v80h80v-80h-80zM120 32v80h80v-80h-80zM0 32v80h80v-80h-80zM0 152v80h80v-80h-80zM120 152v80h80v-80h-80zM240 352h80v-80h-80v80zM120 272v80h80v-80h-80zM240 152v80h80v-80h-80zM240 32v80h80v-80h-80z" />
+ <glyph glyph-name="ion-android-archive" unicode="&#xf2c9;" horiz-adv-x="416"
+d="M406 348c7 -7 10 -17 10 -29v-289c0 -25 -21 -46 -46 -46h-324c-25 0 -46 21 -46 46v289c0 12 3 22 10 29l33 39c6 8 16 13 26 13h278c10 0 20 -5 26 -13zM208 65l127 127h-81v46h-92v-46h-81zM49 354h317l-22 23h-277z" />
+ <glyph glyph-name="ion-android-arrow-back" unicode="&#xf2ca;" horiz-adv-x="342"
+d="M342 213v-42h-260l119 -120l-30 -30l-171 171l171 171l31 -30l-120 -120h260z" />
+ <glyph glyph-name="ion-android-arrow-down" unicode="&#xf35d;" horiz-adv-x="342"
+d="M192 363v-260l120 120l30 -31l-171 -171l-171 171l30 30l120 -119v260h42z" />
+ <glyph glyph-name="ion-android-arrow-dropdown-circle" unicode="&#xf35e;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 128l96 96h-192z" />
+ <glyph glyph-name="ion-android-arrow-dropdown" unicode="&#xf35f;" horiz-adv-x="256"
+d="M0 256h256l-128 -128z" />
+ <glyph glyph-name="ion-android-arrow-dropleft-circle" unicode="&#xf360;" horiz-adv-x="416"
+d="M416 192c0 -115 -93 -208 -208 -208s-208 93 -208 208s93 208 208 208s208 -93 208 -208zM144 192l96 -96v192z" />
+ <glyph glyph-name="ion-android-arrow-dropleft" unicode="&#xf361;" horiz-adv-x="128"
+d="M128 320v-256l-128 128z" />
+ <glyph glyph-name="ion-android-arrow-dropright-circle" unicode="&#xf362;" horiz-adv-x="416"
+d="M208 -16c-115 0 -208 93 -208 208s93 208 208 208s208 -93 208 -208s-93 -208 -208 -208zM176 96l96 96l-96 96v-192z" />
+ <glyph glyph-name="ion-android-arrow-dropright" unicode="&#xf363;" horiz-adv-x="128"
+d="M0 320l128 -128l-128 -128v256z" />
+ <glyph glyph-name="ion-android-arrow-dropup-circle" unicode="&#xf364;" horiz-adv-x="416"
+d="M416 192c0 -115 -93 -208 -208 -208s-208 93 -208 208s93 208 208 208s208 -93 208 -208zM304 160l-96 96l-96 -96h192z" />
+ <glyph glyph-name="ion-android-arrow-dropup" unicode="&#xf365;" horiz-adv-x="256"
+d="M0 128l128 128l128 -128h-256z" />
+ <glyph glyph-name="ion-android-arrow-forward" unicode="&#xf30f;" horiz-adv-x="342"
+d="M0 171v42h260l-119 120l30 30l171 -171l-171 -171l-31 30l120 120h-260z" />
+ <glyph glyph-name="ion-android-arrow-up" unicode="&#xf366;" horiz-adv-x="342"
+d="M192 21h-42v260l-120 -119l-30 30l171 171l171 -171l-30 -31l-120 120v-260z" />
+ <glyph glyph-name="ion-android-attach" unicode="&#xf367;" horiz-adv-x="235"
+d="M203 320h32v-235c0 -65 -53 -117 -118 -117s-117 52 -117 117v246c0 47 38 85 85 85s86 -38 86 -85v-246c0 -30 -24 -53 -54 -53s-53 23 -53 53v203h32v-203c0 -12 9 -21 21 -21s22 9 22 21v246c0 30 -24 53 -54 53s-53 -23 -53 -53v-246c0 -47 38 -85 85 -85
+s86 38 86 85v235z" />
+ <glyph glyph-name="ion-android-bar" unicode="&#xf368;" horiz-adv-x="384"
+d="M171 171l-171 170v43h384v-43l-171 -170v-131h107v-40h-256v40h107v131zM96 299h192l43 42h-278z" />
+ <glyph glyph-name="ion-android-bicycle" unicode="&#xf369;"
+d="M299 317c-19 0 -34 14 -34 33s15 34 34 34s33 -15 33 -34s-14 -33 -33 -33zM355 187c51 0 93 -43 93 -94s-42 -93 -93 -93s-94 42 -94 93s43 94 94 94zM355 28c36 0 65 29 65 65s-29 66 -65 66s-66 -30 -66 -66s30 -65 66 -65zM274 224l-30 45l-43 -45l39 -32v-112h-32
+v86l-61 38c-9 6 -19 15 -19 27c0 8 3 17 9 23l72 69c6 6 14 9 22 9c11 0 22 -7 28 -16l34 -60h59v-32h-78zM93 187c51 0 94 -43 94 -94s-43 -93 -94 -93s-93 42 -93 93s42 94 93 94zM93 28c36 0 66 29 66 65s-30 66 -66 66s-65 -30 -65 -66s29 -65 65 -65z" />
+ <glyph glyph-name="ion-android-boat" unicode="&#xf36a;"
+d="M52 35l-51 139c-2 6 -1 12 1 17s8 8 13 10l38 13v98c0 23 20 43 43 43h64l16 53h96l16 -53h64c23 0 43 -20 43 -43v-98l38 -13c5 -2 11 -5 13 -10s3 -12 1 -17l-51 -139h-1c-34 0 -65 20 -86 43c-21 -23 -51 -43 -85 -43s-64 19 -85 42c-21 -23 -52 -42 -86 -42h-1z
+M96 312v-84l128 41l128 -41v84h-256zM309 40c0 0 59 -64 107 -64h-21c-30 0 -59 12 -86 26c-53 -28 -117 -28 -170 0c-27 -14 -56 -26 -86 -26h-21c49 0 107 64 107 64c52 -36 118 -36 170 0z" />
+ <glyph glyph-name="ion-android-bookmark" unicode="&#xf36b;" horiz-adv-x="288"
+d="M248 384c22 0 40 -18 40 -40v-344l-144 64l-144 -64v344c0 22 18 40 40 40h208z" />
+ <glyph glyph-name="ion-android-bulb" unicode="&#xf36c;"
+d="M224 278c-25 0 -50 -10 -68 -28s-28 -43 -28 -68c0 -34 18 -66 48 -83l16 -10v-18v-71h64v71v18l16 10c15 8 27 20 35 34c9 15 13 31 13 49c0 25 -10 50 -28 68s-43 28 -68 28zM245 416v0v-64h-42v64h42zM374 362v0l30 -30l-38 -38l-30 30zM74 362v0l38 -38l-30 -30
+l-38 38zM224 310v0c70 0 128 -58 128 -128c0 -48 -26 -89 -64 -111v-103h-128v103c-38 22 -64 64 -64 111c0 70 58 128 128 128zM448 203v0v-42h-64v42h64zM64 203v0v-42h-64v42h64z" />
+ <glyph glyph-name="ion-android-bus" unicode="&#xf36d;" horiz-adv-x="352"
+d="M0 96v204c0 75 82 84 176 84s176 -9 176 -84v-204c0 -18 -14 -24 -27 -36v-39c0 -12 -9 -21 -21 -21h-21c-12 0 -22 9 -22 21v22h-170v-22c0 -12 -10 -21 -22 -21h-21c-12 0 -21 9 -21 21v39c-13 12 -27 17 -27 36zM80 80c18 0 32 14 32 32s-14 32 -32 32
+s-32 -14 -32 -32s14 -32 32 -32zM272 80c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM304 203v106h-256v-106h256z" />
+ <glyph glyph-name="ion-android-calendar" unicode="&#xf2d1;" horiz-adv-x="384"
+d="M304 176v-96h-96v96h96zM272 384h48v-32h24c22 0 40 -18 40 -40v-272c0 -22 -18 -40 -40 -40h-304c-22 0 -40 18 -40 40v272c0 22 18 40 40 40h24v32h48v-32h160v32zM344 40v212h-304v-212h304z" />
+ <glyph glyph-name="ion-android-call" unicode="&#xf2d2;" horiz-adv-x="384"
+d="M363 117c12 0 21 -9 21 -21v-75c0 -12 -9 -21 -21 -21c-201 0 -363 162 -363 363c0 12 9 21 21 21h75c12 0 21 -9 21 -21c0 -27 4 -52 13 -77c2 -7 0 -16 -5 -21l-47 -47c31 -61 80 -110 141 -141l47 47c5 6 14 7 21 5c23 -7 49 -12 76 -12z" />
+ <glyph glyph-name="ion-android-camera" unicode="&#xf2d3;"
+d="M161 168c0 42 21 63 63 63s63 -21 63 -63s-21 -63 -63 -63s-63 21 -63 63zM408 352c11 0 20 -4 28 -12s12 -17 12 -28v-272c0 -11 -4 -20 -12 -28s-17 -12 -28 -12h-368c-11 0 -20 4 -28 12s-12 17 -12 28v272c0 11 4 20 12 28s17 12 28 12h88l32 32h128l32 -32h88z
+M224 56c31 0 57 11 79 33s33 48 33 79s-11 57 -33 79s-48 33 -79 33s-57 -11 -79 -33s-33 -48 -33 -79s11 -57 33 -79s48 -33 79 -33z" />
+ <glyph glyph-name="ion-android-cancel" unicode="&#xf36e;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM312 117l-75 75l75 75l-29 29l-75 -75l-75 75l-29 -29l75 -75l-75 -75l29 -29l75 75l75 -75z" />
+ <glyph glyph-name="ion-android-car" unicode="&#xf36f;" horiz-adv-x="384"
+d="M339 331l45 -118v-160c0 -12 -9 -21 -21 -21h-22c-12 0 -21 9 -21 21v11h-256v-11c0 -12 -9 -21 -21 -21h-22c-12 0 -21 9 -21 21v160l45 118c4 13 16 21 30 21h234c14 0 26 -8 30 -21zM75 128c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM309 128
+c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM43 235h298l-32 85h-234z" />
+ <glyph glyph-name="ion-android-cart" unicode="&#xf370;" horiz-adv-x="416"
+d="M122 70c23 0 41 -18 41 -41s-18 -42 -41 -42s-42 19 -42 42s19 41 42 41zM0 397h68l19 -42h308c11 0 21 -9 21 -20c0 -4 -1 -8 -2 -10l-75 -129c-7 -14 -20 -22 -36 -22h-155l-21 -32s-2 -5 -2 -6c0 -3 2 -5 5 -5h238v-40h-243c-26 0 -45 14 -45 42c0 7 2 15 5 20l31 51
+l-74 151h-42v42zM326 70c23 0 42 -18 42 -41s-19 -42 -42 -42s-41 19 -41 42s18 41 41 41z" />
+ <glyph glyph-name="ion-android-chat" unicode="&#xf2d4;" horiz-adv-x="416"
+d="M344 384c4 0 7 -4 7 -8v-214c0 -4 -3 -9 -7 -9h-187l-90 -89v89h-57c-4 0 -10 5 -10 9v214c0 4 6 8 10 8h334zM408 321c4 0 8 -5 8 -9v-214c0 -4 -4 -9 -8 -9h-57v-89l-90 89h-130l39 39h181c18 0 25 10 25 26v167h32z" />
+ <glyph glyph-name="ion-android-checkbox-blank" unicode="&#xf371;" horiz-adv-x="384"
+d="M341 384c23 0 43 -20 43 -43v-298c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h298z" />
+ <glyph glyph-name="ion-android-checkbox-outline-blank" unicode="&#xf372;" horiz-adv-x="384"
+d="M341 341h-298v-298h298v298zM341 384v0c23 0 43 -20 43 -43v-298c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h298z" />
+ <glyph glyph-name="ion-android-checkbox-outline" unicode="&#xf373;" horiz-adv-x="384"
+d="M105 233l66 -66l183 183l30 -30l-213 -213l-96 96zM341 43v170h43v-170c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h213v-43h-213v-298h298z" />
+ <glyph glyph-name="ion-android-checkbox" unicode="&#xf374;" horiz-adv-x="384"
+d="M341 384c23 0 43 -20 43 -43v-298c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h298zM149 85l192 192l-30 30l-162 -162l-76 77l-30 -30z" />
+ <glyph glyph-name="ion-android-checkmark-circle" unicode="&#xf375;" horiz-adv-x="416"
+d="M123 232l64 -64l179 178l29 -29l-208 -208l-93 93zM374 192h42c0 -114 -94 -208 -208 -208s-208 94 -208 208s94 208 208 208c28 0 54 -6 78 -16l-32 -32c-15 4 -30 6 -46 6c-92 0 -166 -74 -166 -166s74 -166 166 -166s166 74 166 166z" />
+ <glyph glyph-name="ion-android-clipboard" unicode="&#xf376;" horiz-adv-x="384"
+d="M341 368c23 0 43 -20 43 -43v-314c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v314c0 23 20 43 43 43h87c7 28 32 48 62 48s55 -20 62 -48h87zM192 368c-12 0 -21 -9 -21 -21s9 -22 21 -22s21 10 21 22s-9 21 -21 21zM344 8v320h-40v-72h-224v72h-40v-320h304z" />
+ <glyph glyph-name="ion-android-close" unicode="&#xf2d7;" horiz-adv-x="298"
+d="M298 311l-119 -119l119 -119l-30 -30l-119 119l-119 -119l-30 30l119 119l-119 119l30 30l119 -119l119 119z" />
+ <glyph glyph-name="ion-android-cloud-circle" unicode="&#xf377;" horiz-adv-x="416"
+d="M208 400c114 0 208 -94 208 -208s-94 -208 -208 -208s-208 94 -208 208s94 208 208 208zM302 109c29 0 52 23 52 52s-23 52 -52 52h-11c0 46 -37 83 -83 83c-38 0 -71 -26 -80 -62h-3c-34 0 -63 -29 -63 -63s29 -62 63 -62h177z" />
+ <glyph glyph-name="ion-android-cloud-done" unicode="&#xf378;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121zM197 85l141 141l-30 30l-111 -111l-44 45l-30 -30z" />
+ <glyph glyph-name="ion-android-cloud-outline" unicode="&#xf379;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121zM380 72c33 0 60 27 60 60s-27 60 -60 60h-30v10c0 61 -49 110 -110 110c-51 0 -93 -34 -106 -80h-14
+c-44 0 -80 -36 -80 -80s36 -80 80 -80h260z" />
+ <glyph glyph-name="ion-android-cloud" unicode="&#xf37a;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121z" />
+ <glyph glyph-name="ion-android-color-palette" unicode="&#xf37b;" horiz-adv-x="384"
+d="M192 384c106 0 192 -77 192 -171c0 -59 -48 -106 -107 -106h-38c-18 0 -32 -14 -32 -32c0 -9 3 -17 8 -22s9 -12 9 -21c0 -18 -14 -32 -32 -32c-106 0 -192 86 -192 192s86 192 192 192zM75 192c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM139 277
+c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM245 277c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM309 192c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
+ <glyph glyph-name="ion-android-compass" unicode="&#xf37c;"
+d="M224 217c13 0 25 -12 25 -25s-12 -25 -25 -25s-25 12 -25 25s12 25 25 25zM224 416c123 0 224 -101 224 -224s-101 -224 -224 -224s-224 101 -224 224s101 224 224 224zM273 143l85 183l-183 -85l-85 -183z" />
+ <glyph glyph-name="ion-android-contact" unicode="&#xf2d8;" horiz-adv-x="384"
+d="M267 110c59 -18 104 -58 117 -110h-384c13 52 58 92 117 110c22 -13 48 -20 75 -20s53 7 75 20zM192 384c73 0 132 -59 132 -132s-59 -132 -132 -132s-132 59 -132 132s59 132 132 132zM192 153c42 0 78 26 92 63h-184c14 -37 50 -63 92 -63z" />
+ <glyph glyph-name="ion-android-contacts" unicode="&#xf2d9;"
+d="M207 104c47 -14 76 -62 87 -104h-294c11 42 40 90 87 104c18 -10 38 -16 60 -16s42 6 60 16zM147 328c58 0 106 -48 106 -106s-48 -106 -106 -106s-106 48 -106 106s48 106 106 106zM147 141c34 0 62 23 74 51h-148c12 -28 40 -51 74 -51zM291 64c-13 20 -34 43 -60 53
+c11 9 21 23 28 35c13 -5 27 -8 42 -8c22 0 42 6 60 16c47 -14 76 -54 87 -96h-157zM275 248c-8 37 -31 69 -63 87c19 29 52 49 89 49c58 0 106 -48 106 -106s-48 -106 -106 -106c-11 0 -22 2 -32 5c3 8 6 16 7 25c8 -3 16 -4 25 -4c34 0 62 22 74 50h-100z" />
+ <glyph glyph-name="ion-android-contract" unicode="&#xf37d;" horiz-adv-x="384"
+d="M0 77v51h128v-128h-51v77h-77zM77 307v77h51v-128h-128v51h77zM256 0v128h128v-51h-77v-77h-51zM307 307h77v-51h-128v128h51v-77z" />
+ <glyph glyph-name="ion-android-create" unicode="&#xf37e;" horiz-adv-x="384"
+d="M0 80l236 236l80 -80l-236 -236h-80v80zM378 298l-40 -40l-80 80l40 40c9 9 20 9 29 0l51 -51c9 -9 9 -20 0 -29z" />
+ <glyph glyph-name="ion-android-delete" unicode="&#xf37f;" horiz-adv-x="320"
+d="M32 43v245h256v-245c0 -23 -20 -43 -43 -43h-170c-23 0 -43 20 -43 43zM320 352v-32h-320v32h80l27 32h106l27 -32h80z" />
+ <glyph glyph-name="ion-android-desktop" unicode="&#xf380;"
+d="M405 416c23 0 43 -20 43 -43v-282c0 -23 -20 -43 -43 -43h-138l42 -48v-32h-170v32l42 48h-138c-23 0 -43 20 -43 43v282c0 23 20 43 43 43h362zM405 128v245h-362v-245h362z" />
+ <glyph glyph-name="ion-android-document" unicode="&#xf381;" horiz-adv-x="320"
+d="M192 400l128 -128v-248c0 -22 -18 -40 -40 -40h-240c-22 0 -40 18 -40 40v336c0 22 18 40 40 40h152zM176 256h112l-112 112v-112z" />
+ <glyph glyph-name="ion-android-done-all" unicode="&#xf382;" horiz-adv-x="512"
+d="M388 308l-140 -139l-31 31l140 139zM481 339l31 -31l-264 -263l-122 123l30 31l92 -91zM0 168l32 31l122 -123l-31 -31z" />
+ <glyph glyph-name="ion-android-done" unicode="&#xf383;" horiz-adv-x="384"
+d="M122 108l230 230l32 -31l-262 -261l-122 122l32 31z" />
+ <glyph glyph-name="ion-android-download" unicode="&#xf2dd;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121zM208 180h-68l100 -100l100 100h-68v76h-64v-76z" />
+ <glyph glyph-name="ion-android-drafts" unicode="&#xf384;"
+d="M448 246v-203c0 -23 -20 -43 -43 -43h-362c-23 0 -43 20 -43 43v203c0 15 8 30 20 37l204 101l204 -101c13 -7 20 -22 20 -37zM224 144l171 112l-171 85l-171 -85z" />
+ <glyph glyph-name="ion-android-exit" unicode="&#xf385;" horiz-adv-x="384"
+d="M151 115l55 56h-206v42h207l-56 56l30 30l107 -107l-107 -107zM341 384c23 0 43 -20 43 -43v-298c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v85h43v-85h298v298h-298v-85h-43v85c0 23 20 43 43 43h298z" />
+ <glyph glyph-name="ion-android-expand" unicode="&#xf386;" horiz-adv-x="384"
+d="M333 51v77h51v-128h-128v51h77zM333 333h-77v51h128v-128h-51v77zM51 333v-77h-51v128h128v-51h-77zM51 51h77v-51h-128v128h51v-77z" />
+ <glyph glyph-name="ion-android-favorite-outline" unicode="&#xf387;" horiz-adv-x="416"
+d="M302 384c64 0 114 -50 114 -115c0 -80 -71 -144 -178 -242l-30 -27l-30 27c-107 98 -178 162 -178 242c0 65 50 115 114 115c36 0 71 -17 94 -44c23 27 58 44 94 44zM221 55c50 46 94 86 123 122c28 35 40 63 40 92c0 23 -9 44 -24 59s-35 24 -58 24
+c-26 0 -53 -13 -70 -33l-24 -29l-24 29c-17 20 -44 33 -70 33c-23 0 -43 -9 -58 -24s-24 -36 -24 -59c0 -29 12 -57 40 -92c29 -36 73 -76 123 -122l4 -4l9 -8l9 8z" />
+ <glyph glyph-name="ion-android-favorite" unicode="&#xf388;" horiz-adv-x="416"
+d="M208 0l-30 27c-107 98 -178 162 -178 242c0 65 50 115 114 115c36 0 71 -17 94 -44c23 27 58 44 94 44c64 0 114 -50 114 -115c0 -80 -71 -144 -178 -242z" />
+ <glyph glyph-name="ion-android-film" unicode="&#xf389;" horiz-adv-x="320"
+d="M280 384h40v-384h-40v43h-40v-43h-160v43h-40v-43h-40v384h40v-43h40v43h160v-43h40v43zM80 85v43h-40v-43h40zM80 171v42h-40v-42h40zM80 256v43h-40v-43h40zM280 85v43h-40v-43h40zM280 171v42h-40v-42h40zM280 256v43h-40v-43h40z" />
+ <glyph glyph-name="ion-android-folder-open" unicode="&#xf38a;"
+d="M405 304c23 0 43 -20 43 -43v-186c0 -23 -20 -43 -43 -43h-362c-23 0 -43 20 -43 43v234c0 23 20 43 43 43h138l43 -48h181zM416 75v186c0 6 -5 11 -11 11h-373v-197c0 -6 5 -11 11 -11h362c6 0 11 5 11 11z" />
+ <glyph glyph-name="ion-android-folder" unicode="&#xf2e0;"
+d="M181 352l43 -48h181c23 0 43 -20 43 -43v-186c0 -23 -20 -43 -43 -43h-362c-23 0 -43 20 -43 43v234c0 23 20 43 43 43h138z" />
+ <glyph glyph-name="ion-android-funnel" unicode="&#xf38b;"
+d="M176 48v48h96v-48h-96zM0 336h448v-48h-448v48zM80 167v50h288v-50h-288z" />
+ <glyph glyph-name="ion-android-globe" unicode="&#xf38c;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM186 15c6 15 21 29 8 39c-8 7 -16 14 -23 21c-2 2 -11 20 -9 23c5 9 6 14 8 24c3 12 -3 16 -13 22c-15 10 -29 23 -43 34c-7 5 -17 10 -20 19s-5 20 -10 28c-14 20 -12 34 -10 58
+c0 7 -1 16 -2 25c-28 -32 -42 -73 -42 -116c0 -48 18 -92 52 -126c29 -29 65 -46 104 -51zM334 66c23 23 39 51 47 82c-8 -1 -19 2 -19 2s-21 24 -23 45c-2 22 0 39 -3 57c-3 16 -20 31 -27 46c-7 14 -13 28 -20 42c2 -1 5 -2 7 -3c5 1 10 2 14 2c-23 16 -49 25 -76 29v-8
+l4 -9l-14 -13l-9 3l-10 10l-10 12l-14 5c-16 -2 -31 -7 -45 -13v-7c7 3 16 5 23 8c3 1 13 -7 16 -9c-4 -5 -21 -15 -22 -21c0 -2 7 -6 7 -10c0 -6 -1 -11 -1 -17c3 3 20 21 22 21c13 3 35 -19 37 -26s-22 -24 -33 -34c-8 -8 -25 -12 -20 -24c2 -4 10 -20 5 -24
+c-6 -5 -14 9 -17 12c-8 10 -26 7 -38 7c0 -17 -1 -31 15 -43c15 -11 30 -25 47 -33c13 -6 36 7 47 -1c16 -11 29 -21 47 -29c8 -3 33 -20 26 -31c-5 -8 -10 -15 -14 -23s-13 -20 -20 -25c-8 -6 -16 -17 -21 -29c35 7 66 23 92 49z" />
+ <glyph glyph-name="ion-android-hand" unicode="&#xf2e3;" horiz-adv-x="414"
+d="M401 174c15 -15 18 -36 3 -51c0 0 -96 -103 -126 -121v0c-28 -21 -65 -34 -100 -34c-55 0 -101 36 -117 85v0v1c0 1 -1 2 -1 3l-58 189c-5 15 2 32 17 37s30 -3 35 -18l34 -88c1 -4 2 -2 2 1l-22 161c-3 15 7 30 22 33s30 -8 33 -23l25 -138c0 -2 2 -2 2 0v177
+c0 15 13 28 28 28s28 -13 28 -28l8 -175c0 -5 3 -4 4 -1l23 135c2 15 16 27 31 25s27 -17 25 -32l-21 -172c-1 -12 -3 -30 2 -36c8 -9 20 -9 31 2l42 42c15 15 35 13 50 -2z" />
+ <glyph glyph-name="ion-android-hangout" unicode="&#xf38d;" horiz-adv-x="352"
+d="M176 400c97 0 176 -77 176 -172c0 -91 -76 -196 -176 -244v71c-97 0 -176 78 -176 173s79 172 176 172zM166 217v61h-62v-61h31l-21 -40h31zM248 217v61h-62v-61h31l-20 -40h31z" />
+ <glyph glyph-name="ion-android-happy" unicode="&#xf38e;" horiz-adv-x="416"
+d="M208 400c114 0 208 -94 208 -208s-93 -208 -208 -208s-208 94 -208 208s93 208 208 208zM208 26c92 0 166 74 166 166s-74 166 -166 166s-166 -74 -166 -166s74 -166 166 -166zM281 213c-18 0 -31 13 -31 31s13 31 31 31s31 -13 31 -31s-13 -31 -31 -31zM135 213
+c-18 0 -31 13 -31 31s13 31 31 31s31 -13 31 -31s-13 -31 -31 -31zM208 78c-49 0 -89 29 -106 72h212c-17 -43 -57 -72 -106 -72z" />
+ <glyph glyph-name="ion-android-home" unicode="&#xf38f;" horiz-adv-x="416"
+d="M160 0h-98v192h-62l208 192l208 -192h-62v-192h-98v128h-96v-128z" />
+ <glyph glyph-name="ion-android-image" unicode="&#xf2e4;" horiz-adv-x="384"
+d="M384 43c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h298c23 0 43 -20 43 -43v-298zM117 160l-74 -96h298l-96 128l-74 -96z" />
+ <glyph glyph-name="ion-android-laptop" unicode="&#xf390;" horiz-adv-x="512"
+d="M437 32h75c0 -23 -64 -32 -96 -32h-320c-32 0 -96 9 -96 32h75c-23 0 -43 20 -43 43v266c0 23 20 43 43 43h362c23 0 43 -20 43 -43v-266c0 -23 -20 -43 -43 -43zM75 341v-272h362v272h-362zM256 13c12 0 21 10 21 22s-9 21 -21 21s-21 -9 -21 -21s9 -22 21 -22z" />
+ <glyph glyph-name="ion-android-list" unicode="&#xf391;" horiz-adv-x="384"
+d="M344 384c22 0 40 -18 40 -40v-304c0 -22 -18 -40 -40 -40h-304c-22 0 -40 18 -40 40v304c0 22 18 40 40 40h304zM240 80v48h-160v-48h160zM304 168v48h-224v-48h224zM304 256v48h-224v-48h224z" />
+ <glyph glyph-name="ion-android-locate" unicode="&#xf2e9;"
+d="M224 272c44 0 80 -36 80 -80s-36 -80 -80 -80s-80 36 -80 80s36 80 80 80zM415 213h33v-42h-33c-10 -89 -81 -160 -170 -170v-33h-42v33c-89 10 -160 81 -170 170h-33v42h33c10 89 81 160 170 170v33h42v-33c89 -10 160 -81 170 -170zM224 43c82 0 149 67 149 149
+s-67 149 -149 149s-149 -67 -149 -149s67 -149 149 -149z" />
+ <glyph glyph-name="ion-android-lock" unicode="&#xf392;" horiz-adv-x="320"
+d="M280 262c22 0 40 -18 40 -40v-200c0 -22 -18 -40 -40 -40h-240c-22 0 -40 18 -40 40v200c0 22 18 40 40 40h20v40c0 55 45 100 100 100s100 -45 100 -100v-40h20zM160 80c22 0 40 18 40 40s-18 40 -40 40s-40 -18 -40 -40s18 -40 40 -40zM222 262v40c0 34 -28 62 -62 62
+s-62 -28 -62 -62v-40h124z" />
+ <glyph glyph-name="ion-android-mail" unicode="&#xf2eb;"
+d="M405 368c23 0 43 -20 43 -43v-266c0 -23 -20 -43 -43 -43h-362c-23 0 -43 20 -43 43v266c0 23 20 43 43 43h362zM400 277v43l-176 -117l-176 117v-43l176 -117z" />
+ <glyph glyph-name="ion-android-map" unicode="&#xf393;" horiz-adv-x="384"
+d="M373 384c6 0 11 -5 11 -11v-322c0 -5 -3 -9 -7 -10l-121 -41l-128 45s-105 -41 -108 -42s-7 -3 -9 -3c-6 0 -11 5 -11 11v322c0 5 3 9 7 10l121 41l128 -45s103 40 108 42s7 3 9 3zM256 43v254l-128 44v-254z" />
+ <glyph glyph-name="ion-android-menu" unicode="&#xf394;" horiz-adv-x="384"
+d="M0 64v43h384v-43h-384zM0 171v42h384v-42h-384zM0 320h384v-43h-384v43z" />
+ <glyph glyph-name="ion-android-microphone-off" unicode="&#xf395;" horiz-adv-x="408"
+d="M316 93l58 -58l-58 58l58 -58l34 -33l-24 -24l-95 95c-19 -11 -40 -20 -62 -23v-82h-46v82c-75 10 -137 76 -137 153h39c0 -68 58 -117 121 -117c20 0 40 5 57 14l-32 33c-8 -3 -16 -5 -25 -5c-38 0 -69 31 -69 69v29l-135 134l24 24l111 -110v0l140 -140l5 -5l9 -9z
+M273 197c0 -4 0 -8 -1 -12l-137 137v25c0 38 31 69 69 69s69 -31 69 -69v-150zM365 203c0 -31 -10 -60 -27 -84l-27 28c9 17 15 36 15 56h39zM408 2v0l-34 33z" />
<glyph glyph-name="ion-android-microphone" unicode="&#xf2ec;" horiz-adv-x="320"
-d="M225 192c0 -35 -29 -64 -64 -64v0c-35 0 -64 29 -64 64v160c0 35 29 64 64 64v0c35 0 64 -29 64 -64v-160zM272 208h48v-8c0 -80 -59 -147 -135 -159v-73h-48v73c-78 11 -137 78 -137 159v8h48v-8c0 -30 12 -59 33 -80s49 -32 79 -32s58 11 79 32s33 50 33 80v8z" />
- <glyph glyph-name="ion-android-mixer" unicode="&#xf2ed;" horiz-adv-x="512"
-d="M0 335v32h304v-32h-304zM432 335v32h80v-32h-80zM0 176v32h80v-32h-80zM208 176v32h304v-32h-304zM0 14v32h304v-32h-304zM432 14v32h80v-32h-80zM192 136c0 -22 -22 -40 -48 -40v0c-26 0 -48 18 -48 40v112c0 22 22 40 48 40v0c26 0 48 -18 48 -40v-112zM416 296
-c0 -22 -22 -40 -48 -40v0c-26 0 -48 18 -48 40v112c0 22 22 40 48 40v0c26 0 48 -18 48 -40v-112zM416 -24c0 -22 -22 -40 -48 -40v0c-26 0 -48 18 -48 40v112c0 22 22 40 48 40v0c26 0 48 -18 48 -40v-112z" />
- <glyph glyph-name="ion-android-more" unicode="&#xf2ee;" horiz-adv-x="128"
-d="M0 128v128h128v-128h-128zM0 320v128h128v-128h-128zM0 -64v128h128v-128h-128z" />
- <glyph glyph-name="ion-android-note" unicode="&#xf2ef;" horiz-adv-x="464"
-d="M0 448h464v-512h-464v512zM40 384v-64h256v64h-256zM424 32v48h-384v-48h384zM424 128v48h-384v-48h384zM424 224v48h-384v-48h384z" />
- <glyph glyph-name="ion-android-playstore" unicode="&#xf2f0;" horiz-adv-x="512"
-d="M512 320c-23 -265 -16 -384 -16 -384h-480s7 116 -16 384h128c0 71 57 128 128 128s128 -57 128 -128h128zM256 416c-53 0 -96 -43 -96 -96h192c0 53 -43 96 -96 96zM192 16l176 104l-176 104v-208z" />
- <glyph glyph-name="ion-android-printer" unicode="&#xf2f1;" horiz-adv-x="512"
-d="M96 320v96h320v-96h-320zM512 229v0v-165h-96v-96h-320v96h-96v165v0c0 33 27 59 60 59h392c33 0 60 -26 60 -59zM352 32v128h-192v-128h192zM416 200c13 0 24 11 24 24s-11 24 -24 24s-24 -11 -24 -24s11 -24 24 -24z" />
- <glyph glyph-name="ion-android-promotion" unicode="&#xf2f2;" horiz-adv-x="384"
-d="M384 256l-192 -192l-192 192v192h192v0zM96 304c26 0 48 22 48 48s-22 48 -48 48s-48 -22 -48 -48s22 -48 48 -48zM384 192v-64l-192 -192l-192 192v64l192 -192z" />
- <glyph glyph-name="ion-android-reminder" unicode="&#xf2f3;" horiz-adv-x="416"
-d="M0 48l64 160v96c0 80 64 144 144 144v0c80 0 144 -64 144 -144v-96l64 -160zM208 -64c-54 0 -100 33 -119 80h238c-19 -47 -65 -80 -119 -80z" />
- <glyph glyph-name="ion-android-remove" unicode="&#xf2f4;" horiz-adv-x="512"
-d="M0 160v64h512v-64h-512z" />
- <glyph glyph-name="ion-android-search" unicode="&#xf2f5;" horiz-adv-x="512"
-d="M510 6c6 -6 -3 -27 -22 -46s-40 -28 -46 -22l-113 113c-4 4 -1 15 8 28l-40 40c-31 -24 -70 -39 -113 -39c-102 0 -184 82 -184 184s82 184 184 184s184 -82 184 -184c0 -43 -15 -82 -39 -113l40 -40c13 9 24 12 28 8zM184 120c38 0 75 15 102 42s42 64 42 102
-s-15 75 -42 102s-64 42 -102 42s-75 -15 -102 -42s-42 -64 -42 -102s15 -75 42 -102s64 -42 102 -42z" />
- <glyph glyph-name="ion-android-send" unicode="&#xf2f6;" horiz-adv-x="512"
-d="M0 448l512 -256l-512 -256l43 235l426 21l-426 21z" />
- <glyph glyph-name="ion-android-settings" unicode="&#xf2f7;" horiz-adv-x="491"
-d="M438 192c0 -14 -2 -28 -5 -42l58 -44l-48 -84l-67 29c-21 -19 -45 -33 -73 -42l-9 -73h-96l-9 73c-28 9 -52 23 -73 42l-68 -29l-48 84l58 44c-3 14 -4 28 -4 42s1 28 4 42l-58 44l48 84l68 -29c21 19 45 33 73 42l9 73h96l9 -73c28 -9 52 -23 73 -42l67 29l48 -84
-l-58 -44c3 -14 5 -28 5 -42zM246 128c35 0 64 29 64 64s-29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64z" />
- <glyph glyph-name="ion-android-share" unicode="&#xf2f8;" horiz-adv-x="480"
-d="M400 96c44 0 80 -36 80 -80s-36 -80 -80 -80s-80 36 -80 80c0 5 0 10 1 14l-186 104c-14 -13 -34 -22 -55 -22c-44 0 -80 36 -80 80s36 80 80 80c21 0 41 -9 55 -22l186 104c-1 5 -1 9 -1 14c0 44 36 80 80 80s80 -36 80 -80s-36 -80 -80 -80c-22 0 -42 9 -56 23
-l-186 -102c1 -5 2 -11 2 -17s-1 -12 -2 -17l185 -102c14 14 35 23 57 23z" />
- <glyph glyph-name="ion-android-social-user" unicode="&#xf2f9;" horiz-adv-x="512"
-d="M142 334c0 76 38 114 114 114s114 -38 114 -114s-38 -114 -114 -114s-114 38 -114 114zM502 50c7 -7 10 -14 10 -22v-92h-512v92c0 8 3 15 10 22c61 61 143 91 246 91s185 -30 246 -91z" />
- <glyph glyph-name="ion-android-social" unicode="&#xf2fa;" horiz-adv-x="512"
-d="M256 280c0 53 27 80 80 80s80 -27 80 -80s-27 -80 -80 -80s-80 27 -80 80zM73 213c0 41 20 61 61 61s61 -20 61 -61s-20 -61 -61 -61s-61 20 -61 61zM136 112c7 0 15 -1 24 -2v0v0c-21 -17 -31 -30 -32 -38v-72h-128v50c0 2 1 5 2 7s1 3 3 5c33 33 76 50 131 50zM505 80
-c5 -5 7 -10 7 -15v-65h-352v65c0 5 2 10 7 15c42 43 98 64 169 64s127 -21 169 -64z" />
- <glyph glyph-name="ion-android-sort" unicode="&#xf2fb;" horiz-adv-x="512"
-d="M0 288v64h512v-64h-512zM0 160v64h352v-64h-352zM0 32v64h192v-64h-192z" />
- <glyph glyph-name="ion-android-stair-drawer" unicode="&#xf311;" horiz-adv-x="512"
-d="M0 0v96h256v-96h-256zM128 144v96h256v-96h-256zM256 288v96h256v-96h-256z" />
- <glyph glyph-name="ion-android-star" unicode="&#xf2fc;" horiz-adv-x="512"
-d="M512 246l-136 -121l40 -178l-160 85l-160 -85l40 178l-136 121l182 17l74 174l74 -174z" />
- <glyph glyph-name="ion-android-stopwatch" unicode="&#xf2fd;"
-d="M240 383c116 -8 208 -105 208 -223c0 -124 -100 -224 -224 -224s-224 100 -224 224c0 118 92 215 208 223v17h-32v48h96v-48h-32v-17zM360 24c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56
-s100 20 136 56zM337 273c3 -3 3 -8 0 -11l-74 -74c6 -8 9 -18 9 -28c0 -26 -22 -48 -48 -48s-48 22 -48 48s22 48 48 48c10 0 20 -3 28 -9l74 74c3 3 8 3 11 0zM224 128c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
- <glyph glyph-name="ion-android-storage" unicode="&#xf2fe;"
-d="M0 256h448v-128h-448v128zM128 160v32h-96v-32h96zM0 416h448v-128h-448v128zM128 320v32h-96v-32h96zM0 96h448v-128h-448v128zM128 0v32h-96v-32h96z" />
- <glyph glyph-name="ion-android-system-back" unicode="&#xf2ff;" horiz-adv-x="512"
-d="M416 256c53 0 96 -43 96 -96s-43 -96 -96 -96h-192v32h192c35 0 64 29 64 64s-29 64 -64 64v0h-361l67 -80h-42l-80 96l80 96h42l-67 -80h361z" />
- <glyph glyph-name="ion-android-system-home" unicode="&#xf300;" horiz-adv-x="512"
-d="M256 303l-224 -84v-123h448v123zM256 338v0l256 -96v-178h-512v178z" />
- <glyph glyph-name="ion-android-system-windows" unicode="&#xf301;" horiz-adv-x="512"
-d="M0 256h416v-192h-416v192zM384 96v128h-352v-128h352zM128 320h384v-192h-32v160h-352v32z" />
- <glyph glyph-name="ion-android-timer" unicode="&#xf302;" horiz-adv-x="320"
-d="M210 202c87 -46 110 -206 110 -234h-320c0 27 23 188 110 234c-87 41 -110 187 -110 214h320c0 -26 -23 -172 -110 -214zM61 304c12 -25 25 -44 41 -58c17 -15 36 -22 58 -22s41 7 58 22c16 14 29 34 41 59c12 26 19 52 23 69c1 3 2 10 2 10h-248c4 -21 12 -52 25 -80z
-M284 0c-4 25 -12 58 -26 91c-12 29 -25 51 -41 67c-17 17 -36 25 -57 25s-39 -8 -56 -25c-16 -16 -30 -38 -42 -67c-14 -33 -22 -66 -26 -91h248z" />
- <glyph glyph-name="ion-android-trash" unicode="&#xf303;" horiz-adv-x="352"
-d="M16 249c39 -10 68 -21 160 -21s121 12 160 21c-2 -54 -10 -224 -11 -266c-1 -25 -66 -46 -147 -46s-145 21 -146 46c-2 34 -13 212 -16 266zM256 374c81 -10 96 -10 96 -53s-68 -59 -176 -59s-176 16 -176 58s17 44 96 54v66c0 6 5 8 11 8h140c6 0 9 -2 9 -8v-66z
-M128 416v-39c15 1 31 1 48 1s34 0 48 -1v39h-96z" />
- <glyph glyph-name="ion-android-user-menu" unicode="&#xf312;"
-d="M144 232c-28 0 -52 17 -62 42h124c-10 -25 -34 -42 -62 -42zM0 416h288v-288h-21c-9 35 -32 62 -72 74c-15 -8 -33 -13 -51 -13s-36 5 -51 13c-40 -12 -63 -39 -72 -74h-21v288zM144 209c49 0 89 40 89 89s-40 89 -89 89s-89 -40 -89 -89s40 -89 89 -89zM320 288v128h128
-v-128h-128zM320 128v128h128v-128h-128zM320 -32v128h128v-128h-128zM160 -32v128h128v-128h-128zM0 -32v128h128v-128h-128z" />
- <glyph glyph-name="ion-android-volume" unicode="&#xf304;" horiz-adv-x="512"
-d="M234 448c54 0 70 -115 70 -256s-16 -256 -70 -256c-42 0 -74 64 -138 160h-64c-18 0 -32 43 -32 96s14 96 32 96h64c64 96 96 160 138 160zM240 -14c24 0 34 82 34 206s-10 206 -34 206c-18 0 -24 -78 -27 -144c28 -7 43 -32 43 -62s-15 -55 -43 -62
-c3 -66 9 -144 27 -144zM466 370c30 -52 46 -113 46 -178s-17 -126 -47 -178l-23 24c4 8 8 16 12 25c17 41 26 84 26 129s-9 88 -26 129c-4 9 -8 17 -12 25zM411 295c23 -28 37 -64 37 -103s-14 -75 -37 -103l-22 23c18 23 27 51 27 80c0 30 -9 57 -27 80zM375 229
-c6 -11 9 -24 9 -37s-3 -27 -9 -38l-30 12c4 8 7 17 7 26s-3 18 -7 26z" />
- <glyph glyph-name="ion-android-wifi" unicode="&#xf305;" horiz-adv-x="512"
-d="M333 181c20 -8 38 -20 54 -34l-54 -61c-21 16 -48 26 -77 26s-56 -10 -77 -26l-54 61c16 14 34 26 54 34c24 10 50 16 77 16s53 -6 77 -16zM256 96c24 0 47 -8 66 -22l-66 -74l-66 74c19 14 42 22 66 22zM372 269c29 -12 56 -28 80 -49l-55 -61c-38 34 -87 54 -141 54
-s-103 -21 -141 -54l-55 61c24 21 51 37 80 49c37 16 76 24 116 24s79 -8 116 -24zM256 384c98 0 188 -36 256 -96l-50 -56c-55 48 -127 77 -206 77s-151 -29 -206 -77l-50 56c68 60 158 96 256 96z" />
+d="M160 128c-38 0 -69 31 -69 69v150c0 38 31 69 69 69s69 -31 69 -69v-150c0 -38 -31 -69 -69 -69zM281 203h39c0 -78 -62 -142 -137 -153v-82h-46v82c-75 10 -137 75 -137 153h39c0 -69 58 -116 121 -116s121 47 121 116z" />
+ <glyph glyph-name="ion-android-more-horizontal" unicode="&#xf396;" horiz-adv-x="320"
+d="M40 232c22 0 40 -18 40 -40s-18 -40 -40 -40s-40 18 -40 40s18 40 40 40zM280 232c22 0 40 -18 40 -40s-18 -40 -40 -40s-40 18 -40 40s18 40 40 40zM160 232c22 0 40 -18 40 -40s-18 -40 -40 -40s-40 18 -40 40s18 40 40 40z" />
+ <glyph glyph-name="ion-android-more-vertical" unicode="&#xf397;" horiz-adv-x="80"
+d="M80 312c0 -22 -18 -40 -40 -40s-40 18 -40 40s18 40 40 40s40 -18 40 -40zM80 72c0 -22 -18 -40 -40 -40s-40 18 -40 40s18 40 40 40s40 -18 40 -40zM80 192c0 -22 -18 -40 -40 -40s-40 18 -40 40s18 40 40 40s40 -18 40 -40z" />
+ <glyph glyph-name="ion-android-navigate" unicode="&#xf398;" horiz-adv-x="320"
+d="M160 384l160 -369l-15 -15l-145 64l-145 -64l-15 15z" />
+ <glyph glyph-name="ion-android-notifications-none" unicode="&#xf399;" horiz-adv-x="352"
+d="M177 328h-2c-6 0 -24 -5 -24 -5c-46 -10 -78 -53 -78 -100v-114v-13l-9 -10l-8 -8h240l-8 8l-9 10v13v114c0 47 -32 90 -78 100c0 0 -17 5 -24 5zM176 400v0c18 0 31 -13 31 -31v-15c59 -14 104 -68 104 -131v-114l41 -42v-21h-352v21l41 42v114c0 63 45 117 104 131v15
+c0 18 13 31 31 31zM217 26v0c0 -23 -18 -42 -41 -42s-41 19 -41 42h82z" />
+ <glyph glyph-name="ion-android-notifications-off" unicode="&#xf39a;" horiz-adv-x="364"
+d="M182 -16c-23 0 -41 19 -41 42h82c0 -23 -18 -42 -41 -42zM57 341l295 -295v0l12 -12l-24 -24l-36 36h-298v21l41 41v115c0 23 6 44 16 63l-63 64l24 24l33 -33v0zM317 223v-94l-208 207c13 8 27 15 42 18v15c0 18 13 31 31 31s31 -13 31 -31v-15c59 -14 104 -67 104 -131
+z" />
+ <glyph glyph-name="ion-android-notifications" unicode="&#xf39b;" horiz-adv-x="352"
+d="M176 -16c-23 0 -41 19 -41 42h82c0 -23 -18 -42 -41 -42zM311 109l41 -42v-21h-352v21l41 42v114c0 63 45 117 104 131v15c0 18 13 31 31 31s31 -13 31 -31v-15c59 -14 104 -68 104 -131v-114z" />
+ <glyph glyph-name="ion-android-open" unicode="&#xf39c;" horiz-adv-x="384"
+d="M341 43v133h43v-133c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h133v-43h-133v-298h298zM224 384h160v-160h-43v87l-215 -215l-30 30l215 215h-87v43z" />
+ <glyph glyph-name="ion-android-options" unicode="&#xf39d;"
+d="M0 32v32h272v-32h-272zM368 32v32h80v-32h-80zM352 0c0 -18 -14 -32 -32 -32v0c-18 0 -32 14 -32 32v96c0 18 14 32 32 32v0c18 0 32 -14 32 -32v-96zM0 176v32h80v-32h-80zM176 176v32h272v-32h-272zM160 144c0 -18 -14 -32 -32 -32v0c-18 0 -32 14 -32 32v96
+c0 18 14 32 32 32v0c18 0 32 -14 32 -32v-96zM0 320v32h272v-32h-272zM368 320v32h80v-32h-80zM352 288c0 -18 -14 -32 -32 -32v0c-18 0 -32 14 -32 32v96c0 18 14 32 32 32v0c18 0 32 -14 32 -32v-96z" />
+ <glyph glyph-name="ion-android-people" unicode="&#xf39e;"
+d="M305 216c-34 0 -61 27 -61 60s27 60 61 60s62 -27 62 -60s-28 -60 -62 -60zM143 216c-34 0 -62 27 -62 60s28 60 62 60s61 -27 61 -60s-27 -60 -61 -60zM143 172c48 0 145 -23 145 -70v-54h-288v54c0 47 95 70 143 70zM305 161c48 0 143 -12 143 -59v-54h-128v54
+c0 30 -9 41 -32 58c7 1 11 1 17 1z" />
+ <glyph glyph-name="ion-android-person-add" unicode="&#xf39f;" horiz-adv-x="480"
+d="M288 192c-53 0 -96 43 -96 96s43 96 96 96s96 -43 96 -96s-43 -96 -96 -96zM288 144c64 0 192 -32 192 -96v-48h-384v48c0 64 128 96 192 96zM96 224h64v-32h-64v-64h-32v64h-64v32h64v64h32v-64z" />
+ <glyph glyph-name="ion-android-person" unicode="&#xf3a0;" horiz-adv-x="384"
+d="M192 192c-53 0 -96 43 -96 96s43 96 96 96s96 -43 96 -96s-43 -96 -96 -96zM192 144c64 0 192 -32 192 -96v-48h-384v48c0 64 128 96 192 96z" />
+ <glyph glyph-name="ion-android-phone-landscape" unicode="&#xf3a1;"
+d="M448 89c0 -23 -19 -41 -41 -41h-366c-22 0 -41 18 -41 41v206c0 23 19 41 41 41h366c22 0 41 -18 41 -41v-206zM80 84h288v216h-288v-216z" />
+ <glyph glyph-name="ion-android-phone-portrait" unicode="&#xf3a2;" horiz-adv-x="288"
+d="M247 416c23 0 41 -19 41 -41v-366c0 -22 -18 -41 -41 -41h-206c-23 0 -41 19 -41 41v366c0 22 18 41 41 41h206zM252 48v288h-216v-288h216z" />
+ <glyph glyph-name="ion-android-pin" unicode="&#xf3a3;" horiz-adv-x="320"
+d="M160 416c88 0 160 -71 160 -157c0 -118 -160 -291 -160 -291s-160 173 -160 291c0 86 72 157 160 157zM160 203c32 0 57 25 57 56s-25 56 -57 56s-57 -25 -57 -56s25 -56 57 -56z" />
+ <glyph glyph-name="ion-android-plane" unicode="&#xf3a4;" horiz-adv-x="384"
+d="M384 112l-160 48v-114l48 -31v-31l-80 16l-80 -16v31l48 31v114l-160 -48v40l160 104v113c0 18 15 31 32 31s32 -13 32 -31v-113l160 -104v-40z" />
+ <glyph glyph-name="ion-android-playstore" unicode="&#xf2f0;" horiz-adv-x="416"
+d="M416 296c-19 -214 -13 -312 -13 -312h-390s6 96 -13 312h104c0 57 47 104 104 104s104 -47 104 -104h104zM208 374c-43 0 -78 -35 -78 -78h156c0 43 -35 78 -78 78zM156 50l143 85l-143 84v-169z" />
+ <glyph glyph-name="ion-android-print" unicode="&#xf3a5;" horiz-adv-x="416"
+d="M352 288c35 0 64 -29 64 -64v-139h-80v-85h-256v85h-80v139c0 35 29 64 64 64h288zM304 32v128h-192v-128h192zM336 384v0v-80h-256v80h256z" />
+ <glyph glyph-name="ion-android-radio-button-off" unicode="&#xf3a6;" horiz-adv-x="416"
+d="M208 400c114 0 208 -94 208 -208s-94 -208 -208 -208s-208 94 -208 208s94 208 208 208zM208 26c92 0 166 74 166 166s-74 166 -166 166s-166 -74 -166 -166s74 -166 166 -166z" />
+ <glyph glyph-name="ion-android-radio-button-on" unicode="&#xf3a7;" horiz-adv-x="416"
+d="M208 296c57 0 104 -47 104 -104s-47 -104 -104 -104s-104 47 -104 104s47 104 104 104zM208 400c114 0 208 -94 208 -208s-94 -208 -208 -208s-208 94 -208 208s94 208 208 208zM208 26c92 0 166 74 166 166s-74 166 -166 166s-166 -74 -166 -166s74 -166 166 -166z" />
+ <glyph glyph-name="ion-android-refresh" unicode="&#xf3a8;" horiz-adv-x="352"
+d="M176 60c56 0 104 34 123 84h46c-21 -74 -88 -128 -169 -128c-98 0 -176 79 -176 176s79 176 176 176c48 0 92 -20 124 -52l52 52v-154h-154l70 70c-23 24 -56 40 -92 40c-73 0 -132 -59 -132 -132s59 -132 132 -132z" />
+ <glyph glyph-name="ion-android-remove-circle" unicode="&#xf3a9;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM315 171v42h-214v-42h214z" />
+ <glyph glyph-name="ion-android-remove" unicode="&#xf2f4;" horiz-adv-x="320"
+d="M0 171v42h320v-42h-320z" />
+ <glyph glyph-name="ion-android-restaurant" unicode="&#xf3aa;" horiz-adv-x="415"
+d="M116 168l-91 89c-34 33 -34 86 0 119l153 -148zM264 206l-33 -31l150 -145l-30 -30l-150 146l-150 -146l-30 30s163 159 211 207c-15 32 -4 77 31 111c41 40 101 49 132 17c33 -31 24 -89 -17 -129c-34 -34 -80 -45 -114 -30z" />
+ <glyph glyph-name="ion-android-sad" unicode="&#xf3ab;" horiz-adv-x="416"
+d="M208 160c45 0 83 -26 102 -64h-204c19 38 57 64 102 64zM208 400c114 0 208 -94 208 -208s-93 -208 -208 -208s-208 94 -208 208s93 208 208 208zM208 26c92 0 166 74 166 166s-74 166 -166 166s-166 -74 -166 -166s74 -166 166 -166zM281 213c-18 0 -31 13 -31 31
+s13 31 31 31s31 -13 31 -31s-13 -31 -31 -31zM135 213c-18 0 -31 13 -31 31s13 31 31 31s31 -13 31 -31s-13 -31 -31 -31z" />
+ <glyph glyph-name="ion-android-search" unicode="&#xf2f5;" horiz-adv-x="384"
+d="M274 143l110 -110l-33 -33l-109 110v17l-7 6c-25 -21 -58 -34 -93 -34c-79 0 -142 63 -142 142s63 143 141 143c79 0 142 -64 142 -143c0 -36 -13 -68 -34 -93l7 -5h18zM142 143c55 0 99 43 99 98s-44 99 -99 99s-98 -44 -98 -99s43 -98 98 -98z" />
+ <glyph glyph-name="ion-android-send" unicode="&#xf2f6;" horiz-adv-x="416"
+d="M0 0v149l298 43l-298 43v149l416 -192z" />
+ <glyph glyph-name="ion-android-settings" unicode="&#xf2f7;" horiz-adv-x="416"
+d="M366 171l47 -34c3 -3 4 -10 2 -14l-43 -71c-2 -4 -7 -7 -12 -5l-54 21c-12 -8 -23 -16 -36 -21l-8 -55c-1 -4 -6 -8 -11 -8h-85c-5 0 -10 3 -11 8l-8 55c-13 5 -25 13 -36 21l-54 -21c-4 -2 -10 1 -12 5l-43 71c-3 5 -2 11 2 14l45 34c0 7 -1 14 -1 21s1 14 1 21l-46 34
+c-3 3 -4 10 -2 14l43 71c2 4 7 7 12 5l54 -21c12 8 23 16 36 21l8 55c1 4 6 8 11 8h85c5 0 10 -4 11 -8l7 -55c13 -5 25 -13 36 -21l53 21c4 2 11 -1 13 -5l43 -71c3 -5 2 -11 -2 -14l-45 -34c0 -7 1 -14 1 -21s0 -15 -1 -21zM207 119c41 0 75 32 75 73s-34 73 -75 73
+s-74 -32 -74 -73s33 -73 74 -73z" />
+ <glyph glyph-name="ion-android-share-alt" unicode="&#xf3ac;" horiz-adv-x="384"
+d="M320 104c34 0 62 -28 62 -62s-28 -62 -62 -62s-62 28 -62 62c0 5 1 10 2 14l-152 88c-12 -11 -27 -17 -44 -17c-35 0 -64 29 -64 64s28 64 63 64c17 0 32 -6 44 -17l151 87c-1 5 -2 10 -2 15c0 35 29 64 64 64s64 -29 64 -64s-29 -64 -64 -64c-17 0 -32 6 -44 17
+l-151 -87c1 -5 2 -10 2 -15s-1 -10 -2 -15l153 -88c11 11 26 16 42 16z" />
+ <glyph glyph-name="ion-android-share" unicode="&#xf2f8;" horiz-adv-x="384"
+d="M384 200l-160 -147v88c-107 0 -171 -34 -224 -109c21 107 75 214 224 235v85z" />
+ <glyph glyph-name="ion-android-star-half" unicode="&#xf3ad;" horiz-adv-x="404"
+d="M404 238l-110 -96l33 -142l-125 75l-125 -75l33 142l-110 96l145 12l57 134l57 -134zM219 103l60 -36l-16 68l-5 19l15 12l53 46l-70 6l-19 2l-8 18l-27 64v-189z" />
+ <glyph glyph-name="ion-android-star-outline" unicode="&#xf3ae;" horiz-adv-x="404"
+d="M404 238l-110 -96l33 -142l-125 75l-125 -75l33 142l-110 96l145 12l57 134l57 -134zM219 103l60 -36l-16 68l-5 19l15 12l53 46l-70 6l-19 2l-8 18l-27 64l-27 -64l-8 -18l-19 -2l-70 -6l53 -46l15 -12l-5 -19l-16 -68l60 36l17 10z" />
+ <glyph glyph-name="ion-android-star" unicode="&#xf2fc;" horiz-adv-x="404"
+d="M202 75l-125 -75l33 142l-110 96l145 12l57 134l57 -134l145 -12l-110 -96l33 -142z" />
+ <glyph glyph-name="ion-android-stopwatch" unicode="&#xf2fd;" horiz-adv-x="384"
+d="M168 141v131h48v-131h-48zM344 278c25 -33 40 -74 40 -118c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192c44 0 85 -15 118 -40l31 30l33 -33zM298 54c28 28 44 66 44 106s-16 78 -44 106s-66 44 -106 44s-78 -16 -106 -44s-44 -66 -44 -106
+s16 -78 44 -106s66 -44 106 -44s78 16 106 44zM128 368v48h128v-48h-128z" />
+ <glyph glyph-name="ion-android-subway" unicode="&#xf3af;" horiz-adv-x="352"
+d="M176 400c94 0 176 -10 176 -85v-214c0 -42 -33 -74 -75 -74l27 -27v-16h-256v16l27 27c-42 0 -75 32 -75 74v214c0 75 82 85 176 85zM80 64c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM160 208v96h-112v-96h112zM272 64c18 0 32 14 32 32
+s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM304 208v96h-112v-96h112z" />
+ <glyph glyph-name="ion-android-sunny" unicode="&#xf3b0;"
+d="M224 288c-25 0 -50 -10 -68 -28s-28 -43 -28 -68s10 -50 28 -68s43 -28 68 -28s50 10 68 28s28 43 28 68s-10 50 -28 68s-43 28 -68 28zM245 416v0v-64h-42v64h42zM374 372v0l30 -30l-38 -38l-30 30zM74 372v0l38 -38l-30 -30l-38 38zM224 320v0c70 0 128 -58 128 -128
+s-58 -128 -128 -128s-128 58 -128 128s58 128 128 128zM448 213v0v-42h-64v42h64zM64 213v0v-42h-64v42h64zM366 80v0l38 -38l-30 -30l-38 38zM82 80v0l30 -30l-38 -38l-30 30zM245 32v0v-64h-42v64h42z" />
+ <glyph glyph-name="ion-android-sync" unicode="&#xf3b1;" horiz-adv-x="320"
+d="M160 355c88 0 160 -73 160 -163c0 -32 -9 -62 -25 -87l-29 30c9 17 14 37 14 57c0 67 -54 122 -120 122v-61l-80 82l80 81v-61zM160 70v61l80 -82l-80 -81v61c-88 0 -160 73 -160 163c0 32 9 63 25 87l29 -30c-9 -17 -14 -37 -14 -57c0 -67 54 -122 120 -122z" />
+ <glyph glyph-name="ion-android-textsms" unicode="&#xf3b2;" horiz-adv-x="384"
+d="M344 384c22 0 40 -18 40 -40v-240c0 -22 -18 -40 -40 -40h-280l-64 -64v344c0 22 10 40 32 40h312zM134 206v40h-38v-40h38zM211 206v40h-38v-40h38zM288 206v40h-38v-40h38z" />
+ <glyph glyph-name="ion-android-time" unicode="&#xf3b3;" horiz-adv-x="426"
+d="M213 405c117 0 213 -96 213 -213s-95 -213 -213 -213s-213 96 -213 213s95 213 213 213zM213 22c94 0 170 76 170 170s-76 170 -170 170s-170 -76 -170 -170s76 -170 170 -170zM224 298v-111l96 -57l-16 -26l-112 67v127h32z" />
+ <glyph glyph-name="ion-android-train" unicode="&#xf3b4;" horiz-adv-x="352"
+d="M0 101v214c0 75 82 85 176 85s176 -10 176 -85v-214c0 -42 -33 -74 -75 -74l27 -27v-16h-256v16l27 27c-42 0 -75 32 -75 74zM176 72c22 0 40 18 40 40s-18 40 -40 40s-40 -18 -40 -40s18 -40 40 -40zM304 224v96h-256v-96h256z" />
+ <glyph glyph-name="ion-android-unlock" unicode="&#xf3b5;" horiz-adv-x="320"
+d="M280 262c22 0 40 -18 40 -40v-200c0 -22 -18 -40 -40 -40h-240c-22 0 -40 18 -40 40v200c0 22 18 40 40 40h182v40v0c0 34 -28 62 -62 62s-62 -28 -62 -62h-38c0 55 45 100 100 100s100 -45 100 -100v-40h20zM160 80c22 0 40 18 40 40s-18 40 -40 40s-40 -18 -40 -40
+s18 -40 40 -40z" />
+ <glyph glyph-name="ion-android-upload" unicode="&#xf3b6;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121zM272 172h68l-100 100l-100 -100h68v-76h64v76z" />
+ <glyph glyph-name="ion-android-volume-down" unicode="&#xf3b7;" horiz-adv-x="288"
+d="M0 256h85l107 112v-352l-107 112h-85v128zM288 192c0 -38 -21 -73 -53 -88v177c32 -16 53 -51 53 -89z" />
+ <glyph glyph-name="ion-android-volume-mute" unicode="&#xf3b8;" horiz-adv-x="192"
+d="M0 256h85l107 112v-352l-107 112h-85v128z" />
+ <glyph glyph-name="ion-android-volume-off" unicode="&#xf3b9;" horiz-adv-x="384"
+d="M342 192c0 69 -45 128 -107 147v45c85 -20 149 -99 149 -192c0 -35 -8 -68 -24 -96l-32 32c9 19 14 41 14 64zM192 368v-104l-51 51zM357 51v0l24 -24l-24 -24l-40 40c-23 -21 -51 -36 -82 -43v45c19 6 37 15 52 28l-95 95v-152l-107 112h-85v128h85l9 10l-91 91l24 24z
+M288 192c0 -7 0 -15 -2 -22l-51 51v60c32 -16 53 -51 53 -89z" />
+ <glyph glyph-name="ion-android-volume-up" unicode="&#xf3ba;" horiz-adv-x="384"
+d="M0 256h85l107 112v-352l-107 112h-85v128zM288 192c0 -38 -21 -73 -53 -88v177c32 -16 53 -51 53 -89zM235 384c85 -20 149 -99 149 -192s-64 -172 -149 -192v45c62 19 106 78 106 147s-44 128 -106 147v45z" />
+ <glyph glyph-name="ion-android-walk" unicode="&#xf3bb;" horiz-adv-x="272"
+d="M168 336c-22 0 -40 18 -40 40s18 40 40 40s40 -18 40 -40s-18 -40 -40 -40zM168 216l-20 38l-20 -62l57 -96v-128h-38v96l-50 68l-57 -164h-40l81 320l-41 -16v-80h-40v112l111 38c4 1 10 1 13 1c13 0 23 -6 31 -18l45 -69h72v-40h-104z" />
+ <glyph glyph-name="ion-android-warning" unicode="&#xf3bc;"
+d="M0 -16l224 416l224 -416h-448zM248 48v48h-48v-48h48zM248 128v96h-48v-96h48z" />
+ <glyph glyph-name="ion-android-watch" unicode="&#xf3bd;" horiz-adv-x="320"
+d="M320 192c0 -51 -24 -96 -61 -125l-19 -115h-160l-19 115c-37 29 -61 74 -61 125s24 96 61 125l19 115h160l19 -115c37 -29 61 -74 61 -125zM40 192c0 -66 54 -120 120 -120s120 54 120 120s-54 120 -120 120s-120 -54 -120 -120z" />
+ <glyph glyph-name="ion-android-wifi" unicode="&#xf305;" horiz-adv-x="416"
+d="M208 219c23 0 42 -18 42 -41s-19 -41 -42 -41s-42 18 -42 41s19 41 42 41zM333 178c0 -45 -26 -85 -63 -107l-20 36c25 14 41 40 41 71c0 45 -37 82 -83 82s-83 -37 -83 -82c0 -31 16 -57 41 -71l-20 -36c-37 22 -63 62 -63 107c0 68 56 124 125 124s125 -56 125 -124z
+M208 384c114 0 208 -93 208 -206c0 -76 -42 -142 -104 -178l-21 36c50 28 83 81 83 142c0 91 -74 165 -166 165s-166 -74 -166 -165c0 -61 33 -113 83 -142l-21 -36c-62 36 -104 102 -104 178c0 113 94 206 208 206z" />
<glyph glyph-name="ion-aperture" unicode="&#xf313;"
d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56s100 20 136 56zM168 342l56 -86h-147
c17 40 50 71 91 86zM381 160h-102l72 129c21 -27 33 -60 33 -97c0 -11 -1 -22 -3 -32zM328 314l-49 -90l-78 126c8 1 15 2 23 2c40 0 76 -14 104 -38zM67 224h102l-72 -129c-21 27 -33 60 -33 97c0 11 1 22 3 32zM280 42l-56 86h147c-17 -40 -50 -71 -91 -86zM120 70l49 90
@@ -262,6 +380,13 @@ s-16 -34 -27 -46s-24 -22 -38 -28s-29 -10 -45 -10s-29 4 -39 12s-15 17 -15 29h-3c-
l-24 -113c-1 -6 -2 -12 -3 -19s-2 -13 -2 -19c0 -7 1 -13 4 -18s7 -7 15 -7c16 0 29 9 39 26s16 40 16 68c0 24 -4 45 -12 64s-20 34 -34 47s-32 23 -52 29s-41 9 -65 9c-26 0 -49 -4 -70 -13s-39 -22 -54 -38s-27 -34 -35 -56c-8 -21 -13 -44 -13 -69c0 -26 4 -51 13 -72
s21 -39 37 -54s35 -27 57 -35s46 -12 72 -12c33 0 61 6 85 16s45 25 65 43zM231 260c-10 0 -18 -2 -25 -8s-14 -13 -19 -22s-8 -18 -11 -28s-4 -20 -4 -30c0 -5 0 -10 1 -16c1 -5 3 -10 6 -15s7 -8 12 -11s11 -5 19 -5c11 0 20 3 28 8s14 13 19 21s9 16 11 26s3 19 3 27
c0 6 0 13 -1 19s-4 12 -7 17s-7 9 -12 12s-12 5 -20 5z" />
+ <glyph glyph-name="ion-backspace-outline" unicode="&#xf3be;" horiz-adv-x="512"
+d="M413 116c2 -2 3 -4 3 -6s-1 -4 -3 -6l-21 -22c-2 -2 -4 -2 -6 -2s-4 0 -6 2l-76 77l-76 -77c-2 -2 -4 -2 -6 -2s-4 0 -6 2l-21 22c-2 2 -3 4 -3 6s1 4 3 6l76 76l-77 76c-3 3 -3 9 0 12l22 22c2 2 4 2 6 2s4 0 6 -2l76 -76l76 76c2 2 4 2 6 2s4 0 6 -2l22 -22
+c3 -3 3 -9 0 -12l-77 -76zM499 354c9 -9 13 -20 13 -33v-256c0 -27 -20 -49 -46 -49h-298c-13 0 -24 3 -34 9c-9 5 -16 11 -23 20v0l-1 1l-110 146l110 148c14 19 34 28 58 28h298c13 0 24 -5 33 -14zM480 65v256c0 9 -5 15 -14 15h-298c-11 0 -22 -3 -32 -16l-96 -128
+l96 -128c8 -10 17 -16 32 -16h298c9 0 14 8 14 17z" />
+ <glyph glyph-name="ion-backspace" unicode="&#xf3bf;" horiz-adv-x="512"
+d="M499 354c9 -9 13 -20 13 -33v-256c0 -27 -20 -49 -46 -49h-298c-13 0 -24 3 -34 9c-9 5 -16 11 -23 20v0l-1 1l-110 146l110 148c14 19 34 28 58 28h298c13 0 24 -5 33 -14zM413 116l-76 76l77 76c3 3 3 9 0 12l-22 22c-2 2 -4 2 -6 2s-4 0 -6 -2l-76 -76l-76 76
+c-2 2 -4 2 -6 2s-4 0 -6 -2l-22 -22c-3 -3 -3 -9 0 -12l77 -76l-76 -76c-2 -2 -3 -4 -3 -6s1 -4 3 -6l21 -22c2 -2 4 -2 6 -2s4 0 6 2l76 77l76 -77c2 -2 4 -2 6 -2s4 0 6 2l21 22c2 2 3 4 3 6s-1 4 -3 6z" />
<glyph glyph-name="ion-bag" unicode="&#xf110;"
d="M416 288l32 -320h-448l32 320h64v4c0 68 56 124 124 124h8c68 0 124 -56 124 -124v-4h64zM128 292v-4h192v4c0 51 -41 92 -92 92v0h-8c-51 0 -92 -41 -92 -92zM36 0h376l-25 256h-35v-36c10 -6 16 -16 16 -28c0 -18 -14 -32 -32 -32s-32 14 -32 32c0 12 6 22 16 28v36
h-192v-36c10 -6 16 -16 16 -28c0 -18 -14 -32 -32 -32s-32 14 -32 32c0 12 6 22 16 28v36h-35z" />
@@ -276,10 +401,8 @@ d="M438 256c6 0 10 -4 10 -10v-108c0 -6 -4 -10 -10 -10h-37v-54c0 -6 -4 -10 -10 -1
<glyph glyph-name="ion-battery-low" unicode="&#xf115;"
d="M10 64c-6 0 -10 4 -10 10v236c0 6 4 10 10 10h381c6 0 10 -4 10 -10v-54h37c6 0 10 -4 10 -10v-108c0 -6 -4 -10 -10 -10h-37v-54c0 -6 -4 -10 -10 -10h-381zM369 288h-209l32 -192h177v32v32h32h15v64h-15h-32v32v32z" />
<glyph glyph-name="ion-beaker" unicode="&#xf269;" horiz-adv-x="384"
-d="M375 52c6 -9 9 -20 9 -32c0 -28 -16 -52 -63 -52h-258c-47 0 -63 24 -63 52c0 12 3 23 9 32l49 73l48 73l2 3c13 20 20 45 20 71v92s-15 30 -15 39s6 13 15 13h127c9 0 16 -3 16 -12s-15 -20 -15 -40v-92c0 -26 6 -51 19 -71l3 -4l48 -72zM345 7c3 3 7 8 7 14
-c0 5 -2 10 -4 14l-49 72v0v1l-48 72s-2 3 -3 5c-16 26 -24 56 -24 87v74c0 7 0 18 1 22c5 18 0 16 -9 16h-47c-9 0 -15 2 -10 -16c1 -4 1 -16 1 -22v-75c0 -32 -9 -61 -25 -86l-3 -5l-47 -73v0v0l-49 -73c-2 -4 -4 -9 -4 -14c0 -6 3 -10 6 -13c4 -4 12 -7 25 -7h258
-c13 0 20 3 24 7zM327 37l1 -1c1 -2 2 -5 2 -7c0 -7 -6 -13 -14 -13v0h-16h-30h-157h-29h-16v0c-7 0 -14 5 -14 13c0 3 1 6 3 8l8 13l1 1v0v1l16 23l42 66l1 1v0v0l12 18h109l14 -20v0l1 -1l1 -2l40 -62l12 -18zM238 106c2 -1 4 -2 6 -2s3 0 5 2c1 2 3 4 3 6s-1 4 -3 6
-c-1 2 -3 2 -5 2s-4 0 -6 -2c-1 -2 -2 -4 -2 -6s0 -4 2 -6zM274 50c2 -2 5 -4 7 -4c1 0 3 0 4 1c4 2 4 7 2 11l-23 36c-1 2 -4 4 -7 4c-2 0 -3 0 -4 -1c-4 -2 -5 -7 -3 -11zM124 141v0c-4 -5 0 0 0 0z" />
+d="M80 256h240v-224c0 -9 -7 -16 -16 -16h-208c-9 0 -16 7 -16 16v224zM296 104v48c0 4 -4 8 -8 8s-8 -4 -8 -8v-48c0 -4 4 -8 8 -8s8 4 8 8zM288 176c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM381 416c3 0 3 -2 3 -3s-2 -3 -3 -5s-13 -20 -13 -40v-336
+c0 -35 -29 -64 -64 -64h-208c-35 0 -64 29 -64 64v307c0 32 -2 33 -32 37c0 12 11 40 65 40h316zM336 368c0 5 0 16 1 16h-273c-1 0 -3 0 -4 -1c5 -7 4 -32 4 -44v-307c0 -18 14 -32 32 -32h210c17 0 30 14 30 32v336z" />
<glyph glyph-name="ion-beer" unicode="&#xf26a;"
d="M384 288c35 0 64 -29 64 -64v-96c0 -35 -29 -64 -64 -64h-32v-80c0 -9 -7 -16 -16 -16h-256c-9 0 -16 7 -16 16v223c-26 0 -48 22 -48 48v54v1c-10 11 -16 26 -16 42c0 35 29 64 64 64c18 0 34 -8 46 -20c10 12 26 20 43 20c14 0 27 -6 37 -14c12 9 26 14 42 14
c17 0 34 -6 46 -16c11 10 26 16 42 16c35 0 64 -29 64 -64c0 -24 -18 -44 -32 -48v-16h32zM296 144c4 0 8 3 8 8v0v48c0 4 -4 8 -8 8s-8 -4 -8 -8v-48c0 -3 2 -6 4 -7c1 -1 2 -1 4 -1zM303 220c1 2 1 4 1 6s-1 4 -3 5s-4 1 -6 1s-4 -2 -5 -4s-2 -4 -2 -6s2 -4 4 -5
@@ -299,6 +422,10 @@ c-10 -10 -25 -10 -35 0s-10 25 0 35c2 2 3 3 5 4zM288 320c0 -32 -9 -58 -50 -86c-37
c21 14 38 31 47 49c5 -15 5 -48 0 -64zM88 288c-6 4 -9 14 -8 27c2 22 34 39 32 69c14 2 31 -3 42 -24c-5 -11 -15 -21 -28 -34s-26 -22 -38 -38z" />
<glyph glyph-name="ion-bookmark" unicode="&#xf26b;" horiz-adv-x="192"
d="M184 384c4 0 8 -4 8 -8v-56h-192v56c0 4 4 8 8 8h176zM0 0v304h192v-304l-96 96z" />
+ <glyph glyph-name="ion-bowtie" unicode="&#xf3c0;"
+d="M192 236c0 0 8 5 20 7c21 4 39 5 47 -9c10 -17 19 -53 17 -85c-1 -17 -5 -22 -5 -22s-15 -10 -47 -7c-35 3 -40 15 -40 15s5 12 8 43s0 58 0 58zM152 163c-17 -4 -38 -10 -38 -10s45 4 64 9c-4 -21 -10 -34 -10 -34s-83 -80 -116 -80c-28 0 -52 68 -52 144s26 144 52 144
+c35 0 106 -57 128 -97c0 0 3 -16 2 -32c-10 5 -24 10 -44 14c-28 6 -42 3 -42 3s18 -4 57 -17c15 -5 22 -8 29 -10c0 -3 -1 -7 -1 -10c0 -5 0 -10 -1 -15c-5 -2 -15 -6 -28 -9zM396 336c26 0 52 -68 52 -144s-24 -144 -52 -144c-37 0 -104 68 -112 79c0 0 4 5 5 22v9
+c16 -7 70 -13 70 -13s-21 6 -40 11c-13 4 -25 8 -30 10c-1 11 -2 23 -4 33c17 11 69 34 69 34s-15 -2 -35 -9c-14 -5 -29 -11 -37 -14c-3 10 -7 18 -10 24c0 1 -1 4 -1 4v1c22 40 89 97 125 97z" />
<glyph glyph-name="ion-briefcase" unicode="&#xf26c;"
d="M240 176v8h208v-176c0 -4 -4 -8 -8 -8h-432c-4 0 -8 4 -8 8v176h208v-8h32zM440 304c4 0 8 -4 8 -8v-96h-208v8h-32v-8h-208v96c0 4 4 8 8 8h120v31c1 28 22 49 51 49h90c30 0 50 -21 51 -49v-31h120zM288 332v1c0 10 -9 19 -19 19h-90c-10 0 -19 -9 -19 -19v-1v-1v-27
h128v27v1z" />
@@ -324,8 +451,8 @@ h192v-16h-192zM64 96v16h96v-16h-96zM320 96v48h64v-48h-64z" />
d="M0 352h512v-256h-512v256zM193 128c-20 23 -33 58 -33 96s13 73 33 96h-97c0 -35 -29 -64 -64 -64v-80c27 0 48 -21 48 -48h113zM298 187c3 4 4 9 4 15c0 3 0 5 -1 8s-2 6 -4 8s-4 4 -7 6s-6 4 -10 5c-1 0 -4 1 -7 2s-5 0 -8 1v31c2 -1 5 -2 7 -3c4 -3 6 -7 7 -13h20
c0 5 -2 9 -4 13s-5 8 -9 11s-9 5 -14 6c-2 1 -5 2 -7 2v9h-18v-9c-2 0 -4 -1 -6 -2c-5 -1 -10 -2 -14 -5s-7 -6 -9 -10s-4 -9 -4 -14c0 -3 0 -5 1 -8s2 -5 4 -7s5 -5 8 -7s7 -4 12 -5c3 -1 6 0 8 -1v-35c-3 1 -6 2 -9 4s-5 4 -6 7s-2 6 -2 9h-20c0 -5 2 -11 4 -16
c3 -5 6 -8 10 -11s9 -6 15 -7c3 -1 5 -2 8 -2v-9h18v9c3 0 6 1 9 2c5 1 10 2 14 5s7 7 10 11zM480 176v80c-35 0 -64 29 -64 64h-97c20 -23 33 -58 33 -96s-13 -73 -33 -96h113c0 27 22 48 48 48zM64 224c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32z
-M384 224c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32zM273 213c2 -1 4 -2 6 -4s3 -5 3 -9c0 -2 0 -4 -1 -6s-2 -4 -4 -5s-5 -3 -8 -4c-1 0 -2 -1 -4 -1v31c3 -1 6 -1 8 -2zM236 257c1 2 3 3 5 4s4 2 6 2v-26c-4 1 -7 3 -9 5s-4 4 -4 8c0 3 1 5 2 7zM0 64
-v16h512v-16h-512zM0 32v16h512v-16h-512z" />
+M384 224c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32zM273 213c2 -1 4 -2 6 -4s3 -5 3 -9c0 -2 0 -4 -1 -6s-2 -4 -4 -5s-5 -3 -8 -4c-1 0 -2 -1 -4 -1v31c3 -1 6 -1 8 -2zM236 257c1 2 3 3 5 4s4 2 6 2v-26c-4 1 -7 3 -9 5s-4 4 -4 8c0 3 1 5 2 7zM0 32
+v32h512v-32h-512z" />
<glyph glyph-name="ion-chatbox-working" unicode="&#xf11a;" horiz-adv-x="416"
d="M76 48c-42 0 -76 31 -76 71v209c0 40 34 72 76 72h264c42 0 76 -32 76 -72v-209c0 -40 -34 -71 -76 -71h-4v-64s-79 54 -86 59s-7 5 -21 5h-153zM304 256c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM208 256c-18 0 -32 -14 -32 -32s14 -32 32 -32
s32 14 32 32s-14 32 -32 32zM112 256c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32z" />
@@ -358,14 +485,13 @@ d="M170 192v0v0l-167 174c-4 4 -4 12 0 16l30 30c4 4 12 5 16 1l204 -213c2 -2 3 -5
<glyph glyph-name="ion-chevron-up" unicode="&#xf126;"
d="M224 234l-174 -167c-4 -4 -12 -4 -16 0l-31 30c-4 4 -4 12 0 16l213 204c2 2 5 3 8 3s6 -1 8 -3l213 -204c4 -4 4 -12 0 -16l-31 -30c-4 -4 -12 -4 -16 0l-174 167v0v0z" />
<glyph glyph-name="ion-clipboard" unicode="&#xf127;" horiz-adv-x="352"
-d="M80 288c2 20 10 35 28 40l1 1c12 3 21 7 21 20v21c0 26 20 46 46 46s46 -20 46 -46v-21c0 -13 9 -18 21 -21h1c18 -5 26 -20 28 -40h-192zM176 384c-8 0 -14 -6 -14 -14s6 -14 14 -14s14 6 14 14s-6 14 -14 14zM325 385c15 0 27 -13 27 -29v-360c0 -16 -12 -28 -27 -28
-h-149h-149c-15 0 -27 12 -27 28v360c0 16 12 29 27 29h74v-15c0 -11 -9 -18 -19 -18h-37c-7 0 -13 -5 -13 -12v-328c0 -6 6 -12 12 -12h264c6 0 12 6 12 12v328c0 7 -6 12 -13 12h-37c-10 0 -19 7 -19 18v15h74zM64 240v16h112v-16h-112zM64 144v16h160v-16h-160zM64 48v16
-h129v-16h-129zM64 96v16h176v-16h-176zM64 192v16h208v-16h-208z" />
+d="M80 288c2 20 10 35 28 40l1 1c12 3 21 7 21 20v21c0 26 21 46 46 46s46 -20 46 -46v-21c0 -13 9 -18 21 -21h2c18 -5 25 -20 27 -40h-192zM176 384c-8 0 -13 -6 -13 -14s5 -14 13 -14s14 6 14 14s-6 14 -14 14zM325 384c15 0 27 -12 27 -28v-360c0 -16 -12 -28 -27 -28
+h-149h-148c-15 0 -28 12 -28 28v360c0 16 13 28 28 28h73v-13c0 -11 -9 -19 -19 -19h-37c-7 0 -12 -6 -12 -13v-327c0 -6 5 -12 11 -12h265c6 0 11 6 11 12v327c0 7 -5 13 -12 13h-37c-10 0 -20 8 -20 19v13h74zM64 224v32h112v-32h-112zM64 32v32h160v-32h-160zM64 96v32
+h129v-32h-129zM64 160v32h208v-32h-208z" />
<glyph glyph-name="ion-clock" unicode="&#xf26e;"
-d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM393 283c-2 3 -3 6 -5 9zM324 356c-3 2 -6 3 -9 5zM133 361c-3 -2 -6 -3 -9 -5zM60 292c-2 -3 -3 -6 -5 -9zM55 101c2 -3 3 -6 5 -9zM124 28c3 -2 6 -3 9 -5zM315 23
-c3 2 6 3 9 5zM360 56c10 10 18 21 26 33l-27 16l8 14l27 -16c13 25 21 52 22 81h-32v16h32c-1 29 -9 56 -22 81l-28 -16l-8 14l28 16c-8 12 -16 23 -26 33s-21 18 -33 26l-16 -27l-14 8l16 27c-25 13 -52 21 -81 22v-32h-16v32c-29 -1 -56 -9 -81 -22l16 -28l-14 -8l-16 28
-c-12 -8 -23 -16 -33 -26s-18 -21 -26 -33l27 -16l-8 -14l-27 16c-13 -25 -21 -52 -22 -81h32v-16h-32c1 -29 9 -56 22 -81l28 16l8 -14l-28 -16c8 -12 16 -23 26 -33s21 -18 33 -26l16 27l14 -8l-16 -27c25 -13 52 -21 81 -22v32h16v-32c29 1 56 9 81 22l-16 27l14 8l16 -27
-c12 8 23 16 33 26zM393 101l-5 -9c2 3 3 6 5 9zM368 199v-16h-113c-4 -13 -17 -23 -31 -23c-7 0 -15 3 -20 7l-70 -71l-6 6l71 70c-4 6 -7 13 -7 20c0 12 6 22 16 28v84h32v-84c8 -4 13 -12 15 -21h113z" />
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c10 10 19 21 26 33l-27 16l8 14l27 -16c13 25 21 52 22 81h-32v16h32c-1 29 -9 56 -22 81l-27 -16l-8 14l27 16c-7 12 -16 23 -26 33s-21 19 -33 26l-16 -27l-14 8
+l16 27c-25 13 -52 21 -81 22v-32h-16v32c-29 -1 -56 -9 -81 -22l16 -27l-14 -8l-16 27c-12 -7 -23 -16 -33 -26s-19 -21 -26 -33l27 -16l-8 -14l-27 16c-13 -25 -21 -52 -22 -81h32v-16h-32c1 -29 9 -56 22 -81l27 16l8 -14l-27 -16c7 -12 16 -23 26 -33s21 -19 33 -26
+l16 27l14 -8l-16 -27c25 -13 52 -21 81 -22v32h16v-32c29 1 56 9 81 22l-16 27l14 8l16 -27c12 7 23 16 33 26zM368 207v-32h-117c-6 -9 -16 -15 -27 -15c-18 0 -32 14 -32 32c0 12 6 22 16 28v68h32v-68c5 -3 9 -8 12 -13h116z" />
<glyph glyph-name="ion-close-circled" unicode="&#xf128;"
d="M224 415c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM332 116l-75 75l76 75c3 3 3 9 0 12l-22 21c-2 2 -4 3 -6 3s-3 -1 -5 -3l-76 -74l-76 74c-2 2 -3 3 -5 3s-4 -1 -6 -3l-21 -21c-3 -3 -3 -9 0 -12l76 -75l-76 -76
c-2 -1 -2 -3 -2 -5s0 -4 2 -6l21 -22c2 -2 4 -2 6 -2s4 0 6 2l75 76l76 -75c2 -2 3 -3 5 -3s4 1 6 3l21 21c2 1 3 4 3 6s-1 4 -3 6z" />
@@ -406,6 +532,8 @@ s9 5 9 10v150z" />
d="M0 32v64h64v-64h-64zM96 32v128h64v-128h-64zM192 32v224h64v-224h-64zM288 32v320h64v-320h-64z" />
<glyph glyph-name="ion-contrast" unicode="&#xf275;"
d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56v-384c51 0 100 20 136 56z" />
+ <glyph glyph-name="ion-crop" unicode="&#xf3c1;"
+d="M320 -32v48h64v-48h-64zM384 96h64v-64h-384v256h-64v64h64v64h64v-320h192v192h-176v64h240v-256z" />
<glyph glyph-name="ion-cube" unicode="&#xf318;"
d="M435 280c7 0 13 -6 13 -12v-183c0 -9 -6 -17 -14 -22v-1l-175 -92v-1c-2 -1 -4 -1 -6 -1c-7 0 -13 6 -13 12v185c0 9 5 17 13 22v0l3 2l172 89l2 1c2 1 3 1 5 1zM422 329c0 0 8 -3 8 -9c0 -7 -8 -11 -8 -11l-183 -97l-2 -1c-4 -2 -8 -3 -13 -3s-9 1 -13 3l-2 1l-183 96
s-8 5 -8 12c0 6 8 9 8 9l181 82s11 5 17 5s17 -5 17 -5zM195 187c8 -5 13 -13 13 -22v-185c0 -6 -6 -12 -13 -12c-2 0 -4 1 -6 2v0l-175 92v1c-8 5 -14 13 -14 22v183c0 6 6 12 13 12c2 0 4 0 5 -1l2 -1l171 -89z" />
@@ -421,33 +549,36 @@ d="M287 279c1 -3 1 -5 1 -9v-244c0 -13 -9 -26 -21 -26h-243c-12 0 -24 13 -24 26v33
<glyph glyph-name="ion-drag" unicode="&#xf130;" horiz-adv-x="512"
d="M0 272v32h512v-32h-512zM0 176v32h512v-32h-512zM0 80v32h512v-32h-512z" />
<glyph glyph-name="ion-earth" unicode="&#xf276;"
-d="M308 321c-1 0 0 -1 -1 -1s-4 4 -3 5l1 1l1 1l2 1l1 1v1c0 1 -1 2 -1 3v2c1 1 2 1 3 1l1 -1l2 -1l1 -2c0 -1 1 -1 2 -1c2 -1 4 -2 5 -3c3 -3 5 -7 6 -11v-2c-2 -1 -3 -3 -5 -4c-1 -1 -2 -1 -3 -1c-2 0 -4 1 -5 2s-1 2 -1 3c0 2 -1 4 -1 6c0 1 -1 1 -1 1h-2s-1 -1 -2 -1z
-M253 351l-1 1c0 1 0 4 1 4h1c4 1 6 3 10 4h1c1 0 2 -1 3 -2c2 -2 2 -3 0 -5v0l-1 -2c0 -1 -1 -2 -1 -3v-1h-1c-3 0 -6 1 -8 2c-2 0 -3 1 -4 2zM134 270h-5c-5 0 -10 1 -14 2h-3s-1 1 -2 1v1s1 2 2 3c1 0 1 1 2 1s2 1 3 1s2 0 3 -1l1 -1l1 -1c2 -1 4 -2 6 -2h5c1 0 1 -1 2 -1
-h1l1 -1c0 -1 0 -2 -1 -2h-2zM144 263c0 0 1 -1 2 -1s1 -1 1 -1v-4h-1v0h-1c-2 1 -5 2 -7 2h-4h-3h-1v1v0c1 0 1 1 2 1l8 4v0l1 -1c1 -1 2 0 3 -1zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM88 56c11 -11 24 -20 37 -28
-c-1 1 -3 2 -4 3l-7 7c-3 4 -4 9 -6 13v1c0 2 -1 4 -1 6c0 3 -2 7 -2 10v1c-1 1 -1 2 -1 3s-1 3 -1 4c0 3 1 5 1 8v3c0 3 1 5 1 8v2c-1 1 -1 3 -1 4v5s0 5 1 7c0 1 1 1 1 2v5c0 3 2 7 2 10v1c-2 1 -2 2 -3 3c-2 2 -2 4 -2 7c0 2 0 4 1 6v1h-1c-4 3 -8 6 -11 10
-c-1 2 -2 4 -4 6l-3 3s-2 3 -2 4c-1 2 -1 4 -1 6v2c-1 2 -1 4 -1 6v8s1 4 2 6c0 1 1 1 2 2c2 2 3 5 5 7l3 6c1 1 2 2 2 4c1 2 1 4 1 6v3c0 2 -1 3 -3 4l-1 1c-2 1 -4 3 -6 4v1c-1 4 -2 5 -3 9c0 1 -1 3 -1 3c-2 1 -3 3 -5 4v2v3s1 3 1 4h-1c-3 1 -6 3 -9 5c-2 1 -3 2 -4 4
-c-1 1 -2 3 -3 4c-1 2 -1 3 -1 5c0 3 2 7 2 10v2h-1v1v0c-19 -30 -29 -65 -29 -101c0 -51 20 -100 56 -136zM403 251c0 0 0 -1 1 -1v1c0 2 0 5 -1 7s-2 3 -3 4c0 0 -10 -6 -27 14s-24 16 -24 16s-2 -2 -2 -1h-1v0v-2c0 -1 -1 -2 -1 -4s-1 -6 -1 -8v-1h-1c-3 -1 -6 -1 -9 -2
-c-2 0 -4 -1 -6 0s-3 2 -4 3c-2 2 -3 3 -4 5c-2 3 -4 7 -6 10v1v0c2 1 3 2 4 3h1c1 0 3 1 4 1c2 0 3 1 5 1h3c2 2 5 2 7 4v1c2 2 3 4 5 6l1 1l-1 1l-2 4v2c0 2 1 3 1 5v2c-3 0 -6 1 -9 1c-1 2 -3 5 -4 7h-1c-2 0 -3 1 -5 1h-1c-1 1 -2 2 -2 3c-1 2 -2 3 -2 5c-1 4 0 8 0 12v0
-c3 0 7 1 10 1c-18 11 -38 20 -58 25v-1c-2 -4 -4 -6 -6 -10c-1 -1 -1 -2 -2 -2c-2 0 -4 -1 -6 -1s-2 0 -3 -1v-1c-2 -2 -4 -5 -6 -7c-3 -3 -6 -6 -9 -10v-1h-1v1c-2 1 -4 2 -5 4c-2 2 -3 4 -4 6c-2 4 -3 8 -3 12c0 1 1 1 1 1c1 3 2 7 3 10c0 1 1 1 1 2v1v2v0h-6h-3v0l4 -8
-v-1h-1c-2 -1 -3 -3 -5 -4l-1 -1l-5 -5v0c0 1 -1 1 -2 2s-3 2 -5 3v1h-6l-2 -1c-1 0 -1 -1 -2 -1h-3c-2 0 -2 0 -3 2c0 1 -1 1 -2 1h-1l-2 -1l-3 -3s-2 -1 -3 -2l-1 -1l-6 -3v-1c0 -1 -1 -1 -1 -2v-6c0 -1 1 -2 1 -3c1 -2 1 -2 3 -2h2c1 1 3 1 4 2c2 1 3 2 4 3s3 2 3 4v1
-c0 1 1 0 2 0v0h2c1 -1 3 -1 4 0c1 0 1 0 2 1l2 2s3 2 4 2c2 0 3 1 4 -1v-1l2 -2c1 0 1 -2 2 -2l2 -1c1 -1 1 -1 1 -2s-1 -1 -1 -2s-1 -2 -2 -3c0 -1 -1 -2 -1 -3l-1 -1c0 -1 0 -1 1 -1h1c1 0 2 1 3 1v0v-1c0 -2 -1 -4 -1 -6s-1 -3 -2 -5c0 -1 0 -1 -1 -2s-3 -2 -5 -2
-c-1 0 -2 1 -3 1s-2 1 -2 1c-1 1 -1 1 -2 1h-3h-1c-1 0 -1 -1 -1 -2s-2 -1 -2 -2l-1 -1h-1c-2 0 -3 -1 -5 -1h-8h-1c-3 -1 -7 -2 -10 -3c-1 0 -1 -1 -1 -1c-1 -1 -2 -1 -3 -1c-1 -1 -3 -2 -4 -2h-3h-2l-1 1c-5 -6 -18 -6 -22 -12v-1c0 -2 -1 -3 -1 -5c0 -4 0 -8 -1 -12
-c0 -1 -1 -1 -1 -2l-1 -1h-2l-1 1s-1 0 -1 1s-1 2 -1 3c-1 2 -1 3 -1 5c0 3 -2 4 -4 6c-1 1 -2 2 -3 2c-2 1 -5 1 -7 1c-1 0 -1 1 -2 1c-2 0 -4 -1 -6 -1c-8 -2 -13 -8 -18 -14v-1c-1 -3 -2 -5 -2 -8c0 -2 1 -4 1 -5c1 -2 2 -3 4 -3h5c1 0 2 1 3 1h2c1 0 1 -1 2 -2s0 -3 0 -4
-s-1 -1 -1 -1c-1 -1 -1 -2 -2 -3s-2 -1 -3 -1s-1 -2 -1 -3s-1 -1 0 -2l1 -1s1 -1 2 -1v-2v-1v-10v-2c0 -3 2 -5 5 -7l1 -1c2 -1 3 -3 5 -3h5c2 0 3 1 5 3c1 1 1 2 2 3l1 1c1 1 3 2 4 2s2 0 3 -1l2 -2l2 -1c3 -1 5 -3 8 -4l1 -1c2 0 3 0 5 -1c4 -2 7 -4 10 -8c0 0 1 -1 2 -1
-c7 -2 14 -7 19 -12c3 -3 5 -7 7 -11c0 -1 1 -3 1 -4l1 -1c2 -2 3 -3 4 -5s3 -5 4 -7v0s3 -1 4 -1c5 -1 10 -3 14 -6c4 -2 5 -4 8 -7c1 -1 2 -1 2 -3v-5c-1 -6 -4 -11 -10 -15c0 0 -1 0 -1 -1c-2 -5 -4 -11 -6 -16l-1 -1c-3 -4 -5 -7 -8 -11l-1 -1c-1 0 -1 -2 -2 -2
-c-4 -2 -9 -3 -13 -4c-1 0 -1 -1 -1 -1c-2 -3 -5 -7 -8 -10v0c-1 -1 -2 -3 -3 -4c-2 -3 -3 -6 -5 -9c0 -1 -1 -2 -2 -2c-4 -3 -9 -6 -13 -9h-1l-7 -7c0 0 -1 -1 -1 -2c-1 -2 -2 -3 -3 -5s-1 -4 -2 -6l-1 -2s1 -1 1 -2c1 -6 3 -19 4 -25v-1c28 -15 59 -24 92 -24
-c40 0 77 12 109 34c-1 1 -1 2 -1 3v2c0 2 1 3 2 5c2 3 2 7 4 10c1 3 4 6 5 9c0 1 1 3 1 4v2s-1 3 -1 4c0 2 -1 5 -1 7c-1 3 -1 5 0 8l3 6s2 4 4 6l1 1l4 4c2 2 2 3 3 5c1 3 2 6 1 9c0 2 -1 4 -2 6s-2 3 -2 5c-1 3 -1 7 0 10c0 1 2 3 2 4c1 2 1 3 2 5s1 3 1 5c0 3 0 6 -1 8v2
-s-1 1 -2 1l-1 -1h-2l-1 -1c-1 0 -1 0 -2 1h-1c-1 1 -1 2 -2 2s-2 1 -3 1c-2 0 -5 1 -7 1c-4 0 -7 -1 -11 -1c-3 0 -7 0 -10 1s-5 3 -8 5c-4 2 -7 4 -10 7c-4 3 -7 7 -10 10l-1 1v1c0 2 -1 4 -1 6c0 4 1 7 2 11c1 5 1 10 3 15c1 2 1 3 1 5s1 3 1 5c0 1 -1 2 -1 3v0v2v1
-c0 1 1 1 1 2c3 6 8 10 15 12l1 1c2 3 5 6 7 9c0 0 1 1 2 1c4 1 7 2 11 3c3 1 5 2 8 2s6 -1 8 -1c3 0 6 -1 8 -2h1h9c2 0 3 -1 5 -2c1 0 1 -1 2 -1s1 -1 2 -1c5 -4 9 -7 14 -11h2v0h9c2 0 4 -1 6 -1z" />
+d="M325 322c2 -4 7 -12 3 -15c-3 -2 -10 -2 -13 5s0 11 -5 9s-7 3 -6 4c1 2 3 3 5 4c0 2 -4 8 2 7c4 -1 12 -10 14 -14zM344 277v0v0zM403 251c0 0 -2 0 0 0v0zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM141 19l8 -4
+c3 -1 6 -2 10 -3c14 -5 28 -8 43 -10c28 -3 56 -1 83 8c15 5 30 11 43 20c6 4 6 16 10 24c8 16 -2 33 12 47c12 14 4 19 4 34c0 10 8 18 4 29c-1 4 -7 -3 -9 1c-5 7 -21 1 -28 2c-13 2 -24 14 -33 23c-5 5 0 20 1 26c4 15 0 33 19 38c5 1 5 9 10 11c5 1 10 3 15 4
+c9 1 17 -2 26 -2c10 0 14 -5 22 -11c7 -6 13 -3 22 -5c7 0 0 5 -2 8c-3 2 -6 2 -8 2c-16 4 -23 22 -36 30c-6 3 -9 2 -11 0c-1 -1 1 -12 1 -12c-1 -3 -10 -4 -13 -5c-9 -2 -29 17 -15 22c4 1 27 5 24 15c-3 6 2 13 -5 14c-8 1 -7 7 -15 8c-5 1 -5 11 -5 14c0 9 2 6 9 7
+c-17 11 -37 19 -57 24c-1 -3 -5 -12 -8 -12c-5 -1 -6 0 -9 -3c-9 -10 -16 -28 -25 -7c-4 11 5 19 2 28h-6h-3c6 -12 -5 -18 -8 -19c-8 0 -10 5 -17 4c-4 -1 -7 4 -11 2s-13 -8 -14 -12c-3 -12 6 -13 14 -6c6 6 17 12 25 6c6 -5 5 -9 5 -14s-1 -18 -9 -16c-4 1 -7 6 -11 3
+c-8 -7 -18 -6 -29 -9c-10 -2 -16 -6 -25 -9c-8 -3 -11 -4 -12 -12c0 -2 0 -14 -3 -15c-5 -2 -8 22 -22 20c-12 -1 -30 -13 -25 -28c2 -5 28 -3 10 -14c-2 -1 2 -17 2 -20c1 -8 13 -18 21 -10c6 6 6 5 14 2c15 -8 33 -15 45 -27c6 -6 9 -24 17 -28c9 -5 19 -5 26 -14
+c6 -7 -2 -19 -8 -23c-4 -2 -12 -24 -16 -29c-2 -4 -12 -6 -16 -7c-3 0 -7 -9 -9 -11c-7 -7 -8 -13 -17 -19c-18 -12 -22 -23 -18 -44c2 -8 5 -13 11 -16zM100 46l2 -2c7 -6 15 -11 23 -16c-21 21 -23 49 -21 78l3 24c1 3 -4 7 -4 11c0 10 0 5 -8 13c-4 4 -10 11 -12 17
+c-7 16 1 30 10 43c9 14 -7 20 -10 32c-1 6 -7 6 -6 12c1 7 -4 5 -9 9c-12 8 -1 20 -7 26c-43 -70 -36 -162 16 -224c1 -1 0 -1 1 -2h1c3 -4 6 -8 9 -11s7 -6 10 -9z" />
+ <glyph glyph-name="ion-easel" unicode="&#xf3c2;"
+d="M48 112v192h352v-192h-352zM432 352c9 0 16 -7 16 -16v-256c0 -9 -7 -16 -16 -16h-416c-9 0 -16 7 -16 16v256c0 9 7 16 16 16h416zM416 96v224h-384v-224h384zM48 -32l29 80h31l-28 -80h-32zM239 416l17 -48h-64l17 48h30zM340 48h31l29 -80h-32zM208 0v48h32v-48h-32z
+" />
<glyph glyph-name="ion-edit" unicode="&#xf2bf;"
-d="M381 259l-250 -251l-91 91l251 250zM440 360c12 -12 11 -32 -2 -45l-45 -45l-91 91l45 45c13 13 33 14 45 2zM14 17l18 68l85 -85l-68 -18zM0 -32l9 32l23 -23z" />
+d="M381 259l-250 -251l-91 91l251 250zM440 360c12 -12 11 -32 -2 -45l-45 -45l-91 91l45 45c13 13 33 14 45 2zM32 85l85 -85l-117 -32z" />
<glyph glyph-name="ion-egg" unicode="&#xf277;" horiz-adv-x="320"
d="M160 416c64 0 160 -133 160 -257s-64 -191 -160 -191s-160 67 -160 191s96 257 160 257z" />
<glyph glyph-name="ion-eject" unicode="&#xf131;" horiz-adv-x="320"
d="M303 128h-286v0c-10 0 -17 7 -17 16c0 3 1 5 3 8l138 191c5 5 11 9 19 9s14 -4 19 -9l138 -190c2 -3 3 -6 3 -9c0 -9 -7 -16 -17 -16v0zM308 96c7 0 12 -5 12 -12v-40c0 -7 -5 -12 -12 -12h-296c-7 0 -12 5 -12 12v40c0 7 5 12 12 12h296z" />
+ <glyph glyph-name="ion-email-unread" unicode="&#xf3c3;" horiz-adv-x="480"
+d="M352 288c0 43 21 64 64 64s64 -21 64 -64s-21 -64 -64 -64s-64 21 -64 64zM209 288h127c0 -17 5 -33 15 -47c-6 -3 -14 -8 -22 -12s-16 -8 -23 -12s-14 -8 -22 -12s-15 -8 -21 -11s-11 -6 -16 -9s-9 -5 -12 -7s-4 -3 -5 -3c-6 -3 -13 -4 -21 -4s-15 1 -21 4
+c-1 1 -15 8 -42 23s-54 29 -81 44s-43 23 -46 25c-7 4 -12 8 -13 11c-1 4 -1 6 1 8s6 2 11 2h191zM277 175c18 11 45 30 83 56c16 -15 34 -23 56 -23v-155c0 -2 -1 -4 -2 -7s-3 -5 -5 -7s-4 -4 -7 -5s-6 -2 -8 -2h-185h-185c-5 0 -11 2 -16 7s-8 9 -8 14v205c0 6 3 8 9 5
+c2 -1 11 -7 26 -17s32 -22 53 -36s39 -26 53 -35l-83 -93c-2 -2 -2 -4 -1 -5c2 -1 4 -1 6 1l98 83c16 -10 25 -16 27 -17c6 -3 13 -4 21 -4s15 1 21 4c2 1 11 7 27 17l98 -83c2 -2 5 -2 6 -1s0 3 -2 5z" />
<glyph glyph-name="ion-email" unicode="&#xf132;" horiz-adv-x="416"
d="M19 299c-4 2 -11 7 -13 11c-3 8 1 10 12 10h191h191c11 0 15 -2 12 -10c-2 -4 -9 -9 -13 -11c-11 -6 -163 -89 -169 -92s-12 -4 -21 -4s-15 1 -21 4s-158 86 -169 92zM408 295c9 4 8 -1 8 -5v-205c0 -9 -12 -21 -22 -21h-185h-185c-10 0 -24 12 -24 21v205s0 9 9 5
c8 -4 83 -56 132 -88l-83 -93c-2 -2 -2 -4 -1 -5s4 -1 6 1l98 83c15 -10 25 -16 27 -17c8 -4 14 -4 21 -4s13 0 21 4c2 1 12 7 27 17l98 -83c2 -2 5 -2 6 -1s0 3 -2 5l-82 93c49 32 123 84 131 88z" />
+ <glyph glyph-name="ion-erlenmeyer-flask-bubbles" unicode="&#xf3c4;" horiz-adv-x="384"
+d="M382 21c2 -4 3 -10 0 -14s-8 -7 -13 -7h-177h-178c-5 0 -9 3 -12 7s-2 10 0 14l118 199v150c0 8 6 14 14 14s15 -6 15 -14v-80c4 3 10 5 16 5c15 0 27 -12 27 -27s-12 -26 -27 -26c-6 0 -12 2 -16 5v-31c0 -2 -1 -4 -2 -6l-35 -59h72c-15 6 -26 20 -26 37
+c0 23 19 42 43 42c15 0 27 -8 35 -19c-1 2 -1 3 -1 5v154c0 8 6 14 14 14s15 -6 15 -14v-150zM218 151h53l-31 54c2 -5 3 -11 3 -17c0 -17 -10 -31 -25 -37zM201 319c-12 0 -22 9 -22 21s10 21 22 21s22 -9 22 -21s-10 -21 -22 -21z" />
+ <glyph glyph-name="ion-erlenmeyer-flask" unicode="&#xf3c5;" horiz-adv-x="384"
+d="M375 52c6 -9 9 -20 9 -32c0 -28 -16 -52 -63 -52h-258c-47 0 -63 24 -63 52c0 12 3 23 9 32l49 73l49 77c13 20 21 44 21 70v92s-14 34 -16 43c-2 8 1 9 17 9h126c16 0 18 -1 16 -9c-2 -9 -15 -22 -15 -42v-93c0 -26 6 -50 19 -70zM345 7c3 3 7 8 7 14c0 5 -2 10 -4 14
+l-101 150c-16 26 -23 56 -23 87v112h-64v-112c0 -32 -9 -62 -25 -87l-99 -150c-2 -4 -4 -9 -4 -14c0 -6 3 -11 6 -14c4 -4 12 -7 25 -7h258c13 0 20 3 24 7zM325 37c1 -2 3 -6 3 -8c0 -7 -6 -15 -14 -15h-244c-7 0 -14 6 -14 14c0 3 1 6 3 8l81 124h103l82 -124v1zM238 106
+c2 -1 4 -2 6 -2s3 0 5 2c1 2 3 4 3 6s-1 4 -3 6c-1 2 -3 2 -5 2s-4 0 -6 -2c-1 -2 -2 -4 -2 -6s0 -4 2 -6zM285 47c4 2 4 7 2 11l-23 36c-1 2 -4 4 -7 4c-2 0 -3 0 -4 -1c-4 -2 -4 -7 -2 -11l23 -36c1 -2 5 -4 7 -4c1 0 3 0 4 1z" />
<glyph glyph-name="ion-eye-disabled" unicode="&#xf306;"
d="M344 290c41 -27 76 -66 104 -100c-51 -54 -124 -135 -224 -135c-36 0 -65 8 -92 22l-77 -77l-23 23l71 71c-36 25 -68 61 -103 98c78 85 142 137 224 137c34 0 64 -9 92 -23l77 78l23 -23zM134 192c0 -19 6 -36 16 -51l27 27c-4 7 -5 15 -5 24c0 29 23 53 52 53h8
c-5 -6 -8 -13 -8 -21c0 -3 0 -5 1 -8l51 50c-15 11 -33 17 -52 17c-49 0 -90 -41 -90 -91zM224 101c49 0 90 41 90 91c0 19 -6 37 -16 52l-50 -51c3 -1 5 -1 8 -1c8 0 14 3 20 7v-7c0 -29 -23 -53 -52 -53c-9 0 -17 2 -24 6l-28 -27c15 -11 33 -17 52 -17z" />
@@ -475,9 +606,6 @@ c0 -65 36 -121 90 -150c6 -3 13 -7 19 -9c2 -1 3 -1 5 -2c9 -3 19 -5 29 -7c9 -2 18
l53 -52l-36 -41zM178 58l38 113h-85l139 155l-38 -113h85z" />
<glyph glyph-name="ion-flash" unicode="&#xf137;" horiz-adv-x="320"
d="M0 160l224 256l-51 -192h147l-224 -256l51 192h-147z" />
- <glyph glyph-name="ion-flask" unicode="&#xf138;" horiz-adv-x="384"
-d="M382 21c2 -4 3 -10 0 -14s-8 -7 -13 -7h-177h-178c-5 0 -9 3 -12 7s-2 10 0 14l118 199v150c0 8 6 14 14 14s15 -6 15 -14v-80c4 3 10 5 16 5c15 0 27 -12 27 -27s-12 -26 -27 -26c-6 0 -12 2 -16 5v-31c0 -2 -1 -4 -2 -6l-35 -59h72c-15 6 -26 20 -26 37
-c0 23 19 42 43 42c15 0 27 -8 35 -19c-1 2 -1 3 -1 5v154c0 8 6 14 14 14s15 -6 15 -14v-150zM218 151h53l-31 54c2 -5 3 -11 3 -17c0 -17 -10 -31 -25 -37zM201 319c-12 0 -22 9 -22 21s10 21 22 21s22 -9 22 -21s-10 -21 -22 -21z" />
<glyph glyph-name="ion-folder" unicode="&#xf139;" horiz-adv-x="384"
d="M366 256c18 0 19 -7 18 -18l-12 -186c-1 -11 -3 -20 -21 -20h-317c-18 0 -20 9 -21 20l-13 184c-1 11 0 20 18 20h348zM362 305l2 -33h-344c0 6 4 46 6 63c2 18 8 17 25 17h75c28 0 23 0 37 -15c16 -18 19 -17 41 -17h143c11 0 15 -3 15 -15z" />
<glyph glyph-name="ion-fork-repo" unicode="&#xf2c0;" horiz-adv-x="320"
@@ -490,16 +618,8 @@ l9 117h8l10 -117v-1c1 -6 3 -10 9 -10s9 5 9 11v117h8v0c9 -40 24 -91 24 -134z" />
<glyph glyph-name="ion-forward" unicode="&#xf13a;" horiz-adv-x="384"
d="M224 150c-102 0 -171 -9 -224 -102c0 0 37 208 224 208v80l160 -144l-160 -134v92z" />
<glyph glyph-name="ion-funnel" unicode="&#xf31b;"
-d="M224 416c124 0 224 -36 224 -80c0 -8 -3 -15 -9 -22v0c-35 -43 -151 -179 -151 -218v-4v-83v0c0 -23 -29 -41 -64 -41s-64 18 -64 41v0v87c0 39 -117 177 -149 216v0c-7 8 -11 16 -11 24c0 44 100 80 224 80zM224 288c106 0 192 25 192 56s-86 56 -192 56
-s-192 -25 -192 -56s86 -56 192 -56z" />
- <glyph glyph-name="ion-game-controller-a" unicode="&#xf13b;"
-d="M0 193c0 65 50 111 111 111h226c61 0 111 -46 111 -111s-50 -113 -111 -113h-226c-61 0 -111 48 -111 113zM373 215c-11 0 -20 -9 -20 -19s9 -19 20 -19s19 9 19 19s-8 19 -19 19zM330 256c-11 0 -19 -9 -19 -19s8 -19 19 -19s20 9 20 19s-9 19 -20 19zM330 173
-c-11 0 -19 -8 -19 -19c0 -10 8 -19 19 -19s20 9 20 19c0 11 -9 19 -20 19zM288 215c-11 0 -20 -9 -20 -19s9 -19 20 -19s19 9 19 19s-8 19 -19 19zM56 203v-22c0 -3 2 -5 5 -5v0h35v-38v-2c0 -3 2 -4 5 -4h22c3 0 5 2 5 5v0v39h37h1c3 0 5 2 5 5v22c0 3 -2 5 -5 5h-1h-37v38
-v1c0 3 -2 5 -5 5h-22c-3 0 -5 -2 -5 -5v-1v-38h-35h-1c-2 0 -4 -2 -4 -5z" />
- <glyph glyph-name="ion-game-controller-b" unicode="&#xf13c;"
-d="M346 348c45 -13 67 -61 88 -149s18 -152 -7 -164s-53 15 -80 49c-24 27 -33 28 -123 28s-100 -2 -122 -28c-27 -34 -56 -61 -81 -49s-28 76 -7 164s43 136 88 149s59 -12 122 -12s77 25 122 12zM96 184c22 0 40 18 40 40s-18 40 -40 40s-39 -18 -39 -40s17 -40 39 -40z
-M278 204c11 0 19 9 19 20s-8 19 -19 19s-20 -8 -20 -19s9 -20 20 -20zM320 162c11 0 19 8 19 19s-8 20 -19 20s-19 -9 -19 -20s8 -19 19 -19zM320 247c11 0 19 8 19 19s-8 20 -19 20s-19 -9 -19 -20s8 -19 19 -19zM362 204c11 0 20 9 20 20s-9 19 -20 19s-19 -8 -19 -19
-s8 -20 19 -20z" />
+d="M224 416c124 0 224 -36 224 -80c0 -8 -3 -15 -9 -22v0c-35 -43 -151 -179 -151 -218v-4v-83v0c0 -23 -29 -41 -64 -41s-64 18 -64 41v0v87c0 39 -117 177 -149 216v0c-7 8 -11 16 -11 24c0 44 100 80 224 80zM224 288c92 0 176 22 176 48s-83 48 -176 48
+s-176 -22 -176 -48s84 -48 176 -48z" />
<glyph glyph-name="ion-gear-a" unicode="&#xf13d;" horiz-adv-x="384"
d="M347 192c0 -24 15 -43 37 -56c-4 -13 -10 -26 -16 -38c-25 6 -45 -3 -62 -20s-22 -37 -16 -62c-12 -6 -25 -12 -38 -16c-13 22 -36 37 -60 37s-47 -15 -60 -37c-13 4 -27 10 -39 16c6 25 2 45 -15 62s-37 21 -62 15c-6 12 -12 26 -16 39c22 13 37 36 37 60s-15 43 -37 56
c4 13 9 26 16 38c25 -6 45 3 62 20s21 37 15 62c12 6 26 12 39 16c13 -22 36 -37 60 -37s47 15 60 37c13 -4 27 -10 39 -16c-6 -25 -2 -45 15 -62s37 -26 62 -20c6 -12 12 -25 16 -38c-22 -13 -37 -32 -37 -56zM192 94c54 0 98 44 98 98s-44 98 -98 98s-98 -44 -98 -98
@@ -514,11 +634,15 @@ c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50zM192 39
<glyph glyph-name="ion-hammer" unicode="&#xf27b;" horiz-adv-x="320"
d="M314 416c3 0 6 -3 6 -6v-84c0 -3 -3 -6 -6 -6h-52c-3 0 -6 3 -6 6v14c-6 5 -16 9 -22 7c-7 -2 -23 -13 -30 -25s-6 -28 -6 -66l8 -2c5 -1 7 -6 7 -9v-70c0 -95 11 -201 11 -201c0 -3 -3 -6 -6 -6h-84c-3 0 -6 3 -6 6c0 0 11 106 11 201v70c0 3 3 8 7 9l7 2
c0 43 -5 58 -22 74c-18 16 -41 19 -63 17s-51 -35 -58 -45s-10 2 -10 11c1 16 22 60 72 81s91 22 102 22s27 -1 38 -3s16 -18 26 -18c7 0 14 5 18 9v6c0 3 3 6 6 6h52z" />
- <glyph glyph-name="ion-happy" unicode="&#xf31c;"
+ <glyph glyph-name="ion-happy-outline" unicode="&#xf3c6;"
d="M355 158c8 -4 11 -13 7 -21c-24 -46 -78 -73 -138 -73c-62 0 -118 29 -139 74c-4 8 0 17 8 21c2 1 5 1 7 1c6 0 11 -3 14 -9c16 -34 60 -55 110 -55c49 0 92 21 110 56c3 5 8 8 14 8c3 0 5 -1 7 -2zM381 217c5 -7 4 -17 -4 -22c-3 -2 -6 -3 -10 -3c-5 0 -11 2 -14 6
s-7 10 -17 10s-14 -6 -17 -10s-9 -6 -14 -6c-4 0 -7 1 -10 3c-8 6 -9 15 -3 22c11 14 23 23 44 23s35 -9 45 -23zM157 217c5 -7 4 -17 -4 -22c-3 -2 -6 -3 -10 -3c-5 0 -11 2 -14 6s-7 10 -17 10s-14 -6 -17 -10s-9 -6 -14 -6c-4 0 -7 1 -10 3c-8 6 -9 15 -3 22
c11 14 23 23 44 23s35 -9 45 -23zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56
s100 20 136 56z" />
+ <glyph glyph-name="ion-happy" unicode="&#xf31c;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM71 195c3 -2 6 -3 10 -3c5 0 11 2 14 6s7 10 17 10s14 -6 17 -10s9 -6 14 -6c4 0 7 1 10 3c8 5 9 15 4 22c-10 14 -24 23 -45 23s-33 -9 -44 -23c-6 -7 -5 -16 3 -22zM362 137
+c4 8 1 17 -7 21c-2 1 -4 2 -7 2c-6 0 -11 -3 -14 -8c-18 -35 -61 -56 -110 -56c-50 0 -94 21 -110 55c-3 6 -8 9 -14 9c-2 0 -5 0 -7 -1c-8 -4 -12 -13 -8 -21c21 -45 77 -74 139 -74c60 0 114 27 138 73zM377 195c8 5 9 15 4 22c-10 14 -24 23 -45 23s-33 -9 -44 -23
+c-6 -7 -5 -16 3 -22c3 -2 6 -3 10 -3c5 0 11 2 14 6s7 10 17 10s14 -6 17 -10s9 -6 14 -6c4 0 7 1 10 3z" />
<glyph glyph-name="ion-headphone" unicode="&#xf140;" horiz-adv-x="384"
d="M383 210c3 -51 -3 -130 -13 -162c-20 -67 -40 -80 -72 -80s-58 27 -58 59v106c0 33 23 59 53 59c18 0 34 -9 44 -24c0 0 11 7 13 22s4 34 -5 64s-21 19 -36 38c-2 3 -5 7 -8 10l-10 10c-2 2 -3 3 -5 4c-11 9 -21 17 -34 23c-19 9 -39 13 -60 13s-42 -4 -61 -13
c-13 -6 -22 -14 -33 -23c-2 -1 -3 -2 -5 -4l-10 -10s-6 -7 -8 -10c-15 -19 -27 -8 -36 -38c-9 -31 -7 -49 -5 -64s13 -22 13 -22c10 15 26 24 44 24c30 0 53 -27 53 -59v-106c0 -32 -26 -59 -58 -59s-52 13 -72 80c-10 32 -16 111 -13 162c3 60 22 108 56 145v0
@@ -545,14 +669,6 @@ d="M384 160h-48v-160h-96v128h-96v-128h-96v160h-48l192 224z" />
<glyph glyph-name="ion-icecream" unicode="&#xf27d;" horiz-adv-x="320"
d="M32 192h256l-128 -224zM307 275c8 -5 13 -13 13 -23c0 -16 -14 -28 -30 -28h-4h-252h-4c-16 0 -30 13 -30 28c0 10 6 18 14 23c1 0 1 2 2 2c4 3 7 7 8 12v1c-2 6 -2 12 -2 18c0 42 34 76 76 76c8 0 16 -2 23 -4c-3 -12 -4 -31 -4 -31c2 15 11 29 11 29c18 23 46 38 77 38
c53 0 96 -43 96 -96c0 -11 -2 -21 -5 -30v-1c0 -4 4 -9 8 -12c1 0 2 -2 3 -2z" />
- <glyph glyph-name="ion-icon-social-google-plus-outline" unicode="&#xf145;"
-d="M192 366c12 -10 36 -30 36 -68c0 -37 -21 -55 -43 -72c-7 -7 -15 -13 -15 -24s8 -18 14 -22l18 -14c23 -19 43 -36 43 -71c0 -47 -47 -95 -135 -95c-74 0 -110 35 -110 72c0 18 10 44 40 62c32 19 75 21 98 23c-7 9 -16 18 -16 34c0 9 3 14 5 20c-6 0 -11 -1 -16 -1
-c-54 0 -85 40 -85 79c0 23 10 48 32 67c29 24 64 28 92 28h106l-33 -18h-31zM155 142c-4 0 -7 1 -12 1s-32 -1 -54 -8c-11 -4 -44 -16 -44 -52s36 -62 91 -62c49 0 75 24 75 55c0 26 -17 39 -56 66zM170 238c12 12 13 28 13 37c0 36 -22 92 -65 92c-13 0 -28 -6 -36 -16
-c-9 -11 -11 -24 -11 -37c0 -34 20 -90 64 -90c13 0 27 6 35 14zM448 306v-18h-78v-81h-18v81h-80v18h80v78h18v-78h78z" />
- <glyph glyph-name="ion-icon-social-google-plus" unicode="&#xf146;"
-d="M210 172c22 -18 45 -36 45 -73c0 -49 -47 -99 -139 -99c-80 0 -116 39 -116 77c0 10 3 42 42 65c27 16 61 21 85 23c-4 7 -8 15 -8 26c0 4 0 7 1 10h-4c-19 0 -46 4 -67 26c-15 15 -24 36 -24 57c0 26 13 53 35 71v0c32 25 69 29 94 29h134l-60 -33h-13
-c11 -13 23 -31 23 -58c0 -40 -25 -59 -45 -74v-1c-6 -6 -11 -10 -11 -17c0 -6 4 -10 10 -15v0zM85 308c0 -13 4 -33 14 -51c7 -12 21 -27 41 -27c10 0 21 4 28 11c10 10 10 25 10 30c0 18 -6 37 -15 53c-8 13 -20 28 -40 28c-11 0 -23 -5 -29 -13c-6 -7 -9 -18 -9 -31z
-M206 80c0 20 -13 31 -50 56c-3 0 -4 1 -8 1c-6 0 -31 -2 -50 -8c-16 -6 -38 -16 -38 -42c0 -31 32 -51 80 -51c41 0 66 17 66 44zM370 306h78v-34h-78v-81h-34v81h-80v34h80v78h34v-78z" />
<glyph glyph-name="ion-image" unicode="&#xf147;"
d="M336 224c-26 0 -48 22 -48 48s22 48 48 48s48 -22 48 -48s-22 -48 -48 -48zM420 384c16 0 28 -12 28 -28v-328c0 -16 -12 -28 -28 -28h-392c-16 0 -28 12 -28 28v328c0 16 12 28 28 28h392zM317 186l99 -106v260c0 7 -6 12 -13 12h-358c-7 0 -12 -5 -13 -12v-260l126 152
c4 4 10 8 17 8s13 -2 17 -7l54 -59l4 -4c3 -2 7 -4 11 -4s8 2 12 5l18 16c4 3 8 5 13 5s10 -2 13 -6z" />
@@ -565,463 +681,554 @@ d="M448 195c2 -124 -97 -225 -221 -227s-225 97 -227 221s97 225 221 227s225 -97 22
<glyph glyph-name="ion-information" unicode="&#xf14a;" horiz-adv-x="128"
d="M96 0h32v-16h-128v16h32v240h-32v16h96v-256zM64 304c-27 0 -48 21 -48 48s21 48 48 48s48 -21 48 -48s-21 -48 -48 -48z" />
<glyph glyph-name="ion-ionic" unicode="&#xf14b;" horiz-adv-x="416"
-d="M378 313c24 -34 38 -76 38 -121c0 -115 -93 -208 -208 -208s-208 93 -208 208s93 208 208 208c45 0 87 -14 121 -38c6 5 13 7 21 7c19 0 35 -16 35 -35c0 -8 -2 -15 -7 -21zM344 56c18 18 31 38 41 61c10 24 15 49 15 75s-5 51 -15 75c-5 13 -12 25 -20 36
-c-5 -2 -10 -3 -15 -3c-19 0 -35 15 -35 34c0 5 2 11 4 15c-11 8 -23 15 -36 20c-24 10 -49 15 -75 15s-51 -5 -75 -15c-23 -10 -43 -23 -61 -41s-31 -38 -41 -61c-10 -24 -15 -49 -15 -75s5 -51 15 -75c10 -23 23 -43 41 -61s38 -31 61 -41c24 -10 49 -15 75 -15s51 5 75 15
+d="M376 315c25 -34 40 -77 40 -123c0 -115 -93 -208 -208 -208s-208 93 -208 208s93 208 208 208c46 0 89 -15 123 -40c5 3 11 5 18 5c18 0 32 -14 32 -32c0 -7 -2 -13 -5 -18zM344 56c18 18 31 38 41 61c10 24 15 49 15 75s-5 51 -15 75c-6 13 -13 26 -21 38
+c-4 -2 -10 -4 -15 -4c-18 0 -32 14 -32 32c0 5 2 11 4 15c-12 8 -25 15 -38 21c-24 10 -49 15 -75 15s-51 -5 -75 -15c-23 -10 -43 -23 -61 -41s-31 -38 -41 -61c-10 -24 -15 -49 -15 -75s5 -51 15 -75c10 -23 23 -43 41 -61s38 -31 61 -41c24 -10 49 -15 75 -15s51 5 75 15
c23 10 43 23 61 41zM112 192c0 64 32 96 96 96s96 -32 96 -96s-32 -96 -96 -96s-96 32 -96 96z" />
- <glyph glyph-name="ion-ios7-alarm-outline" unicode="&#xf14c;" horiz-adv-x="404"
+ <glyph glyph-name="ion-ios-alarm-outline" unicode="&#xf3c7;" horiz-adv-x="404"
d="M384 256l-54 52l-9 -9c35 -32 57 -79 57 -130c0 -44 -16 -83 -43 -114l36 -45l-12 -10l-35 43c-32 -30 -75 -49 -122 -49v0v0c-47 0 -90 19 -122 49l-35 -43l-12 10l36 45c-27 31 -43 71 -43 115c0 51 22 97 57 129l-9 9l-54 -52c-12 14 -20 32 -20 52c0 44 35 80 80 82
h5c20 0 39 -7 54 -18l-54 -52l11 -11c26 19 56 32 90 35v0c0 8 8 16 16 16s15 -8 15 -16v0c34 -3 65 -16 91 -35l11 11l-54 52c15 11 34 18 54 18h5c45 -2 80 -38 80 -82c0 -20 -8 -38 -20 -52zM22 280l91 89c-9 5 -19 7 -32 6c-37 -2 -65 -32 -65 -67c0 -10 2 -19 6 -28z
M362 172c0 88 -72 158 -160 158s-160 -70 -160 -158s72 -158 160 -158s160 70 160 158zM291 369l91 -89c4 9 6 18 6 28c0 35 -28 65 -65 67c-13 1 -23 -1 -32 -6zM202 288h16v-144h-112v16h96v128z" />
- <glyph glyph-name="ion-ios7-alarm" unicode="&#xf14d;" horiz-adv-x="404"
+ <glyph glyph-name="ion-ios-alarm" unicode="&#xf3c8;" horiz-adv-x="404"
d="M385 256l-55 52l-9 -9c35 -32 57 -79 57 -130c0 -44 -16 -83 -43 -114l37 -45l-13 -10l-35 43c-32 -30 -75 -49 -122 -49v0v0c-47 0 -90 19 -122 49l-35 -43l-12 10l36 45c-27 31 -43 70 -43 114c0 51 22 98 57 130l-9 9l-54 -52c-12 14 -20 32 -20 52c0 44 35 80 80 82
h5c20 0 39 -7 54 -18l-54 -53l11 -10c26 19 56 32 90 35v0c0 8 8 16 16 16s15 -8 15 -16v0c34 -3 65 -16 91 -35l11 11l-54 52c15 11 34 18 54 18h5c45 -2 80 -38 80 -82c0 -20 -7 -38 -19 -52zM218 144v144h-16v-128h-96v-16h112z" />
- <glyph glyph-name="ion-ios7-albums-outline" unicode="&#xf14e;"
+ <glyph glyph-name="ion-ios-albums-outline" unicode="&#xf3c9;"
d="M432 304h-416v-288h416v288zM448 320v0v-320h-448v320h448zM40 336v16h368v-16h-368zM72 368v16h304v-16h-304z" />
- <glyph glyph-name="ion-ios7-albums" unicode="&#xf14f;"
+ <glyph glyph-name="ion-ios-albums" unicode="&#xf3ca;"
d="M448 320v0v-320h-448v320h448zM40 336v16h368v-16h-368zM72 368v16h304v-16h-304z" />
- <glyph glyph-name="ion-ios7-americanfootball-outline" unicode="&#xf31e;"
-d="M356 324c120 -120 88 -352 88 -352s-28 -4 -70 -4c-78 0 -204 14 -282 92c-120 120 -88 352 -88 352s28 4 70 4c78 0 204 -14 282 -92zM364 64l66 -67c2 23 3 61 -1 105l-3 24zM345 313c-33 33 -78 56 -134 71c-11 3 -22 5 -33 7l-71 -71l69 -69l37 37l11 -11l-37 -37
-l21 -21l37 37l11 -11l-37 -37l21 -21l37 37l11 -11l-37 -37l21 -21l37 37l11 -11l-37 -37l70 -69l70 71c-4 24 -10 46 -18 67c-15 40 -34 74 -60 100zM19 282l3 -24l62 62l-66 67c-2 -23 -3 -61 1 -105zM29 398l66 -66l63 62c-27 4 -55 6 -84 6c-18 0 -33 -1 -45 -2zM103 71
-c33 -33 78 -56 134 -71c11 -3 22 -5 33 -7l71 71l-69 69l-37 -37l-11 11l37 37l-21 21l-37 -37l-11 11l37 37l-21 21l-37 -37l-11 11l37 37l-21 21l-37 -37l-11 11l37 37l-69 69l-71 -71c4 -24 10 -46 18 -67c15 -40 34 -74 60 -100zM374 -16c18 0 33 1 45 2l-67 66l-62 -62
-c27 -4 55 -6 84 -6z" />
- <glyph glyph-name="ion-ios7-americanfootball" unicode="&#xf31f;"
-d="M3 402l81 -82l-76 -76c-12 70 -7 134 -5 158zM272 133l69 -69l-84 -85c-59 12 -120 36 -165 81s-69 106 -81 165l85 84l69 -69l-37 -37l11 -11l37 37l21 -21l-37 -37l11 -11l37 37l21 -21l-37 -37l11 -11l37 37l21 -21l-37 -37l11 -11zM176 251l-69 69l84 85
-c59 -12 120 -36 165 -81s69 -106 81 -165l-84 -84l-70 69l37 37l-11 11l-37 -37l-21 21l37 37l-11 11l-37 -37l-21 21l37 37l-11 11l-37 -37l-21 21l37 37l-11 11zM276 -24l77 76l81 -81c-12 -1 -33 -3 -60 -3c-28 0 -62 2 -98 8zM172 408l-76 -76l-82 81c12 1 33 3 60 3
-c28 0 62 -2 98 -8zM445 -18l-81 82l76 76c12 -70 7 -134 5 -158z" />
- <glyph glyph-name="ion-ios7-analytics-outline" unicode="&#xf320;"
+ <glyph glyph-name="ion-ios-americanfootball-outline" unicode="&#xf3cb;" horiz-adv-x="416"
+d="M331 315c112 -112 81 -327 81 -327s-26 -4 -65 -4c-73 0 -189 12 -262 85c-112 112 -81 327 -81 327s26 4 65 4c73 0 189 -12 262 -85zM17 383c-2 -19 -5 -60 0 -107c1 -8 2 -16 3 -23l127 127c-25 3 -51 5 -78 5v0v0c-22 0 -41 -1 -52 -2zM96 80c30 -30 72 -53 124 -66
+c10 -3 20 -5 31 -7l142 142c-4 22 -10 44 -17 63c-14 37 -32 68 -56 92c-30 30 -72 53 -124 66c-10 3 -20 5 -31 7l-142 -142c4 -22 10 -44 17 -63c14 -37 32 -68 56 -92zM399 1c2 19 5 60 0 107c-1 8 -2 16 -3 23l-127 -127c25 -3 51 -5 78 -5c22 0 41 1 52 2zM259 130
+l-28 -29l-12 12l29 28l-23 23l-28 -29l-12 12l29 28l-23 23l-28 -29l-12 12l29 28l-23 23l-28 -29l-12 12l29 28l-22 23l-29 -29l-11 12l67 67l12 -11l-29 -29l23 -22l28 29l12 -12l-29 -28l23 -23l28 29l12 -12l-29 -28l23 -23l28 29l12 -12l-29 -28l22 -23l29 29l12 -12
+l-29 -28l22 -23l29 29l11 -12l-67 -67l-12 11l29 29z" />
+ <glyph glyph-name="ion-ios-americanfootball" unicode="&#xf3cc;" horiz-adv-x="416"
+d="M331 315c112 -112 81 -327 81 -327s-26 -4 -65 -4c-73 0 -189 12 -262 85c-112 112 -81 327 -81 327s26 4 65 4c73 0 189 -12 262 -85zM20 253l3 -18l142 142l-18 3zM219 113l12 -12l28 29l23 -22l-29 -29l12 -11l67 67l-11 12l-29 -29l-22 23l29 28l-12 12l-28 -29
+l-23 23l29 28l-12 12l-28 -29l-23 23l29 28l-12 12l-28 -29l-23 23l29 28l-12 12l-28 -29l-23 22l29 29l-12 11l-67 -67l11 -12l29 29l22 -23l-29 -28l12 -12l28 29l23 -23l-29 -28l12 -12l28 29l23 -23l-29 -28l12 -12l28 29l23 -23zM269 4l127 127l-3 18l-142 -142z" />
+ <glyph glyph-name="ion-ios-analytics-outline" unicode="&#xf3cd;"
d="M224 400c-28 0 -55 -5 -81 -16c-25 -10 -47 -26 -66 -45s-35 -41 -45 -66c-11 -26 -16 -53 -16 -81s5 -55 16 -81c10 -25 26 -47 45 -66s41 -35 66 -45c26 -11 53 -16 81 -16s55 5 81 16c25 10 47 26 66 45s35 41 45 66c11 26 16 53 16 81s-5 55 -16 81
c-10 25 -26 47 -45 66s-41 35 -66 45c-26 11 -53 16 -81 16zM224 416v0c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM76 128c-25 0 -41 18 -42 19c-3 3 -2 9 1 12s8 2 11 -1c1 -1 15 -17 36 -14c12 2 27 26 38 42c4 6 9 12 12 16
c17 21 34 23 45 21c24 -3 45 -28 54 -50c7 -18 18 -28 32 -29c15 -1 31 11 43 30c1 2 3 4 4 7c9 17 24 43 52 43c31 0 52 -35 53 -36c2 -4 1 -9 -3 -11s-9 -1 -11 3c0 0 -5 8 -12 15c-6 6 -16 13 -27 13c-18 0 -29 -19 -38 -35c-1 -3 -3 -5 -4 -7c-15 -25 -36 -40 -58 -38
c-20 1 -36 15 -46 39s-28 39 -41 41c-11 1 -21 -4 -31 -16c-3 -4 -6 -9 -10 -15c-14 -20 -31 -45 -50 -48c-3 0 -5 -1 -8 -1z" />
- <glyph glyph-name="ion-ios7-analytics" unicode="&#xf321;"
+ <glyph glyph-name="ion-ios-analytics" unicode="&#xf3ce;"
d="M224 416c124 0 224 -100 224 -224c0 -13 -1 -25 -3 -37c-1 -6 -2 -12 -3 -17c-24 -98 -113 -170 -218 -170c-122 0 -221 98 -224 219v5c0 9 1 17 2 26c13 111 107 198 222 198zM431 168c1 8 1 16 1 24c0 28 -5 55 -16 81c-10 25 -26 47 -45 66s-41 35 -66 45
c-26 11 -53 16 -81 16s-55 -5 -81 -16c-25 -10 -47 -26 -66 -45s-35 -41 -45 -66c-11 -26 -16 -53 -16 -81v0c14 -21 29 -34 29 -34h1v-1c1 -1 15 -16 36 -13c12 2 27 26 38 42c4 6 9 12 12 16c17 21 34 23 45 21c24 -3 45 -27 54 -50c7 -18 18 -28 32 -29c15 -1 31 9 43 29
c1 2 3 4 4 7c9 17 24 44 52 44c31 0 52 -35 53 -36c3 -4 9 -12 16 -20z" />
- <glyph glyph-name="ion-ios7-arrow-back" unicode="&#xf150;" horiz-adv-x="192"
+ <glyph glyph-name="ion-ios-arrow-back" unicode="&#xf3cf;" horiz-adv-x="192"
d="M192 320l-127 -128l127 -128l-32 -32l-160 160v0v0l160 160z" />
- <glyph glyph-name="ion-ios7-arrow-down" unicode="&#xf151;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-arrow-down" unicode="&#xf3d0;" horiz-adv-x="320"
d="M301 288l19 -21l-160 -171l-160 171l19 21l141 -150z" />
- <glyph glyph-name="ion-ios7-arrow-forward" unicode="&#xf152;" horiz-adv-x="192"
+ <glyph glyph-name="ion-ios-arrow-forward" unicode="&#xf3d1;" horiz-adv-x="192"
d="M0 320l32 32l160 -160v0v0l-160 -160l-32 32l127 128z" />
- <glyph glyph-name="ion-ios7-arrow-left" unicode="&#xf153;" horiz-adv-x="192"
+ <glyph glyph-name="ion-ios-arrow-left" unicode="&#xf3d2;" horiz-adv-x="192"
d="M192 333l-150 -141l150 -141l-21 -19l-171 160l171 160z" />
- <glyph glyph-name="ion-ios7-arrow-right" unicode="&#xf154;" horiz-adv-x="192"
+ <glyph glyph-name="ion-ios-arrow-right" unicode="&#xf3d3;" horiz-adv-x="192"
d="M0 333l21 19l171 -160l-171 -160l-21 19l150 141z" />
- <glyph glyph-name="ion-ios7-arrow-thin-down" unicode="&#xf27e;" horiz-adv-x="192"
+ <glyph glyph-name="ion-ios-arrow-thin-down" unicode="&#xf3d4;" horiz-adv-x="192"
d="M190 126c2 -2 2 -4 2 -6s0 -4 -2 -6c0 0 -87 -79 -88 -80s-3 -2 -6 -2s-5 1 -6 2s-88 80 -88 80c-3 3 -3 9 0 12s9 3 12 0l74 -67v285c0 4 4 8 8 8s8 -4 8 -8v-285l74 67c3 3 9 3 12 0z" />
- <glyph glyph-name="ion-ios7-arrow-thin-left" unicode="&#xf27f;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-arrow-thin-left" unicode="&#xf3d5;" horiz-adv-x="320"
d="M94 98c-2 -2 -4 -2 -6 -2s-4 0 -6 2c0 0 -79 87 -80 88s-2 3 -2 6s1 5 2 6s80 88 80 88c3 3 9 3 12 0s3 -9 0 -12l-67 -74h285c4 0 8 -4 8 -8s-4 -8 -8 -8h-285l67 -74c3 -3 3 -9 0 -12z" />
- <glyph glyph-name="ion-ios7-arrow-thin-right" unicode="&#xf280;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-arrow-thin-right" unicode="&#xf3d6;" horiz-adv-x="320"
d="M226 98c-3 3 -3 9 0 12l67 74h-285c-4 0 -8 4 -8 8s4 8 8 8h285l-67 74c-3 3 -3 9 0 12s9 3 12 0c0 0 79 -87 80 -88s2 -3 2 -6s-1 -5 -2 -6s-80 -88 -80 -88c-2 -2 -4 -2 -6 -2s-4 0 -6 2z" />
- <glyph glyph-name="ion-ios7-arrow-thin-up" unicode="&#xf281;" horiz-adv-x="192"
+ <glyph glyph-name="ion-ios-arrow-thin-up" unicode="&#xf3d7;" horiz-adv-x="192"
d="M190 258c-3 -3 -9 -3 -12 0l-74 67v-285c0 -4 -4 -8 -8 -8s-8 4 -8 8v285l-74 -67c-3 -3 -9 -3 -12 0s-3 9 0 12c0 0 87 79 88 80s3 2 6 2s5 -1 6 -2s88 -80 88 -80c2 -2 2 -4 2 -6s0 -4 -2 -6z" />
- <glyph glyph-name="ion-ios7-arrow-up" unicode="&#xf155;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-arrow-up" unicode="&#xf3d8;" horiz-adv-x="320"
d="M301 96l-141 150l-141 -150l-19 21l160 171l160 -171z" />
- <glyph glyph-name="ion-ios7-at-outline" unicode="&#xf156;" horiz-adv-x="255"
+ <glyph glyph-name="ion-ios-at-outline" unicode="&#xf3d9;" horiz-adv-x="255"
d="M236 127v1h19l-3 -6c-3 -6 -13 -19 -22 -27s-18 -14 -28 -20s-21 -10 -32 -13s-23 -5 -34 -5c-16 0 -33 3 -49 8s-30 13 -43 24c-12 11 -26 29 -34 46c-7 16 -10 33 -10 58c0 18 4 38 11 55c7 16 17 30 29 42s27 21 43 28c15 6 33 9 53 9c16 0 32 -3 46 -8
c15 -5 28 -12 39 -22s17 -21 24 -35c6 -13 8 -26 8 -44c0 -14 -2 -28 -7 -40s-9 -20 -17 -30c-8 -9 -13 -15 -23 -21c-11 -6 -20 -9 -29 -9c-8 0 -15 2 -20 7c-3 2 -5 6 -6 9c-6 -6 -11 -10 -17 -12c-10 -3 -18 -4 -26 -4s-15 1 -21 4s-12 7 -17 12s-8 11 -11 18
s-5 14 -5 22c0 12 3 24 7 36v2c4 11 5 16 13 26c8 11 17 19 28 26s24 11 38 11c12 0 21 -3 31 -9c7 -4 12 -10 16 -16l6 17h18l-38 -102c-2 -5 -4 -10 -5 -14s-1 -7 -1 -10c0 -2 1 -4 3 -5s4 -2 8 -2c6 0 11 2 20 7c8 4 12 9 19 17c6 8 10 14 14 25s6 23 6 35
c0 15 -2 25 -7 36c-6 13 -10 22 -19 30s-20 15 -33 20s-27 7 -42 7c-19 0 -35 -3 -48 -9c-15 -6 -27 -14 -37 -24c-11 -10 -19 -23 -25 -37c-6 -15 -10 -32 -10 -48c0 -22 2 -36 8 -49c6 -15 17 -31 28 -41s24 -18 38 -23s30 -7 46 -7c10 0 20 1 30 4s18 6 27 11
s17 11 24 18s14 13 19 21zM147 154c4 5 8 12 11 20l21 57c-2 5 -4 10 -7 13c-3 4 -6 6 -10 8c-1 0 -1 1 -2 1c-3 2 -5 3 -9 4c-5 1 -9 2 -13 2c-10 0 -19 -3 -28 -9s-17 -13 -23 -22c-5 -8 -7 -11 -10 -20c0 -1 -1 -3 -1 -4c-4 -11 -5 -20 -5 -30c0 -6 1 -11 3 -16
s5 -9 8 -13s7 -6 12 -8s9 -3 15 -3c4 0 9 1 14 2c4 1 8 2 12 5s8 7 12 13z" />
- <glyph glyph-name="ion-ios7-at" unicode="&#xf157;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-at" unicode="&#xf3da;" horiz-adv-x="256"
d="M228 128v0h28c-1 -1 -2 -4 -3 -6c-4 -6 -14 -19 -23 -27s-18 -14 -28 -20s-20 -10 -32 -13c-11 -3 -23 -5 -34 -5c-16 0 -33 3 -49 8s-30 13 -43 24c-12 10 -26 28 -34 46c-7 16 -10 33 -10 58c0 19 4 39 11 55s17 30 29 42s28 21 44 28c15 6 32 9 52 9c16 0 31 -3 46 -8
s28 -12 39 -22s18 -22 25 -36c6 -14 8 -26 8 -44c0 -14 -2 -28 -7 -40c-4 -11 -9 -20 -17 -30c-7 -9 -14 -16 -24 -22c-12 -6 -21 -9 -30 -9s-16 2 -22 8c-2 1 -3 3 -4 5c-4 -4 -9 -6 -14 -8c-10 -3 -18 -5 -27 -5c-8 0 -16 2 -23 5s-12 7 -17 12s-9 12 -12 19s-4 14 -4 22
c0 12 2 25 6 37l1 1c4 10 5 17 13 27c8 11 17 20 28 27c12 7 24 10 38 10c12 0 22 -3 33 -9c5 -3 8 -6 12 -10l5 12h25l-39 -104c-2 -5 -3 -9 -4 -13c-1 -3 -1 -7 -1 -9s0 -3 1 -3c0 0 1 -1 5 -1c5 0 11 2 19 7c7 4 10 8 16 16s9 13 13 23s6 20 6 32c0 14 -1 24 -6 34
c-5 12 -10 21 -18 28c-9 8 -19 14 -31 18s-26 7 -40 7c-18 0 -32 -3 -44 -8c-14 -6 -25 -13 -35 -23s-18 -22 -24 -35c-6 -14 -9 -30 -9 -45c0 -21 3 -34 8 -46c6 -14 16 -30 26 -39s22 -16 35 -21c14 -5 28 -7 43 -7c10 0 20 2 29 4s18 6 26 11s28 20 38 33zM144 157
c4 5 7 12 10 19l20 55c-1 4 -3 7 -5 9c-3 3 -6 6 -9 8h-1h-1v1c-3 2 -5 2 -8 3c-4 1 -8 1 -12 1c-9 0 -17 -2 -25 -7c-10 -6 -17 -14 -21 -21c-5 -8 -6 -11 -9 -19c0 -1 -1 -2 -1 -3c-3 -10 -6 -19 -6 -28c0 -5 1 -10 3 -14s4 -8 7 -11s7 -6 11 -8s8 -2 13 -2c4 0 8 0 12 1
v0c4 1 7 2 11 5c3 2 7 5 11 11z" />
- <glyph glyph-name="ion-ios7-barcode-outline" unicode="&#xf322;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-barcode-outline" unicode="&#xf3db;" horiz-adv-x="416"
d="M0 64v256h80v-16h-64v-224h64v-16h-80zM336 320h80v-256h-80v16h64v224h-64v16zM64 128v128h16v-128h-16zM336 128v128h16v-128h-16zM272 96v192h16v-192h-16zM128 96v192h16v-192h-16zM199 112v160h16v-160h-16z" />
- <glyph glyph-name="ion-ios7-barcode" unicode="&#xf323;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-barcode" unicode="&#xf3dc;" horiz-adv-x="416"
d="M0 320h416v-256h-416v256zM80 128v128h-16v-128h16zM144 96v192h-16v-192h16zM215 112v160h-16v-160h16zM288 96v192h-16v-192h16zM352 128v128h-16v-128h16z" />
- <glyph glyph-name="ion-ios7-baseball-outline" unicode="&#xf324;"
-d="M378 355c43 -41 70 -99 70 -163s-27 -122 -70 -163c-4 -4 -8 -8 -12 -11c-39 -31 -88 -50 -142 -50c-55 0 -105 19 -144 52c-4 3 -8 7 -12 11c-42 41 -68 98 -68 161s26 120 68 161c4 4 8 8 12 11c39 33 89 52 144 52c54 0 103 -19 142 -50c4 -3 8 -7 12 -11zM77 45l3 -3
-l3 3c9 9 18 19 25 30l-20 10l7 15l22 -11c4 7 8 14 11 22c2 5 3 9 5 14l-23 5l3 16l25 -5c4 14 5 28 6 43h-24v16h24c-1 14 -3 28 -6 42l-25 -5l-3 16l24 4c-2 5 -4 11 -6 16c-3 7 -7 14 -11 21l-22 -11l-7 14l21 11c-7 11 -16 21 -26 31l-3 3l-3 -3
-c-19 -19 -35 -41 -45 -66c-11 -26 -16 -53 -16 -81s5 -55 16 -81c10 -25 26 -47 45 -66zM305 0c17 7 33 17 48 29c-13 12 -23 25 -33 40l-25 -13l-7 14l24 12c-7 13 -13 27 -18 41l-27 -5l-3 16l25 4c-4 15 -5 30 -6 46h-27v16h27c1 15 3 30 6 44l-25 5l3 16l26 -5
-c5 14 11 28 18 41l-23 12l7 14l24 -13c10 15 21 29 34 41c-15 12 -31 22 -48 29c-26 11 -53 16 -81 16s-55 -5 -81 -16c-19 -8 -36 -18 -51 -31c12 -11 22 -24 31 -38l22 12l7 -14l-21 -11c7 -13 13 -27 18 -42l24 5l3 -16l-22 -4c4 -14 5 -30 6 -45h24v-16h-24
-c-1 -16 -3 -31 -7 -46l23 -4l-3 -16l-24 4c-5 -14 -11 -28 -18 -41l21 -11l-7 -14l-23 12c-9 -13 -19 -26 -30 -37c15 -13 32 -23 51 -31c26 -11 53 -16 81 -16s55 5 81 16zM371 45c19 19 35 41 45 66c11 26 16 53 16 81s-5 55 -16 81c-10 25 -26 47 -45 66l-5 5
-c-2 -2 -4 -3 -6 -5c-10 -10 -18 -21 -26 -32l18 -10l-7 -14l-20 10c-4 -7 -7 -13 -10 -20c-2 -5 -4 -11 -6 -16l21 -4l-3 -16l-22 4c-3 -13 -5 -27 -6 -41h21v-16h-21c1 -14 3 -29 6 -43l22 5l3 -16l-20 -4c2 -5 3 -10 5 -15c3 -7 7 -14 11 -21l19 10l7 -15l-18 -9
-c7 -11 16 -21 26 -31c2 -2 4 -3 6 -5z" />
- <glyph glyph-name="ion-ios7-baseball" unicode="&#xf325;"
-d="M83 45l-3 -3c-4 -4 -8 -8 -12 -11c-42 41 -68 98 -68 161s26 120 68 161c4 -3 8 -7 12 -11l3 -3c10 -10 19 -20 26 -31l-21 -11l7 -14l22 11c4 -7 8 -14 11 -21c2 -5 4 -11 6 -16l-24 -4l3 -16l25 5c3 -14 5 -28 6 -42h-24v-16h24c-1 -15 -2 -29 -6 -43l-25 5l-3 -16
-l23 -4c-2 -5 -3 -10 -5 -15c-3 -8 -7 -15 -11 -22l-22 11l-7 -15l20 -10c-7 -11 -16 -21 -25 -30zM320 69c10 -15 20 -28 33 -40c4 -4 9 -8 13 -11c-39 -31 -88 -50 -142 -50c-55 0 -105 19 -144 52c4 3 8 7 12 11c11 11 21 24 30 37l23 -12l7 14l-21 11c7 13 13 27 18 41
-l24 -4l3 16l-23 4c4 15 6 30 7 46h24v16h-24c-1 15 -2 31 -6 45l22 4l-3 16l-24 -5c-5 15 -11 29 -18 42l21 11l-7 14l-22 -12c-9 14 -19 27 -31 38c-4 4 -8 8 -12 11c39 33 89 52 144 52c54 0 102 -19 141 -50c-4 -3 -8 -7 -12 -11c-13 -12 -24 -26 -34 -41l-24 13l-7 -14
-l23 -12c-7 -13 -13 -27 -18 -41l-26 5l-3 -16l25 -5c-3 -14 -5 -29 -6 -44h-27v-16h27c1 -16 2 -31 6 -46l-25 -4l3 -16l27 5c5 -14 11 -28 18 -41l-24 -12l7 -14zM448 192c0 -64 -27 -122 -70 -163c-4 3 -8 7 -12 11c-2 2 -4 3 -6 5c-10 10 -19 20 -26 31l18 9l-7 15
-l-19 -10c-4 7 -8 14 -11 21c-2 5 -3 10 -5 15l20 4l-3 16l-22 -5c-3 14 -5 29 -6 43h21v16h-21c1 14 3 28 6 41l22 -4l3 16l-21 4c2 5 4 11 6 16c3 7 6 13 10 20l20 -10l7 14l-18 10c8 11 16 22 26 32c2 2 4 3 6 5c4 4 8 8 12 11c43 -41 70 -99 70 -163zM68 353v0v0v0z
-M68 31v0v0zM80 20v0v0v0zM80 364v0v0zM378 29v0v0v0zM378 355v0v0zM366 366v0v0v0zM366 18v0v0z" />
- <glyph glyph-name="ion-ios7-basketball-outline" unicode="&#xf326;"
-d="M378 355c43 -41 70 -99 70 -163s-27 -122 -70 -163c-4 -4 -8 -8 -12 -11c-39 -31 -88 -50 -142 -50c-55 0 -105 19 -144 52c-4 3 -8 7 -12 11c-42 41 -68 98 -68 161s26 120 68 161c4 4 8 8 12 11c39 33 89 52 144 52c54 0 103 -19 142 -50c4 -3 8 -7 12 -11zM371 339
-l-5 5c-2 -2 -4 -3 -6 -5c-19 -19 -35 -41 -45 -66c-10 -23 -15 -48 -16 -73h133c-1 25 -6 50 -16 73c-10 25 -26 47 -45 66zM353 355c-15 12 -31 22 -48 29c-23 10 -48 15 -73 16v-200h51c2 61 29 116 70 155zM143 384c-19 -8 -36 -18 -51 -31c40 -39 66 -93 68 -153h56v200
-c-25 -1 -50 -6 -73 -16zM77 339c-19 -19 -35 -41 -45 -66c-10 -23 -15 -48 -16 -73h128c-1 25 -6 50 -16 73c-10 25 -26 47 -45 66l-3 3zM77 45l3 -3l3 3c19 19 35 41 45 66c10 23 15 48 16 73h-128c1 -25 6 -50 16 -73c10 -25 26 -47 45 -66zM92 31c15 -13 32 -23 51 -31
-c23 -10 48 -15 73 -16v200h-56c-2 -60 -28 -114 -68 -153zM305 0c17 7 33 17 48 29c-41 39 -68 94 -70 155h-51v-200c25 1 50 6 73 16zM371 45c19 19 35 41 45 66c10 23 15 48 16 73h-133c1 -25 6 -50 16 -73c10 -25 26 -47 45 -66c2 -2 4 -3 6 -5z" />
- <glyph glyph-name="ion-ios7-basketball" unicode="&#xf327;"
-d="M160 200c-2 60 -28 114 -68 153c-4 4 -8 8 -12 11c37 31 84 50 136 52v-216h-56zM283 200h-51v216c51 -2 96 -20 133 -50c-4 -3 -8 -7 -12 -11c-41 -39 -68 -94 -70 -155zM360 339l5 5c4 4 9 8 13 11c41 -39 68 -94 70 -155h-149c1 25 6 50 16 73c10 25 26 47 45 66z
-M128 273c10 -23 15 -48 16 -73h-144c2 60 28 114 68 153c4 -3 8 -7 12 -11l3 -3c19 -19 35 -41 45 -66zM283 184c2 -61 29 -116 70 -155c4 -4 8 -8 12 -11c-37 -30 -82 -48 -133 -50v216h51zM83 45l-3 -3c-4 -4 -8 -8 -12 -11c-40 39 -66 93 -68 153h144
-c-1 -25 -6 -50 -16 -73c-10 -25 -26 -47 -45 -66zM315 111c-10 23 -15 48 -16 73h149c-2 -61 -29 -116 -70 -155c-4 3 -9 7 -13 11l-5 5c-19 19 -35 41 -45 66zM160 184h56v-216c-52 2 -99 21 -136 52c4 3 8 7 12 11c40 39 66 93 68 153zM68 31v0v0zM378 29v0v0v0zM68 353v0
-v0v0zM80 20v0v0v0zM365 18v0v0zM80 364v0v0zM365 366v0v0v0zM378 355v0v0z" />
- <glyph glyph-name="ion-ios7-bell-outline" unicode="&#xf158;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-baseball-outline" unicode="&#xf3dd;" horiz-adv-x="416"
+d="M415 169v-1v0c-11 -97 -90 -174 -187 -183v0h-2c-2 0 -3 -1 -5 -1h-1h-3h-1h-8c-115 0 -208 93 -208 208v8v1v3v1c0 2 1 3 1 5v2v0c9 97 86 176 183 187v0v0c8 1 16 1 24 1c115 0 208 -93 208 -208c0 -7 0 -14 -1 -20v0v-3zM399 192c0 105 -86 191 -191 191
+c-3 0 -5 -1 -8 -1c0 -11 2 -21 4 -31l20 6l5 -15l-21 -7c2 -7 4 -14 7 -21c2 -5 5 -11 8 -16l17 12l9 -13l-19 -13c7 -12 16 -23 26 -33l14 15l12 -12l-15 -15c11 -10 22 -18 34 -25l12 18l14 -9l-12 -17c5 -2 10 -5 15 -7c7 -3 14 -5 22 -7l7 20l15 -5l-6 -19
+c10 -2 20 -4 30 -4c0 3 1 5 1 8zM17 192c0 -105 86 -191 191 -191h4c-1 9 -1 17 -3 26l-22 -7l-5 16l23 7c-2 8 -5 16 -8 24c-2 5 -4 9 -6 14l-20 -13l-9 13l21 14c-7 12 -16 24 -26 35l-17 -17l-11 11l17 17c-10 10 -22 18 -34 25l-14 -21l-14 9l14 20c-5 2 -10 5 -15 7
+c-7 3 -15 6 -23 8l-8 -24l-15 5l7 23c-9 2 -18 2 -27 3v-4zM228 2c88 9 158 78 169 166c-11 1 -23 3 -34 5l-9 -27l-15 5l8 25c-14 4 -28 10 -41 17l-15 -23l-13 9l14 21c-13 8 -26 17 -37 28l-19 -19l-11 11l19 19c-10 11 -19 23 -27 36l-21 -14l-9 13l22 15
+c-7 13 -12 27 -16 41l-25 -8l-5 16l26 8c-2 12 -4 23 -5 35c-88 -11 -157 -81 -166 -169c10 -1 21 -2 31 -4l8 23l15 -5l-7 -22c14 -4 28 -9 42 -16l13 19l14 -9l-13 -18c13 -8 25 -17 36 -28l17 17l11 -11l-17 -17c11 -12 20 -24 28 -37l19 13l9 -14l-20 -13
+c7 -14 12 -28 16 -42l23 7l5 -15l-24 -8c2 -10 3 -20 4 -30z" />
+ <glyph glyph-name="ion-ios-baseball" unicode="&#xf3de;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208c0 -8 0 -16 -1 -24v0v0c-12 -104 -100 -184 -207 -184c-115 0 -208 93 -208 208c0 107 80 195 184 207v0v0c8 1 16 1 24 1zM212 1c5 0 11 0 16 1c-1 10 -2 20 -4 30l24 8l-5 15l-23 -7c-4 14 -9 28 -16 42l20 13l-9 14l-19 -13
+c-8 13 -17 25 -28 37l17 17l-11 11l-17 -17c-11 11 -23 20 -36 28l13 18l-14 9l-13 -19c-14 7 -28 12 -42 16l7 22l-15 5l-8 -23c-10 2 -21 3 -31 4c-1 -5 -1 -11 -1 -16c9 -1 18 -1 27 -3l-7 -23l15 -5l8 24c8 -2 16 -5 23 -8c5 -2 10 -5 15 -7l-14 -20l14 -9l14 21
+c12 -7 24 -15 34 -25l-17 -17l11 -11l17 17c10 -11 19 -23 26 -35l-21 -14l9 -13l20 13c2 -5 4 -9 6 -14c3 -8 6 -16 8 -24l-23 -7l5 -16l22 7c2 -8 2 -17 3 -26zM363 173c11 -2 23 -4 34 -5c1 5 1 11 1 16c-10 1 -20 2 -30 4l6 19l-15 5l-7 -20c-8 2 -15 4 -22 7
+c-5 2 -10 5 -15 7l12 17l-14 9l-12 -18c-12 7 -23 15 -34 25l15 15l-12 12l-15 -15c-10 10 -18 21 -25 33l19 13l-9 13l-17 -12c-3 5 -6 11 -8 16c-3 7 -5 14 -7 21l21 7l-5 15l-20 -6c-2 10 -3 20 -4 31c-5 0 -11 0 -16 -1c1 -12 3 -23 5 -35l-26 -8l5 -16l25 8
+c4 -14 9 -28 16 -41l-22 -15l9 -13l21 14c8 -13 17 -25 27 -36l-19 -19l11 -11l19 19c11 -11 24 -20 37 -28l-14 -21l13 -9l15 23c13 -7 27 -13 41 -17l-8 -25l15 -5z" />
+ <glyph glyph-name="ion-ios-basketball-outline" unicode="&#xf3df;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM399 192c0 55 -24 105 -62 140c-14 -34 -31 -65 -52 -95c15 -12 31 -21 49 -29c21 -9 43 -14 65 -16v0zM325 343c-32 25 -73 40 -117 40v0c2 -22 6 -44 15 -65
+c10 -25 26 -47 45 -66c2 -1 2 -3 4 -4c20 29 38 60 52 93c0 1 1 1 1 2zM192 382c-51 -4 -96 -29 -128 -65c64 -28 121 -69 169 -119c11 12 21 24 30 37c-40 37 -67 89 -71 147zM233 174c-15 -16 -31 -30 -48 -44c28 -35 45 -79 47 -127c33 4 63 17 88 35
+c-22 50 -51 95 -87 136zM214 178l8 8l-10 10c-46 46 -99 82 -158 108c-18 -25 -31 -55 -35 -88c62 -3 116 -31 155 -74c14 11 27 23 40 36zM18 200c0 -3 -1 -5 -1 -8c0 -45 16 -87 43 -120c36 16 71 36 102 60l-7 7c-19 19 -41 35 -66 45c-22 9 -46 15 -71 16zM71 59
+c35 -36 83 -58 137 -58c3 0 5 1 8 1c-1 25 -6 48 -16 71c-7 17 -17 33 -28 47c-31 -24 -65 -45 -101 -61zM333 48c37 32 61 77 65 128c-46 3 -89 21 -123 48c-10 -13 -20 -26 -31 -38c36 -41 67 -87 89 -138z" />
+ <glyph glyph-name="ion-ios-basketball" unicode="&#xf3e0;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM333 48c-22 51 -53 97 -89 138c11 12 21 25 31 38c34 -27 77 -45 123 -48c0 5 1 11 1 16c-22 2 -44 7 -65 16c-18 8 -34 17 -49 29c21 30 38 61 52 95c-4 4 -8 8 -12 11
+c0 -1 -1 -1 -1 -2c-14 -33 -32 -64 -52 -93c-2 1 -2 2 -4 4c-19 19 -35 41 -45 66c-9 21 -13 43 -15 65c-5 0 -11 -1 -16 -1c4 -58 31 -110 71 -147c-9 -13 -19 -25 -30 -37c-48 50 -105 91 -169 119c-4 -4 -7 -9 -10 -13c59 -26 112 -62 158 -108l10 -10l-8 -8
+c-13 -13 -26 -25 -40 -36c-39 43 -93 71 -155 74c-1 -5 -1 -11 -1 -16c25 -1 49 -7 71 -16c25 -10 47 -26 66 -45l7 -7c-31 -24 -66 -44 -102 -60c4 -4 7 -9 11 -13c36 16 70 37 101 61c11 -14 21 -30 28 -47c10 -23 15 -46 16 -71c5 0 11 0 16 1c-2 48 -19 92 -47 127
+c17 14 33 28 48 44c36 -41 65 -86 87 -136c4 3 9 6 13 10z" />
+ <glyph glyph-name="ion-ios-bell-outline" unicode="&#xf3e1;" horiz-adv-x="384"
d="M318 222c0 -114 28 -126 66 -158h-384c38 32 66 44 66 158c0 98 53 130 102 138v2c0 12 11 22 24 22s24 -10 24 -22v-2c49 -7 102 -40 102 -138zM43 80h298c-25 25 -40 58 -40 142c0 46 -13 80 -37 101c-23 19 -52 23 -72 23s-49 -4 -72 -23c-25 -21 -37 -55 -37 -101
c0 -51 -5 -85 -17 -110c-6 -13 -14 -23 -23 -32zM192 0c-27 0 -49 20 -52 43h104c-3 -23 -25 -43 -52 -43z" />
- <glyph glyph-name="ion-ios7-bell" unicode="&#xf159;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-bell" unicode="&#xf3e2;" horiz-adv-x="384"
d="M318 222c0 -114 28 -126 66 -158h-384c38 32 66 44 66 158c0 98 53 130 102 138v2c0 12 11 22 24 22s24 -10 24 -22v-2c49 -7 102 -40 102 -138zM192 0c-27 0 -49 20 -52 43h104c-3 -23 -25 -43 -52 -43z" />
- <glyph glyph-name="ion-ios7-bolt-outline" unicode="&#xf15a;" horiz-adv-x="226"
+ <glyph glyph-name="ion-ios-body-outline" unicode="&#xf3e3;" horiz-adv-x="384"
+d="M192 400c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM192 416v0c27 0 48 -21 48 -48s-21 -48 -48 -48s-48 21 -48 48s21 48 48 48zM360 304c13 0 24 -11 24 -24s-11 -24 -24 -24h-100c-5 0 -14 -5 -18 -15c-5 -12 -2 -33 1 -51l4 -21v-1v0l32 -172
+c2 -13 -6 -26 -19 -28h-5c-11 0 -22 8 -24 20l-21 120v0s-5 31 -17 31h-2c-12 0 -19 -31 -19 -31v0l-21 -120c-2 -12 -11 -20 -22 -20h-5c-13 2 -21 15 -19 28l32 172v1l4 21c3 18 6 39 1 51c-4 10 -12 15 -18 15h-100c-13 0 -24 11 -24 24s11 24 24 24h336zM24 272
+c-4 0 -8 4 -8 8s4 8 8 8h336c4 0 8 -4 8 -8s-4 -8 -8 -8h-102c-16 0 -26 -15 -30 -24c-5 -13 -6 -32 -1 -61v0v0l3 -19l1 -3l32 -172c0 -3 0 -5 -1 -6s-2 -2 -5 -3h-2c-4 0 -7 2 -8 6l-21 120v0c0 2 -2 10 -5 19c-2 6 -5 11 -8 15c-7 9 -14 11 -20 11h-2
+c-5 0 -13 -2 -20 -11c-3 -4 -6 -9 -8 -15c-4 -9 -6 -17 -6 -18v-1l-21 -120c-1 -4 -3 -6 -7 -6h-2c-3 0 -4 2 -5 3s-2 3 -1 6l32 172v0v1l4 21v0v0c5 29 5 48 0 61c-4 9 -14 24 -32 24z" />
+ <glyph glyph-name="ion-ios-body" unicode="&#xf3e4;" horiz-adv-x="384"
+d="M144 368c0 32 16 48 48 48s48 -16 48 -48s-16 -48 -48 -48s-48 16 -48 48zM360 304c7 0 12 -2 17 -7s7 -10 7 -17s-2 -12 -7 -17s-10 -7 -17 -7h-98c-8 -2 -15 -6 -18 -14c-4 -9 -3 -27 1 -52l4 -21v-1v0l30 -172c1 -7 0 -13 -4 -18s-8 -9 -15 -10s-13 0 -18 4
+s-9 9 -10 16l-21 120v-1l-2 9c-1 5 -3 11 -6 16s-6 8 -10 8h-2c-8 0 -14 -11 -18 -33v1l-21 -120c-1 -7 -5 -12 -10 -16s-11 -5 -18 -4s-11 5 -15 10s-5 11 -4 18l30 172v0v1l4 21c4 25 5 43 1 52c-3 8 -10 12 -18 14h-98c-7 0 -12 2 -17 7s-7 10 -7 17s2 12 7 17s10 7 17 7
+h336z" />
+ <glyph glyph-name="ion-ios-bolt-outline" unicode="&#xf3e5;" horiz-adv-x="226"
d="M131 316l-100 -140h65h19l-3 -19l-17 -89l100 140h-65h-19l3 19zM160 384v0l-30 -160h96l-160 -224l30 160h-96z" />
- <glyph glyph-name="ion-ios7-bolt" unicode="&#xf15b;" horiz-adv-x="226"
+ <glyph glyph-name="ion-ios-bolt" unicode="&#xf3e6;" horiz-adv-x="226"
d="M160 384v0l-30 -160h96l-160 -224l30 160h-96z" />
- <glyph glyph-name="ion-ios7-bookmarks-outline" unicode="&#xf15c;" horiz-adv-x="418"
+ <glyph glyph-name="ion-ios-book-outline" unicode="&#xf3e7;" horiz-adv-x="384"
+d="M284 384c55 0 100 -26 100 -79v-1v-4v-261v-17h-6h-11h-5c-17 30 -44 42 -78 42c-40 0 -74 -28 -82 -64h-20c-8 36 -42 64 -82 64c-34 0 -65 -16 -78 -42h-5h-11h-6v9v264v9v1c0 53 45 79 100 79c41 0 78 -14 92 -44c12 30 51 44 92 44zM184 37v254v13v2
+c-1 43 -39 62 -84 62c-44 0 -81 -19 -84 -61v-1v0v-262h1c19 26 48 36 83 36s66 -17 84 -43zM368 300v14v1c-3 42 -40 53 -84 53c-46 0 -84 -20 -84 -64v-1v-266c18 26 49 43 84 43s66 -10 84 -36v256z" />
+ <glyph glyph-name="ion-ios-book" unicode="&#xf3e8;" horiz-adv-x="384"
+d="M100 384c35 0 67 -10 84 -31v-353h-2c-8 36 -42 64 -82 64c-34 0 -65 -16 -78 -42h-5h-11h-6v9v264v9v1c0 53 45 79 100 79zM284 384c55 0 100 -26 100 -79v-1v-4v-261v-17h-6h-11h-5c-17 30 -44 42 -78 42c-40 0 -74 -28 -82 -64h-2v353c17 21 50 31 84 31z" />
+ <glyph glyph-name="ion-ios-bookmarks-outline" unicode="&#xf3e9;" horiz-adv-x="418"
d="M385 384c19 0 33 -13 33 -32v-286c0 -19 -14 -34 -33 -34h-143s-25 -4 -25 -19v-13h-8h-8v13c0 15 -11 19 -25 19h-143c-19 0 -33 15 -33 34v286c0 19 14 32 33 32h150c10 0 20 -5 26 -12v0v0c6 7 16 12 26 12h150zM201 37v309c0 9 -12 22 -25 22h-143
c-9 0 -16 -7 -16 -16v-286c0 -9 7 -18 16 -18h144c10 0 19 -3 24 -11zM273 368v-100l23 14l9 6l9 -6l23 -14v100h-64zM401 66v286c0 9 -7 16 -16 16h-32v-131l-48 32l-48 -32v131h-15c-13 0 -25 -13 -25 -22v-309c5 9 14 11 24 11h144c9 0 16 9 16 18z" />
- <glyph glyph-name="ion-ios7-bookmarks" unicode="&#xf15d;" horiz-adv-x="418"
+ <glyph glyph-name="ion-ios-bookmarks" unicode="&#xf3ea;" horiz-adv-x="418"
d="M296 283l-23 -15v116h64v-116l-23 15l-9 6zM385 384c19 0 33 -13 33 -32v-286c0 -19 -14 -34 -33 -34h-143s-25 -4 -25 -19v-13h-8h-8v13c0 15 -11 19 -25 19h-143c-19 0 -33 15 -33 34v286c0 19 14 32 33 32h150s18 -8 18 -15v-329l8 -6l8 6v329s10 15 18 15h22v-146
l48 32l48 -32v146h32z" />
- <glyph glyph-name="ion-ios7-box-outline" unicode="&#xf15e;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-box-outline" unicode="&#xf3eb;" horiz-adv-x="320"
d="M192 208h-1h-63c-9 0 -16 -7 -16 -16s7 -16 16 -16h64c9 0 16 7 16 16s-7 16 -16 16zM192 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32h-64c-18 0 -32 14 -32 32s14 32 32 32h64zM320 336v-80h-16v-208h-288v208h-16v80h320zM288 64v192h-256v-192h256zM304 272v48h-288
v-48h288z" />
- <glyph glyph-name="ion-ios7-box" unicode="&#xf15f;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-box" unicode="&#xf3ec;" horiz-adv-x="320"
d="M16 48v192h288v-192h-288zM128 208c-9 0 -16 -7 -16 -16s7 -16 16 -16h64c9 0 16 7 16 16s-7 16 -16 16h-64zM0 336h320v-80h-16h-288h-16v80z" />
- <glyph glyph-name="ion-ios7-briefcase-outline" unicode="&#xf282;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-briefcase-outline" unicode="&#xf3ed;" horiz-adv-x="416"
d="M368 320h48v-320h-416v320h48v16h32v-16h48v30v2c0 18 10 32 29 32h99c19 0 32 -14 32 -32v-2v-30h48v16h32v-16zM144 320v0h128v0v30c0 10 -7 18 -17 18h-97c-11 0 -14 -8 -14 -18v-30zM400 16v224h-384v-224h384zM400 256v48h-32v-16h-32v16h-256v-16h-32v16h-32v-48
h384z" />
- <glyph glyph-name="ion-ios7-briefcase" unicode="&#xf283;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-briefcase" unicode="&#xf3ee;" horiz-adv-x="416"
d="M48 320v16h32v-16h-32zM0 0v240h416v-240h-416zM336 320v16h32v-16h-32zM368 320h48v-64h-416v64h48v-32h32v32h48v30v2c0 18 10 32 29 32h99c19 0 32 -14 32 -32v-2v-30h48v-32h32v32zM272 320v30c0 10 -7 18 -17 18h-97c-11 0 -14 -8 -14 -18v-30v0h128v0z" />
- <glyph glyph-name="ion-ios7-browsers-outline" unicode="&#xf160;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-browsers-outline" unicode="&#xf3ef;" horiz-adv-x="384"
d="M0 304h304v-304h-304v304zM288 16v272h-272v-272h272zM384 384v-304h-64v16h48v272h-272v-48h-16v64h304z" />
- <glyph glyph-name="ion-ios7-browsers" unicode="&#xf161;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-browsers" unicode="&#xf3f0;" horiz-adv-x="384"
d="M0 304h304v-304h-304v304zM80 384h304v-304h-64v240h-240v64z" />
- <glyph glyph-name="ion-ios7-calculator-outline" unicode="&#xf284;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-calculator-outline" unicode="&#xf3f1;" horiz-adv-x="288"
d="M32 288v64h224v-64h-224zM48 336v-32h192v32h-192zM256 384c18 0 32 -14 32 -32v-320c0 -18 -14 -32 -32 -32h-224c-18 0 -32 14 -32 32v320c0 18 14 32 32 32h224zM272 32v320c0 9 -7 16 -16 16h-224c-9 0 -16 -7 -16 -16v-320c0 -9 7 -16 16 -16h224c9 0 16 7 16 16z
M48 208h32h16v-16h-64v64h16v-16v-32zM48 128h32h16v-16h-64v64h16v-16v-32zM48 48h32h16v-16h-64v64h16v-16v-32zM128 208h32h16v-16h-64v64h16v-16v-32zM208 208h32h16v-16h-64v64h16v-16v-32zM128 128h32h16v-16h-64v64h16v-16v-32zM128 48h32h16v-16h-64v64h16v-16v-32z
M208 48h32h16v-16h-64v144h16v-96v-32z" />
- <glyph glyph-name="ion-ios7-calculator" unicode="&#xf285;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-calculator" unicode="&#xf3f2;" horiz-adv-x="288"
d="M256 384c18 0 32 -14 32 -32v-320c0 -18 -14 -32 -32 -32h-224c-18 0 -32 14 -32 32v320c0 18 14 32 32 32h224zM248 168h-48v-128h48v128zM248 248h-48v-48h48v48zM168 88h-48v-48h48v48zM168 168h-48v-48h48v48zM168 248h-48v-48h48v48zM88 88h-48v-48h48v48zM88 168
h-48v-48h48v48zM88 248h-48v-48h48v48zM40 296h208v48h-208v-48z" />
- <glyph glyph-name="ion-ios7-calendar-outline" unicode="&#xf162;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-calendar-outline" unicode="&#xf3f3;" horiz-adv-x="384"
d="M16 336v-64h352v64zM288 352h96v-352h-384v352h96v32h16v-32h160v32h16v-32zM368 16v240h-352v-240h352zM368 272v64h-80v-32h-16v32h-160v-32h-16v32h-80v-64h352z" />
- <glyph glyph-name="ion-ios7-calendar" unicode="&#xf163;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-calendar" unicode="&#xf3f4;" horiz-adv-x="384"
d="M0 0v256h384v-256h-384zM384 352v-80h-384v80h96v-48h16v48h160v-48h16v48h96zM96 352v32h16v-32h-16zM272 352v32h16v-32h-16z" />
- <glyph glyph-name="ion-ios7-camera-outline" unicode="&#xf164;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-camera-outline" unicode="&#xf3f5;" horiz-adv-x="384"
d="M354 288c18 0 30 -13 30 -31v-176c0 -18 -12 -33 -30 -33h-320c-18 0 -34 15 -34 33v176c0 18 16 31 34 31h13v16h34v-16h13c32 36 43 48 55 48h88c12 0 23 -12 55 -48h62zM368 81v176c0 9 -5 15 -14 15h-62h-7l-5 3c-3 4 -7 8 -10 11c-12 13 -20 24 -26 30
c-5 5 -7 4 -7 4h-88s-2 0 -7 -4c-6 -5 -14 -14 -25 -27c-3 -4 -7 -10 -11 -14l-5 -3h-7h-60c-9 0 -18 -7 -18 -15v-176c0 -9 9 -17 18 -17h320c8 0 14 8 14 17zM192 258c47 0 86 -38 86 -85s-39 -85 -86 -85s-86 38 -86 85s39 85 86 85zM192 104c38 0 70 31 70 69
s-32 69 -70 69s-70 -31 -70 -69s32 -69 70 -69zM288 239v17h17v-17h-17zM160 173c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32z" />
- <glyph glyph-name="ion-ios7-camera" unicode="&#xf165;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-camera" unicode="&#xf3f6;" horiz-adv-x="384"
d="M354 288c18 0 30 -13 30 -31v-176c0 -18 -12 -33 -30 -33h-320c-18 0 -34 15 -34 33v176c0 18 16 31 34 31h13v16h34v-16h13c32 36 43 48 55 48h88c12 0 23 -12 55 -48h62zM192 88c47 0 86 38 86 85s-39 85 -86 85s-86 -38 -86 -85s39 -85 86 -85zM305 239v17h-17v-17h17
zM192 242c38 0 70 -31 70 -69s-32 -69 -70 -69s-70 31 -70 69s32 69 70 69zM192 141c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
- <glyph glyph-name="ion-ios7-cart-outline" unicode="&#xf166;" horiz-adv-x="384"
-d="M377 32c0 -14 -11 -25 -25 -25s-25 11 -25 25s11 25 25 25s25 -11 25 -25zM89 32c0 -14 -11 -25 -25 -25s-25 11 -25 25s11 25 25 25s25 -11 25 -25zM64 352h320l-15 -175s-209 -30 -244 -34s-69 -30 -74 -62h333v-17h-352s0 5 2 17c5 35 33 62 65 73l-57 213h-42v17h53z
-M352 192l15 143h-297l44 -177c1 0 2 1 3 1z" />
- <glyph glyph-name="ion-ios7-cart" unicode="&#xf167;" horiz-adv-x="384"
-d="M377 32c0 -14 -11 -25 -25 -25s-25 11 -25 25s11 25 25 25s25 -11 25 -25zM89 32c0 -14 -11 -25 -25 -25s-25 11 -25 25s11 25 25 25s25 -11 25 -25zM64 352h320l-15 -175s-209 -30 -244 -34s-69 -30 -74 -62h333v-17h-352s0 5 2 17c5 35 33 62 65 73l-57 213h-42v17h53z
-" />
- <glyph glyph-name="ion-ios7-chatboxes-outline" unicode="&#xf168;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-cart-outline" unicode="&#xf3f7;" horiz-adv-x="384"
+d="M96 48c13 0 24 -11 24 -24s-11 -24 -24 -24s-24 11 -24 24s11 24 24 24zM96 16c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM320 48c13 0 24 -11 24 -24s-11 -24 -24 -24s-24 11 -24 24s11 24 24 24zM320 16c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM384 320
+l-16 -128l-271 -48l5 -30c7 -34 21 -34 26 -34h240v-16h-240c-11 0 -21 5 -28 14c-6 8 -11 19 -13 33l-43 234v0c-2 8 -3 12 -7 16c-6 5 -18 7 -37 7v16c23 0 38 -4 47 -11c7 -6 10 -14 12 -21zM355 206l11 99l-304 31l32 -176z" />
+ <glyph glyph-name="ion-ios-cart" unicode="&#xf3f8;" horiz-adv-x="384"
+d="M96 48c13 0 24 -11 24 -24s-11 -24 -24 -24s-24 11 -24 24s11 24 24 24zM320 48c13 0 24 -11 24 -24s-11 -24 -24 -24s-24 11 -24 24s11 24 24 24zM384 320l-16 -128l-271 -48l5 -30c7 -34 21 -34 26 -34h240v-16h-240c-11 0 -21 5 -28 14c-6 8 -11 19 -13 33l-43 234v0
+c-2 8 -3 12 -7 16c-6 5 -18 7 -37 7v16c23 0 38 -4 47 -11c7 -6 10 -14 12 -21z" />
+ <glyph glyph-name="ion-ios-chatboxes-outline" unicode="&#xf3f9;" horiz-adv-x="416"
d="M16 384v-192h96v-16h-112v224h288v-112h-16v96h-256zM128 272h288v-224h-48v-64h-13l-64 64h-163v224zM400 64v192h-256v-192h153l55 -55v55h48z" />
- <glyph glyph-name="ion-ios7-chatboxes" unicode="&#xf169;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-chatboxes" unicode="&#xf3fa;" horiz-adv-x="416"
d="M288 400v-112h-176v-112h-112v224h288zM128 272h288v-224h-48v-64h-13l-64 64h-163v224z" />
- <glyph glyph-name="ion-ios7-chatbubble-outline" unicode="&#xf16a;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-chatbubble-outline" unicode="&#xf3fb;" horiz-adv-x="384"
d="M192 336c-97 0 -176 -62 -176 -138c0 -26 10 -51 27 -73c0 -1 0 -2 1 -3s2 -1 2 -2c4 -6 6 -13 6 -20c0 -3 1 -3 -13 -47l39 17v0c2 1 10 4 11 4h1v0c5 2 10 3 16 3c5 0 9 -1 14 -2l1 -1h2c19 -6 41 -10 70 -10c48 0 92 15 125 40c32 25 50 58 50 94
c0 76 -79 138 -176 138zM192 352v0c106 0 192 -69 192 -154s-85 -150 -191 -150c-27 0 -52 3 -75 11h-2v0c-3 1 -6 2 -10 2s-9 -1 -12 -2h1h-1c-1 0 -9 -4 -10 -4l-50 -22l-2 -1h-3h-3c-6 1 -8 6 -7 10v0s17 57 17 58c0 4 -1 8 -3 11v0v0v0l1 -1l-4 4c-19 24 -30 53 -30 84
c0 85 86 154 192 154z" />
- <glyph glyph-name="ion-ios7-chatbubble" unicode="&#xf16b;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-chatbubble" unicode="&#xf3fc;" horiz-adv-x="384"
d="M192 352v0c106 0 192 -69 192 -154s-85 -150 -191 -150c-27 0 -52 3 -75 11h-2v0c-3 1 -6 2 -10 2s-9 -1 -12 -2h1h-1c-1 0 -9 -4 -10 -4l-50 -22l-2 -1h-3h-3c-6 1 -8 6 -7 10v0s17 57 17 58c0 4 -1 8 -3 11v0v0v0l1 -1l-4 4c-19 24 -30 53 -30 84c0 85 86 154 192 154z
" />
- <glyph glyph-name="ion-ios7-checkmark-empty" unicode="&#xf16c;" horiz-adv-x="207"
+ <glyph glyph-name="ion-ios-checkmark-empty" unicode="&#xf3fd;" horiz-adv-x="207"
d="M74 118c-2 -2 -6 -4 -9 -4s-7 2 -9 4l-56 56l18 18l47 -47l125 126l17 -18z" />
- <glyph glyph-name="ion-ios7-checkmark-outline" unicode="&#xf16d;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-checkmark-outline" unicode="&#xf3fe;" horiz-adv-x="416"
d="M292 271l18 -18l-134 -135c-2 -2 -6 -4 -9 -4s-7 2 -9 4l-56 56l18 18l47 -47zM208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191z" />
- <glyph glyph-name="ion-ios7-checkmark" unicode="&#xf16e;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-checkmark" unicode="&#xf3ff;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM176 118l134 135l-18 18l-125 -126l-47 47l-18 -18l56 -56c2 -2 6 -4 9 -4s7 2 9 4z" />
- <glyph glyph-name="ion-ios7-circle-filled" unicode="&#xf16f;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-circle-filled" unicode="&#xf400;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM208 352c88 0 160 -72 160 -160s-72 -160 -160 -160s-160 72 -160 160s72 160 160 160z" />
- <glyph glyph-name="ion-ios7-circle-outline" unicode="&#xf170;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-circle-outline" unicode="&#xf401;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191z" />
- <glyph glyph-name="ion-ios7-clock-outline" unicode="&#xf171;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-clock-outline" unicode="&#xf402;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM208 192v128h17v-145h-113v17h96z" />
- <glyph glyph-name="ion-ios7-clock" unicode="&#xf172;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-clock" unicode="&#xf403;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM225 175v145h-17v-128h-96v-17h113z" />
- <glyph glyph-name="ion-ios7-close-empty" unicode="&#xf2bd;" horiz-adv-x="192"
+ <glyph glyph-name="ion-ios-close-empty" unicode="&#xf404;" horiz-adv-x="192"
d="M180 288l12 -12l-84 -84l84 -84l-12 -12l-84 84l-84 -84l-12 12l84 84l-84 84l12 12l84 -84z" />
- <glyph glyph-name="ion-ios7-close-outline" unicode="&#xf2bb;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-close-outline" unicode="&#xf405;" horiz-adv-x="416"
d="M355 339c81 -81 81 -213 0 -294s-213 -81 -294 0s-81 213 0 294s213 81 294 0zM343 57c74 74 74 196 0 270s-196 74 -270 0s-74 -196 0 -270s196 -74 270 0zM292 288l12 -12l-84 -84l84 -84l-12 -12l-84 84l-84 -84l-12 12l84 84l-84 84l12 12l84 -84z" />
- <glyph glyph-name="ion-ios7-close" unicode="&#xf2bc;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-close" unicode="&#xf406;" horiz-adv-x="416"
d="M355 339c81 -81 81 -213 0 -294s-213 -81 -294 0s-81 213 0 294s213 81 294 0zM304 108l-84 84l84 84l-12 12l-84 -84l-84 84l-12 -12l84 -84l-84 -84l12 -12l84 84l84 -84z" />
- <glyph glyph-name="ion-ios7-cloud-download-outline" unicode="&#xf173;"
+ <glyph glyph-name="ion-ios-cloud-download-outline" unicode="&#xf407;"
d="M161 67l55 -54v242h16v-242l55 54l12 -12l-75 -73l-74 73zM367 284c45 0 81 -37 81 -82s-37 -82 -82 -82v0h-101v16h97h4c37 0 66 30 66 66s-29 67 -66 67h-15v20c0 55 -46 97 -101 97c-38 0 -73 -22 -90 -56l-6 -14l-14 7c-6 3 -13 5 -20 5c-22 0 -40 -18 -44 -39l-1 -9
l-9 -3c-30 -10 -50 -36 -50 -67c0 -40 33 -74 74 -74h91v-16h-91c-50 0 -90 40 -90 89c0 39 26 71 61 83c5 28 29 51 59 51c10 0 18 -2 26 -6c19 39 59 65 105 65c64 0 117 -51 117 -115c0 -1 -1 -2 -1 -3z" />
- <glyph glyph-name="ion-ios7-cloud-download" unicode="&#xf174;"
+ <glyph glyph-name="ion-ios-cloud-download" unicode="&#xf408;"
d="M216 13v107h16v-107l55 54l12 -12l-75 -73l-74 73l11 12zM367 284c45 0 81 -37 81 -82s-37 -82 -82 -82h-134v135h-16v-135h-35h-21h-70c-50 0 -90 40 -90 89c0 39 26 71 61 83c5 28 29 51 59 51c10 0 18 -2 26 -6c19 39 59 65 105 65c64 0 117 -51 117 -115
c0 -1 -1 -2 -1 -3z" />
- <glyph glyph-name="ion-ios7-cloud-outline" unicode="&#xf175;"
+ <glyph glyph-name="ion-ios-cloud-outline" unicode="&#xf409;"
d="M367 215c45 0 81 -37 81 -83c0 -45 -37 -84 -82 -84h-276c-50 0 -90 42 -90 92c0 40 26 71 61 83c5 28 29 52 59 52c10 0 18 -2 26 -6c19 39 59 67 105 67c64 0 117 -53 117 -117c0 -1 -1 -3 -1 -4zM366 64c37 0 66 32 66 69s-29 67 -66 67h-15v21c0 56 -46 99 -101 99
c-38 0 -73 -23 -90 -58l-6 -14l-14 7c-6 3 -13 5 -20 5c-22 0 -40 -17 -44 -39l-1 -9l-9 -3c-30 -10 -50 -37 -50 -69c0 -41 33 -76 74 -76h272h4z" />
- <glyph glyph-name="ion-ios7-cloud-upload-outline" unicode="&#xf176;"
+ <glyph glyph-name="ion-ios-cloud-upload-outline" unicode="&#xf40a;"
d="M161 188l-11 11l74 75l75 -75l-12 -11l-55 54v-242h-16v242zM367 264c45 0 81 -39 81 -85s-37 -83 -82 -83v0h-101v16h97h4c37 0 66 30 66 67s-29 70 -66 70l-15 1v20c0 56 -46 99 -101 99c-38 0 -73 -23 -90 -58l-6 -13l-14 6c-6 3 -13 5 -20 5c-22 0 -40 -17 -44 -39
l-1 -9l-9 -3c-30 -10 -50 -39 -50 -71c0 -41 33 -75 74 -75h91v-16h-91c-50 0 -90 40 -90 90c0 40 26 74 61 86c5 28 29 52 59 52c10 0 18 -2 26 -6c19 39 59 66 105 66c64 0 117 -52 117 -116c0 -1 -1 -3 -1 -4z" />
- <glyph glyph-name="ion-ios7-cloud-upload" unicode="&#xf177;"
+ <glyph glyph-name="ion-ios-cloud-upload" unicode="&#xf40b;"
d="M216 0v96h16v-96h-16zM367 264c45 0 81 -39 81 -85s-37 -83 -82 -83h-134v146l55 -54l12 11l-75 75l-74 -75l11 -11l55 54v-146h-35h-31h-60c-50 0 -90 40 -90 90c0 40 26 74 61 86c5 28 29 52 59 52c10 0 18 -2 26 -6c19 39 59 66 105 66c64 0 117 -52 117 -116
c0 -1 -1 -3 -1 -4z" />
- <glyph glyph-name="ion-ios7-cloud" unicode="&#xf178;"
+ <glyph glyph-name="ion-ios-cloud" unicode="&#xf40c;"
d="M367 215c45 0 81 -37 81 -83c0 -45 -37 -84 -82 -84h-276c-50 0 -90 42 -90 92c0 40 26 71 61 83c5 28 29 52 59 52c10 0 18 -2 26 -6c19 39 59 67 105 67c64 0 117 -53 117 -117c0 -1 -1 -3 -1 -4z" />
- <glyph glyph-name="ion-ios7-cloudy-night-outline" unicode="&#xf307;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-cloudy-night-outline" unicode="&#xf40d;" horiz-adv-x="384"
d="M125 224c-34 0 -63 -28 -63 -62v-12s1 -10 1 -10c-5 0 -12 -1 -14 -1c-19 -3 -33 -18 -33 -37c0 -10 3 -19 10 -26s16 -11 26 -11h157c27 0 49 22 49 49s-22 50 -49 50c-2 0 -4 -1 -6 -1l-14 -2l-3 14c-3 14 -11 26 -22 35s-25 14 -39 14zM125 240v0c37 0 68 -26 76 -61
h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78zM361 142c8 0 15 2 23 4c-4 -7 -9 -14 -14 -20c-21 -24 -50 -41 -84 -45c4 6 6 12 8 19c19 4 36 13 50 25c-18 1 -35 6 -50 13c-23 11 -42 29 -56 51
c-14 21 -22 48 -22 75c0 15 2 30 7 44c-24 -12 -43 -33 -53 -59c-5 2 -12 4 -18 5c14 36 45 65 82 77c8 2 16 4 24 5c-5 -6 -9 -13 -12 -20c-8 -16 -12 -34 -12 -52c0 -32 12 -63 35 -86s54 -36 86 -36h6z" />
- <glyph glyph-name="ion-ios7-cloudy-night" unicode="&#xf308;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-cloudy-night" unicode="&#xf40e;" horiz-adv-x="384"
d="M361 142c8 0 15 2 23 4c-4 -7 -9 -15 -14 -21c-21 -24 -50 -40 -84 -44h-3c4 10 7 21 7 32c0 22 -9 43 -24 58c-14 15 -33 23 -53 24c-6 16 -16 29 -29 40c-10 8 -20 13 -32 17v2c14 36 45 65 82 77c8 2 16 4 24 5c-5 -6 -9 -13 -12 -20c-8 -16 -12 -34 -12 -52
c0 -32 12 -63 35 -86s54 -36 86 -36h6zM125 239v0c37 0 68 -26 76 -61h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v7c0 43 35 79 78 79z" />
- <glyph glyph-name="ion-ios7-cloudy-outline" unicode="&#xf179;" horiz-adv-x="274"
+ <glyph glyph-name="ion-ios-cloudy-outline" unicode="&#xf40f;" horiz-adv-x="274"
d="M125 272c-34 0 -63 -28 -63 -62v-12s1 -10 1 -10c-6 0 -12 -1 -14 -1c-19 -3 -33 -18 -33 -37c0 -10 3 -19 10 -26s16 -11 26 -11h157c27 0 49 22 49 49s-22 50 -49 50c-2 0 -4 -1 -6 -1l-14 -2l-3 14c-3 14 -11 26 -22 35s-25 14 -39 14zM125 288v0c37 0 68 -26 76 -61
h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78z" />
- <glyph glyph-name="ion-ios7-cloudy" unicode="&#xf17a;" horiz-adv-x="274"
+ <glyph glyph-name="ion-ios-cloudy" unicode="&#xf410;" horiz-adv-x="274"
d="M125 288v0c37 0 68 -26 76 -61h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78z" />
- <glyph glyph-name="ion-ios7-cog-outline" unicode="&#xf17b;" horiz-adv-x="384"
-d="M313 235c4 -12 7 -25 8 -37v-13c-1 -13 -4 -25 -8 -37c-1 -4 -3 -7 -5 -12c-5 -11 -11 -20 -19 -29c0 0 -2 -3 -6 -7s-7 -6 -7 -6c-9 -8 -19 -14 -29 -19c-4 -2 -8 -3 -11 -4c-12 -4 -24 -7 -37 -8h-13c-13 1 -25 4 -37 8c-4 1 -7 3 -11 5c-11 5 -23 12 -32 21l-4 4l-4 4
-c-9 10 -16 20 -21 32c-2 3 -3 7 -4 10c0 0 -1 3 -3 10s-3 10 -3 10c-1 6 -2 13 -2 19v11c1 13 4 26 8 38c1 4 2 7 4 10c5 12 12 22 21 32c1 2 3 4 4 5s3 3 5 4c9 8 20 15 31 20c4 2 7 4 11 5c12 4 25 7 38 8h11c6 0 13 -1 19 -2l8 -2s11 -4 11 -4c3 -1 7 -2 11 -4
-c12 -5 22 -12 32 -21l4 -4l4 -4c9 -9 15 -20 21 -32c2 -4 4 -7 5 -11zM81 186c0 -5 1 -11 2 -16l103 28l28 103c-5 1 -10 2 -16 2h-10c-11 0 -22 -3 -33 -7c-3 -1 -8 -2 -11 -4c-10 -5 -18 -10 -26 -18l-4 -4l-4 -4c-8 -9 -14 -18 -19 -28l-3 -9c-4 -11 -7 -22 -7 -33v-10z
-M240 89c9 4 18 10 26 17l-76 76l-103 -28v-1c1 -3 3 -6 4 -9c5 -10 11 -20 19 -28l4 -4s2 -3 3 -4c8 -8 18 -13 28 -18c3 -2 7 -3 10 -4c10 -4 21 -6 32 -7h11c11 0 22 3 32 7c3 1 7 2 10 3zM305 186v11c-1 11 -3 22 -7 32c-1 3 -2 7 -4 10c-5 10 -11 20 -19 28l-3 3l-4 4
-c-8 8 -18 14 -28 19c-3 2 -7 2 -10 3l-1 1l-28 -104l76 -76c7 8 13 16 17 25c2 3 3 7 4 11c4 10 7 22 7 33zM384 175l-33 -8c-1 -5 -2 -10 -3 -14l27 -20l-12 -30l-34 5c-2 -4 -5 -7 -8 -11l17 -29l-22 -23l-30 17c-3 -2 -6 -5 -10 -7l5 -34l-29 -12l-21 27
-c-4 -1 -9 -2 -14 -3l-8 -33h-32l-9 33c-4 1 -9 2 -13 3l-21 -28l-29 12l4 34c-4 2 -7 5 -11 8l-30 -18l-23 22l18 31c-3 4 -5 7 -7 11l-35 -5l-12 29l28 22c-1 4 -1 8 -2 12l-35 9v32l35 9c1 4 1 8 2 12l-29 22l12 30l36 -5c2 4 5 7 7 10l-19 32l22 22l32 -19c4 3 8 6 12 8
-l-5 35l29 13l22 -29c4 1 8 1 12 2l9 35h32l9 -35c4 -1 8 -1 12 -2l22 28l29 -12l-5 -35c4 -2 7 -5 11 -8l30 18l22 -23l-17 -29c3 -4 5 -7 7 -11l35 5l12 -30l-28 -21c1 -4 2 -9 3 -13l33 -9v-32zM338 140l-8 7l2 10l3 12l1 11l10 2l22 6v7l-22 6l-10 2l-1 11l-3 12l-2 10
-l8 6l18 13l-3 7l-22 -3l-10 -1l-6 8c-2 3 -3 6 -6 10l-7 8l6 10l11 18l-5 6l-20 -12l-8 -5l-9 7l-9 6l-10 6l2 10l4 23l-7 2l-14 -18l-6 -8l-10 2c-4 1 -7 1 -11 2l-11 2l-3 10l-5 23h-7l-6 -23l-3 -10l-11 -2c-4 0 -6 -1 -10 -2l-11 -2l-6 8l-14 19l-7 -3l3 -23l2 -11
-l-9 -5l-2 -1c-3 -2 -5 -4 -8 -6l-9 -6l-9 6l-21 12l-5 -5l12 -21l6 -9l-6 -8c-2 -3 -4 -7 -6 -10l-6 -9l-10 2l-23 3l-3 -7l19 -14l8 -6l-2 -10c-1 -4 -1 -7 -2 -11l-2 -11l-10 -2l-23 -6v-7l23 -6l10 -3l1 -10c1 -4 2 -7 3 -11l2 -11l-8 -6l-19 -14l3 -6l23 3l10 1l6 -9
-c2 -4 4 -7 6 -10l6 -8l-5 -9l-12 -20l5 -5l20 11l9 6l9 -6c3 -2 6 -5 10 -7l9 -5l-2 -11l-3 -22l7 -3l13 18l6 9l11 -3c4 -1 8 -1 12 -2l10 -2l3 -10l5 -21h8l5 21l2 10l11 2c4 1 8 1 12 2l10 3l7 -9l13 -17l7 3l-4 21l-1 11l9 5c2 2 4 4 7 6c0 0 1 1 2 1l8 6l9 -5l19 -11
-l5 5l-11 18l-5 9l6 9c2 3 6 6 8 10l5 9l11 -1l21 -3l3 6z" />
- <glyph glyph-name="ion-ios7-cog" unicode="&#xf17c;" horiz-adv-x="384"
-d="M384 175l-33 -8c-1 -5 -2 -10 -3 -14l27 -20l-12 -30l-34 5c-2 -4 -5 -7 -8 -11l17 -29l-22 -23l-30 17c-3 -2 -6 -5 -10 -7l5 -34l-29 -12l-21 27c-4 -1 -9 -2 -14 -3l-8 -33h-32l-9 33c-4 1 -9 2 -13 3l-21 -28l-29 12l4 34c-4 2 -7 5 -11 8l-30 -18l-23 22l18 31
-c-3 4 -5 7 -7 11l-35 -5l-12 29l28 22c-1 4 -1 8 -2 12l-35 9v32l35 9c1 4 1 8 2 12l-29 22l12 30l36 -5c2 4 5 7 7 10l-19 32l22 22l32 -19c4 3 8 6 12 8l-5 35l29 13l22 -29c4 1 8 1 12 2l9 35h32l9 -35c4 -1 8 -1 12 -2l22 28l29 -12l-5 -35c4 -2 7 -5 11 -8l30 18
-l22 -23l-17 -29c3 -4 5 -7 7 -11l35 5l12 -30l-28 -21c1 -4 2 -9 3 -13l33 -9v-32zM321 185c0 4 -1 8 -1 12c-1 13 -3 25 -7 37c-1 4 -3 8 -5 12c-5 11 -12 22 -21 31l-4 4l-5 5c-10 9 -19 16 -31 21c-4 2 -8 3 -11 4c0 0 -7 2 -11 3l-8 2c-6 1 -13 3 -19 3h-11
-c-13 -1 -26 -4 -38 -8c-4 -1 -7 -3 -11 -5c-11 -5 -22 -12 -31 -20c-2 -1 -4 -4 -5 -5s-3 -2 -4 -4c-9 -10 -16 -20 -21 -32c-2 -3 -4 -7 -5 -11c-4 -12 -6 -24 -7 -37v-12c0 -6 1 -12 2 -18c0 0 1 -3 3 -10s3 -10 3 -10c1 -3 3 -7 4 -10c5 -12 12 -22 21 -32
-c2 -2 2 -3 4 -5c1 -1 3 -2 4 -3c9 -9 20 -16 32 -22c4 -2 7 -3 11 -4c12 -4 24 -7 37 -8h13c12 1 25 3 37 7c3 1 7 3 11 5c10 5 20 11 29 19c0 0 3 2 7 6s6 7 6 7c8 9 14 18 19 29c2 5 4 8 5 12c4 12 7 24 8 37zM214 301l-28 -103l-103 -28c-1 5 -2 11 -2 16v10
-c0 11 3 22 7 33l3 9c5 10 11 19 19 28l4 4l4 4c8 8 17 13 27 18c3 2 7 3 10 4c11 4 22 7 33 7h10c5 0 11 -1 16 -2zM87 154l103 28l76 -76c-8 -6 -17 -13 -26 -17c-3 -1 -7 -2 -10 -3c-10 -4 -21 -7 -32 -7h-11c-11 0 -22 3 -32 7c-3 1 -8 2 -11 4c-10 5 -19 10 -27 18
-c-1 1 -2 3 -3 4l-4 4c-8 8 -14 18 -19 28c-2 3 -3 6 -4 9v1zM298 229c4 -10 6 -21 7 -32v-11c-1 -11 -3 -23 -7 -33c-1 -4 -2 -7 -4 -11c-4 -9 -10 -17 -17 -25l-76 76l28 104l1 -1c3 -1 7 -2 10 -3c10 -5 20 -11 28 -19l4 -4l3 -3c8 -8 14 -18 19 -28c2 -3 3 -7 4 -10z" />
- <glyph glyph-name="ion-ios7-compose-outline" unicode="&#xf17d;" horiz-adv-x="368"
-d="M288 48v192l16 16v-224h-304v288h240l-16 -16h-208v-256h272zM158 164l171 171l11 -11l-180 -180h-32v32l180 180l11 -11l-171 -171zM364 368c2 -3 4 -6 4 -10s-2 -7 -4 -10l-12 -12l-21 21l-11 11v0l12 12c3 2 6 4 10 4s7 -2 10 -4z" />
- <glyph glyph-name="ion-ios7-compose" unicode="&#xf17e;" horiz-adv-x="368"
-d="M128 176l180 180l32 -32l-180 -180h-32v32zM364 368c2 -3 4 -6 4 -10s-2 -7 -4 -10l-12 -12l-21 21l-11 11v0l12 12c3 2 6 4 10 4s7 -2 10 -4zM176 128l128 129v-3v-222h-304v288h240v0v0l-128 -128v-64h64z" />
- <glyph glyph-name="ion-ios7-contact-outline" unicode="&#xf17f;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-cog-outline" unicode="&#xf411;" horiz-adv-x="384"
+d="M384 175l-33 -8l-3 -14l27 -20l-12 -30l-34 5l-8 -11l17 -29l-23 -23l-29 17l-10 -7l5 -34l-29 -12l-21 27l-14 -3l-8 -33h-32l-9 33l-13 3l-21 -28l-29 12l4 34l-11 8l-30 -19l-23 23l18 31l-7 11l-35 -5l-12 29l28 22l-2 12l-35 9v32l35 9l2 12l-29 22l12 30l36 -5
+l7 10l-19 32l22 22l32 -19l11 8l-4 35l29 13l22 -29l12 2l9 35h32l9 -35l12 -2l22 28l29 -12l-5 -35l11 -8l30 18l22 -23l-17 -30l7 -10l35 5l12 -30l-28 -21l3 -13l33 -9v-32zM356 127l-26 20l6 33l32 8v7l-32 8l-6 33l26 19l-3 7l-32 -5l-19 27l17 28l-5 6l-28 -17l-28 18
+l5 34l-6 2l-20 -26l-32 6l-8 33h-7l-9 -33l-32 -6l-20 27l-7 -3l5 -34l-28 -18l-9 6l-21 12l-5 -5l18 -30l-18 -27l-33 5l-3 -7l27 -20l-6 -32l-33 -8v-7l33 -9l6 -32l-27 -20l3 -6l33 4l18 -27l-17 -29l5 -6l29 18l28 -18l-5 -33l7 -3l19 27l33 -7l8 -31h8l7 31l33 7
+l20 -26l7 3l-5 32l26 18l28 -16l5 5l-16 27l19 28l32 -4zM192 320c71 0 128 -57 128 -128s-57 -128 -128 -128s-128 57 -128 128s57 128 128 128zM80 192c0 -7 1 -15 2 -22l104 28l28 104c-7 1 -15 2 -22 2c-30 0 -58 -12 -79 -33s-33 -49 -33 -79zM192 80c27 0 53 10 73 27
+l-75 75l-104 -28c6 -15 15 -29 27 -41c21 -21 49 -33 79 -33zM276 118c18 20 28 47 28 74c0 30 -12 58 -33 79c-12 12 -26 22 -42 27l-28 -105z" />
+ <glyph glyph-name="ion-ios-cog" unicode="&#xf412;" horiz-adv-x="384"
+d="M229 298c16 -5 30 -15 42 -27c21 -21 33 -49 33 -79c0 -27 -10 -54 -28 -74l-75 75zM214 302l-28 -104l-104 -28c-1 7 -2 15 -2 22c0 30 12 58 33 79s49 33 79 33c7 0 15 -1 22 -2zM86 154l104 28l75 -75c-20 -17 -46 -27 -73 -27c-30 0 -58 12 -79 33
+c-12 12 -21 26 -27 41zM384 175l-33 -8l-3 -14l27 -20l-12 -30l-34 5l-8 -11l17 -29l-23 -23l-29 17l-10 -7l5 -34l-29 -12l-21 27l-14 -3l-8 -33h-32l-9 33l-13 3l-21 -28l-29 12l4 34l-11 8l-30 -19l-23 23l18 31l-7 11l-35 -5l-12 29l28 22l-2 12l-35 9v32l35 9l2 12
+l-29 22l12 30l36 -5l7 10l-19 32l22 22l32 -19l11 8l-4 35l29 13l22 -29l12 2l9 35h32l9 -35l12 -2l22 28l29 -12l-5 -35l11 -8l30 18l22 -23l-17 -30l7 -10l35 5l12 -30l-28 -21l3 -13l33 -9v-32zM192 64c71 0 128 57 128 128s-57 128 -128 128s-128 -57 -128 -128
+s57 -128 128 -128z" />
+ <glyph glyph-name="ion-ios-color-filter-outline" unicode="&#xf413;" horiz-adv-x="384"
+d="M302 236c47 -13 82 -57 82 -108c0 -62 -50 -112 -112 -112c-31 0 -60 13 -80 34c-20 -21 -49 -34 -80 -34c-62 0 -112 50 -112 112c0 51 35 95 82 108c-1 7 -2 13 -2 20c0 62 50 112 112 112s112 -50 112 -112c0 -7 -1 -13 -2 -20zM96 256c0 -6 0 -12 1 -17
+c5 1 10 1 15 1c31 0 60 -13 80 -34c20 21 49 34 80 34c5 0 10 0 15 -1c1 5 1 11 1 17c0 53 -43 96 -96 96s-96 -43 -96 -96zM208 128c0 6 0 12 -1 17c-5 -1 -10 -1 -15 -1s-10 0 -15 1c-1 -5 -1 -11 -1 -17c0 -20 6 -38 16 -53c10 15 16 33 16 53zM192 160c3 0 7 1 10 1
+c-3 7 -6 14 -10 20c-4 -6 -7 -13 -10 -20c3 0 7 -1 10 -1zM166 164c4 11 9 21 16 30c-18 18 -43 30 -70 30c-3 0 -7 -1 -10 -1c10 -29 34 -51 64 -59zM202 194c7 -9 12 -19 16 -30c30 8 54 30 64 59c-3 0 -7 1 -10 1c-27 0 -52 -12 -70 -30zM112 32c27 0 52 12 70 30
+c-14 19 -22 41 -22 66c0 7 1 13 2 20c-36 10 -64 37 -76 72c-40 -11 -70 -48 -70 -92c0 -53 43 -96 96 -96zM272 32c53 0 96 43 96 96c0 44 -30 81 -70 92c-12 -35 -40 -62 -76 -72c1 -7 2 -13 2 -20c0 -25 -8 -47 -22 -66c18 -18 43 -30 70 -30z" />
+ <glyph glyph-name="ion-ios-color-filter" unicode="&#xf414;" horiz-adv-x="384"
+d="M302 236c47 -13 82 -57 82 -108c0 -62 -50 -112 -112 -112c-31 0 -60 13 -80 34c-20 -21 -49 -34 -80 -34c-62 0 -112 50 -112 112c0 51 35 95 82 108c-1 7 -2 13 -2 20c0 62 50 112 112 112s112 -50 112 -112c0 -7 -1 -13 -2 -20zM192 53l1 -2c3 3 6 7 9 11
+c14 19 22 41 22 66c0 7 -1 13 -2 20c36 10 64 37 76 72c2 5 3 10 4 15c-1 0 -2 1 -3 1v1c-4 1 -8 1 -12 2c-5 1 -10 1 -15 1c-31 0 -60 -13 -80 -34c-20 21 -49 34 -80 34c-5 0 -10 0 -15 -1c-4 -1 -8 -1 -12 -2v-1c-1 0 -2 -1 -3 -1c1 -5 2 -10 4 -15c12 -35 40 -62 76 -72
+c-1 -7 -2 -13 -2 -20c0 -25 8 -47 22 -66c3 -4 6 -8 9 -11zM207 145c1 -5 1 -11 1 -17c0 -20 -6 -38 -16 -53c-10 15 -16 33 -16 53c0 6 0 12 1 17c5 -1 10 -1 15 -1s10 0 15 1zM282 223c-10 -29 -34 -51 -64 -59c-4 11 -9 21 -16 30c18 18 43 30 70 30c3 0 7 -1 10 -1z
+M202 161c-3 0 -7 -1 -10 -1s-7 1 -10 1c3 7 6 14 10 20c4 -6 7 -13 10 -20zM112 224c27 0 52 -12 70 -30c-7 -9 -12 -19 -16 -30c-30 8 -54 30 -64 59c3 0 7 1 10 1z" />
+ <glyph glyph-name="ion-ios-color-wand-outline" unicode="&#xf415;" horiz-adv-x="384"
+d="M128 298l256 -256l-34 -34l-256 256zM149 232l201 -201l11 11l-201 202zM120 344v40h16v-40h-16zM120 140v40h16v-40h-16zM216 256v16h40v-16h-40zM0 256v16h40v-16h-40zM47 354l29 -29l-12 -11l-28 28zM76 198l-29 -28l-11 11l28 28zM220 342l-28 -28l-12 11l29 29z" />
+ <glyph glyph-name="ion-ios-color-wand" unicode="&#xf416;" horiz-adv-x="396"
+d="M140 289l256 -257l-34 -34l-256 257zM124 322v64h32v-64h-32zM124 118v64h32v-64h-32zM216 238v32h64v-32h-64zM246 336l-45 -45l-23 22l45 46zM34 336l23 23l45 -46l-23 -22zM34 169l45 45l23 -22l-45 -46zM0 238v32h64v-32h-64z" />
+ <glyph glyph-name="ion-ios-compose-outline" unicode="&#xf417;" horiz-adv-x="384"
+d="M304 32v208l16 16v-240h-320v304h256l-16 -16h-224v-272h288zM174 164l171 171l11 -11l-180 -180h-32v32l180 180l11 -11l-171 -171zM380 368c2 -3 4 -6 4 -10s-2 -7 -4 -10l-12 -12l-21 21l-11 11v0l12 12c3 2 6 4 10 4s7 -2 10 -4z" />
+ <glyph glyph-name="ion-ios-compose" unicode="&#xf418;" horiz-adv-x="384"
+d="M192 128l128 128v-240h-320v304h256l-128 -128v-64h64zM324 356l32 -32l-180 -180h-32v32zM380 368c2 -3 4 -6 4 -10s-2 -7 -4 -10l-12 -12l-21 21l-11 11v0l12 12c3 2 6 4 10 4s7 -2 10 -4z" />
+ <glyph glyph-name="ion-ios-contact-outline" unicode="&#xf419;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 383c-105 0 -191 -86 -191 -191c0 -47 17 -89 45 -122c18 8 62 24 90 32c2 1 3 0 3 10c0 11 -1 18 -4 24c-4 8 -7 20 -9 31c-4 5 -10 15 -14 33c-3 16 -1 22 1 28v2
c1 4 0 23 -3 38c-2 10 1 34 15 52c9 12 27 26 58 28h18c32 -2 49 -16 58 -28c14 -18 17 -42 15 -52c-3 -15 -4 -34 -3 -38c0 0 1 -1 1 -2c2 -6 3 -12 0 -28c-4 -18 -10 -27 -14 -32c-2 -11 -5 -24 -9 -32c-3 -7 -6 -15 -6 -23c0 -10 0 -10 2 -11c27 -8 73 -24 93 -32
c28 33 45 76 45 122c0 105 -86 191 -191 191z" />
- <glyph glyph-name="ion-ios7-contact" unicode="&#xf180;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-contact" unicode="&#xf41a;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c59 0 111 27 146 69c-20 8 -66 24 -93 32c-2 1 -3 1 -3 11c0 8 4 16 7 23c4 8 7 21 9 32c4 5 10 14 14 32c3 16 2 22 0 28c0 0 -1 1 -1 2c-1 4 0 23 3 38c2 10 -1 34 -15 52
c-9 12 -26 26 -58 28h-18c-31 -2 -49 -16 -58 -28c-14 -18 -17 -42 -15 -52c3 -15 4 -34 3 -38v-2c-2 -6 -4 -12 -1 -28c4 -18 10 -28 14 -33c2 -11 5 -23 9 -31c3 -6 4 -13 4 -24c0 -10 -1 -9 -3 -10c-28 -8 -72 -24 -90 -32c35 -42 87 -69 146 -69z" />
- <glyph glyph-name="ion-ios7-copy-outline" unicode="&#xf181;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-copy-outline" unicode="&#xf41b;" horiz-adv-x="288"
d="M192 352v-64h64v-16h-80v80h16zM213 384l75 -75v-261h-48v-48h-240v336h48v48h165zM224 16v32h-176v272h-32v-304h208zM272 64v238l-65 66h-143v-304h208z" />
- <glyph glyph-name="ion-ios7-copy" unicode="&#xf182;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-copy" unicode="&#xf41c;" horiz-adv-x="288"
d="M32 32h16h192v-32h-240v336h32v-288v-16zM213 384l75 -75v-261h-48h-192v288v48h165zM256 272v16h-64v64h-16v-80h80z" />
- <glyph glyph-name="ion-ios7-download-outline" unicode="&#xf183;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-crop-strong" unicode="&#xf41d;" horiz-adv-x="384"
+d="M64 336v48h32v-48h-32zM96 96h176v-32h-208v208h32v-176zM336 64v32h48v-32h-48zM0 320h320v-320h-32v288h-288v32z" />
+ <glyph glyph-name="ion-ios-crop" unicode="&#xf41e;" horiz-adv-x="384"
+d="M64 336v48h16v-48h-16zM80 80h208v-16h-224v224h16v-208zM336 64v16h48v-16h-48zM0 320h320v-320h-16v304h-304v16z" />
+ <glyph glyph-name="ion-ios-download-outline" unicode="&#xf41f;" horiz-adv-x="320"
d="M192 304h128v-304h-320v304h128v-16h-112v-272h288v272h-112v16zM97 196l55 -55v243h16v-243l55 55l11 -12l-74 -74l-74 74z" />
- <glyph glyph-name="ion-ios7-download" unicode="&#xf184;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-download" unicode="&#xf420;" horiz-adv-x="320"
d="M168 304h152v-304h-320v304h152v-163l-55 55l-11 -12l74 -74l74 74l-11 12l-55 -55v163zM152 304v80h16v-80h-16z" />
- <glyph glyph-name="ion-ios7-drag" unicode="&#xf185;" horiz-adv-x="352"
+ <glyph glyph-name="ion-ios-drag" unicode="&#xf421;" horiz-adv-x="352"
d="M0 128v16h352v-16h-352zM0 184v16h352v-16h-352zM0 240v16h352v-16h-352z" />
- <glyph glyph-name="ion-ios7-email-outline" unicode="&#xf186;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-email-outline" unicode="&#xf422;" horiz-adv-x="384"
d="M0 320h384v-256h-384v256zM192 180l163 124h-326zM16 80h352v214l-115 -88l68 -77l-2 -2l-79 70l-48 -37l-48 37l-79 -70l-2 2l68 77l-115 88v-214z" />
- <glyph glyph-name="ion-ios7-email" unicode="&#xf187;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-email" unicode="&#xf423;" horiz-adv-x="384"
d="M384 64h-384v242l131 -100l-68 -77l2 -2l79 70l48 -37l48 37l79 -70l2 2l-68 77l131 100v-242zM376 320l-184 -140l-184 140h368z" />
- <glyph glyph-name="ion-ios7-expand" unicode="&#xf30d;" horiz-adv-x="364"
-d="M214 152l8 8l92 -92l50 50v-108h-108l50 50zM150 232l-8 -8l-92 92l-50 -50v108h108l-50 -50z" />
- <glyph glyph-name="ion-ios7-eye-outline" unicode="&#xf188;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-eye-outline" unicode="&#xf424;" horiz-adv-x="384"
d="M383 192l1 -1l-6 -6c-21 -21 -47 -48 -78 -69c-36 -24 -72 -36 -108 -36c-83 0 -130 49 -185 105l-7 7l1 1c39 40 67 64 94 81c32 20 63 30 97 30c83 0 146 -60 191 -112zM192 288c-62 0 -111 -36 -170 -96c24 -24 48 -50 76 -68c30 -20 60 -28 94 -28
c75 0 133 56 171 95c-26 29 -50 50 -74 66c-32 21 -64 31 -97 31zM192 112c-44 0 -80 36 -80 80s36 80 80 80s80 -36 80 -80s-36 -80 -80 -80zM192 256c-35 0 -64 -29 -64 -64s29 -64 64 -64s64 29 64 64s-29 64 -64 64zM224 192h16v0c0 -26 -22 -48 -48 -48s-48 21 -48 48
s22 48 48 48v-16c-16 0 -32 -13 -32 -31s15 -33 32 -33s32 14 32 32v0z" />
- <glyph glyph-name="ion-ios7-eye" unicode="&#xf189;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-eye" unicode="&#xf425;" horiz-adv-x="384"
d="M383 192l1 -1l-6 -6c-21 -21 -47 -48 -78 -69c-36 -24 -72 -36 -108 -36c-83 0 -130 49 -185 105l-7 7l1 1c39 40 67 64 94 81c32 20 63 30 97 30c83 0 146 -60 191 -112zM192 112c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80zM186 221
c0 -19 16 -35 35 -35c7 0 14 2 19 6v0c0 -27 -22 -48 -48 -48s-48 21 -48 48s22 48 48 48c-4 -5 -6 -12 -6 -19z" />
- <glyph glyph-name="ion-ios7-fastforward-outline" unicode="&#xf18a;"
+ <glyph glyph-name="ion-ios-fastforward-outline" unicode="&#xf426;"
d="M16 293v-202l184 101zM240 292v0v-78v-27v-95l176 100zM224 320v0l224 -128l-224 -128v123l-224 -123v256l224 -123v123z" />
- <glyph glyph-name="ion-ios7-fastforward" unicode="&#xf18b;"
+ <glyph glyph-name="ion-ios-fastforward" unicode="&#xf427;"
d="M224 320v0l224 -128l-224 -128v123l-224 -123v256l224 -123v123z" />
- <glyph glyph-name="ion-ios7-filing-outline" unicode="&#xf18c;" horiz-adv-x="352"
+ <glyph glyph-name="ion-ios-filing-outline" unicode="&#xf428;" horiz-adv-x="352"
d="M288 320l64 -96v-160h-176h-176v160l64 96h224zM333 224l-45 68v-68h45zM80 304v-80h48c0 -26 22 -48 48 -48s48 22 48 48h48v80h-192zM64 292l-45 -68h45v68zM336 80v128h-98c-7 -28 -32 -48 -62 -48s-55 20 -62 48h-98v-128h160h160z" />
- <glyph glyph-name="ion-ios7-filing" unicode="&#xf18d;" horiz-adv-x="352"
+ <glyph glyph-name="ion-ios-filing" unicode="&#xf429;" horiz-adv-x="352"
d="M176 160c30 0 55 20 62 48h114v-144h-176h-176v144h114c7 -28 32 -48 62 -48zM64 224h-7h-57l64 96v0v-80h16v80h192v-80h16v80v0l64 -96h-56h-8h-16h-8h-40c0 -26 -22 -48 -48 -48s-48 22 -48 48h-39h-9h-16z" />
- <glyph glyph-name="ion-ios7-film-outline" unicode="&#xf18e;" horiz-adv-x="384"
-d="M0 349v35h32v-35h-32zM303 366h-222v-142h222v142zM320 384v0v-177h-256v177h256zM303 160h-222v-143h222v143zM320 178v0v-178h-256v178h256zM0 279v35h32v-35h-32zM0 210v34h32v-34h-32zM0 140v34h32v-34h-32zM0 70v35h32v-35h-32zM0 0v35h32v-35h-32zM352 349v35h32
-v-35h-32zM352 279v35h32v-35h-32zM352 210v34h32v-34h-32zM352 140v34h32v-34h-32zM352 70v35h32v-35h-32zM352 0v35h32v-35h-32z" />
- <glyph glyph-name="ion-ios7-film" unicode="&#xf18f;" horiz-adv-x="384"
-d="M0 349v35h32v-35h-32zM320 384v0v-177h-256v177h256zM320 178v0v-178h-256v178h256zM0 279v35h32v-35h-32zM0 210v34h32v-34h-32zM0 140v34h32v-34h-32zM0 70v35h32v-35h-32zM0 0v35h32v-35h-32zM352 349v35h32v-35h-32zM352 279v35h32v-35h-32zM352 210v34h32v-34h-32z
-M352 140v34h32v-34h-32zM352 70v35h32v-35h-32zM352 0v35h32v-35h-32z" />
- <glyph glyph-name="ion-ios7-flag-outline" unicode="&#xf190;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-film-outline" unicode="&#xf42a;" horiz-adv-x="400"
+d="M0 360h400v-336h-400v336zM72 40v48h-56v-48h56zM72 104v48h-56v-48h56zM72 168v48h-56v-48h56zM72 232v48h-56v-48h56zM72 296v48h-56v-48h56zM312 40v144h-224v-144h224zM312 200v144h-224v-144h224zM384 40v48h-56v-48h56zM384 104v48h-56v-48h56zM384 168v48h-56v-48
+h56zM384 232v48h-56v-48h56zM384 296v48h-56v-48h56z" />
+ <glyph glyph-name="ion-ios-film" unicode="&#xf42b;" horiz-adv-x="400"
+d="M0 360h400v-336h-400v336zM72 40v48h-56v-48h56zM72 104v48h-56v-48h56zM72 168v48h-56v-48h56zM72 232v48h-56v-48h56zM72 296v48h-56v-48h56zM312 184v16h-224v-16h224zM384 40v48h-56v-48h56zM384 104v48h-56v-48h56zM384 168v48h-56v-48h56zM384 232v48h-56v-48h56z
+M384 296v48h-56v-48h56z" />
+ <glyph glyph-name="ion-ios-flag-outline" unicode="&#xf42c;" horiz-adv-x="256"
d="M240 336c6 1 11 1 16 2v-16v-157c-5 -1 -10 -1 -16 -2c-11 -1 -24 -3 -39 -3c-25 0 -47 4 -69 9s-42 13 -64 13c-30 0 -46 -5 -52 -7v-143h-16v142v162v2l3 3c2 1 18 11 65 11c24 0 45 -4 67 -9c21 -4 42 -11 65 -11c15 0 29 3 40 4zM240 179v0v141c-11 -1 -25 -4 -40 -4
c-25 0 -46 6 -68 11s-42 9 -64 9c-30 0 -46 -5 -52 -7v-137c10 3 26 6 52 6c24 0 45 -8 67 -13c21 -4 43 -9 66 -9c15 0 28 2 39 3z" />
- <glyph glyph-name="ion-ios7-flag" unicode="&#xf191;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-flag" unicode="&#xf42d;" horiz-adv-x="256"
d="M240 336c6 1 11 1 16 2v-16v-157c-5 -1 -10 -1 -16 -2c-11 -1 -24 -3 -39 -3c-25 0 -47 4 -69 9s-42 13 -64 13c-30 0 -46 -5 -52 -7v-143h-16v142v162v2l3 3c2 1 18 11 65 11c24 0 45 -4 67 -9c21 -4 42 -11 65 -11c15 0 29 3 40 4z" />
- <glyph glyph-name="ion-ios7-folder-outline" unicode="&#xf192;" horiz-adv-x="320"
-d="M294 304c16 0 26 -9 26 -25v-202c0 -16 -10 -29 -26 -29h-266c-16 0 -28 13 -28 29v235c0 15 12 24 28 24h60c6 0 14 -5 21 -13c8 -9 14 -19 19 -19h166zM28 320c-2 0 -12 1 -12 -8v-56h288v23c0 7 -3 9 -10 9h-166c-14 0 -18 10 -30 24c-6 7 -11 8 -15 8h-11h-44z
-M294 64c7 0 10 7 10 13v163h-288v-163c0 -7 6 -13 12 -13h266z" />
- <glyph glyph-name="ion-ios7-folder" unicode="&#xf193;" horiz-adv-x="320"
-d="M0 77v163h320v-163c0 -16 -10 -29 -26 -29h-266c-16 0 -28 13 -28 29zM320 279v-23h-320v56c0 15 12 24 28 24h60c6 0 14 -5 21 -13c8 -9 14 -19 19 -19h166c16 0 26 -9 26 -25z" />
- <glyph glyph-name="ion-ios7-football-outline" unicode="&#xf328;"
-d="M152 208l72 48l72 -48l-24 -80h-96zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM388 64c11 14 21 30 28 47c9 22 15 46 16 70l-13 -10l-42 59v78l21 -3c-8 12 -17 24 -27 34c-19 19 -41 35 -66 45c-7 3 -13 5 -20 7
-l10 -25l-71 -22l-71 22l10 25c-7 -2 -13 -4 -20 -7c-25 -10 -47 -26 -66 -45c-10 -10 -19 -22 -27 -34l21 3v-78l-42 -59l-13 10c1 -24 7 -48 16 -70c7 -17 17 -33 28 -47l1 13l69 -24l44 -61l-2 -2c17 -4 34 -6 52 -6s35 2 52 6l-2 2l44 61l69 24z" />
- <glyph glyph-name="ion-ios7-football" unicode="&#xf329;"
-d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM432 181v11c0 28 -5 55 -16 81c-5 11 -11 22 -18 32l-21 3v-78l42 -59zM176 128h96l24 80l-72 48l-72 -48zM285 391c-20 6 -40 9 -61 9s-41 -3 -61 -9l-10 -25l71 -22l71 22z
-M32 273c-11 -26 -16 -53 -16 -81v-11l13 -10l42 59v78l-21 -3c-7 -10 -13 -21 -18 -32zM77 45c19 -19 41 -35 66 -45c10 -4 19 -7 29 -10l2 2l-44 61l-69 24l-1 -13c5 -7 11 -13 17 -19zM371 45c6 6 12 12 17 19l-1 13l-69 -24l-44 -61l2 -2c10 3 19 6 29 10
-c25 10 47 26 66 45z" />
- <glyph glyph-name="ion-ios7-gear-outline" unicode="&#xf194;" horiz-adv-x="384"
-d="M193 288c26 0 50 -10 68 -28s28 -42 28 -68s-10 -50 -28 -68s-42 -28 -68 -28s-50 10 -68 28s-28 42 -28 68s10 50 28 68s42 28 68 28zM193 112c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80zM360 232c14 0 24 -11 24 -25v-15v-15
-c0 -14 -10 -24 -24 -24h-15c-12 0 -23 -11 -23 -24c0 -6 3 -13 8 -17l10 -9c10 -10 10 -25 0 -35l-22 -22c-4 -4 -11 -7 -18 -7s-14 3 -18 7l-9 9c-5 5 -11 8 -17 8c-13 0 -23 -11 -23 -23v-15c0 -14 -11 -25 -25 -25h-30c-14 0 -25 11 -25 25v15c0 12 -10 23 -23 23
-c-6 0 -13 -3 -17 -8l-10 -9c-4 -4 -10 -7 -17 -7s-14 3 -18 7l-22 22c-10 10 -10 25 0 35l9 9c5 4 8 11 8 17c0 13 -11 23 -23 23h-15c-14 0 -25 11 -25 25v15v15c0 14 11 25 25 25h15c12 0 23 10 23 23c0 6 -3 13 -8 17l-9 9c-10 10 -10 25 0 35l22 22c4 4 11 7 18 7
-s13 -3 17 -7l10 -10c4 -5 11 -7 17 -7c13 0 23 11 23 23v15c0 14 11 25 25 25h30c14 0 24 -11 24 -25v-15c0 -12 11 -23 24 -23c6 0 13 3 17 8l9 9c4 4 11 7 18 7s14 -3 18 -7l22 -22c10 -10 10 -25 0 -35l-10 -9c-5 -4 -8 -11 -8 -17c0 -13 11 -23 23 -23h15zM368 192v15
-c0 4 -3 9 -8 9h-15c-10 0 -20 4 -27 12s-12 17 -12 27c0 11 5 21 13 28l9 9c2 2 3 5 3 7s-1 4 -3 6l-22 22c-2 1 -4 2 -6 2s-4 0 -6 -2l-10 -9c-8 -8 -17 -13 -28 -13c-10 0 -20 4 -28 11s-12 18 -12 28v15c0 5 -4 9 -8 9h-30c-4 0 -9 -4 -9 -9v-15c0 -10 -4 -21 -12 -28
-s-17 -11 -27 -11c-11 0 -21 4 -28 12l-10 10v0v0c-1 1 -4 2 -6 2s-4 0 -6 -2l-23 -22c-2 -2 -2 -5 -2 -6s0 -5 2 -7l9 -9c8 -8 13 -17 13 -28c0 -10 -4 -19 -11 -27s-18 -12 -28 -12h-15c-5 0 -9 -5 -9 -9v-15v-15c0 -4 4 -9 9 -9h15c10 0 21 -4 28 -12s11 -17 11 -27
-c0 -11 -4 -21 -12 -29l-9 -8c-3 -3 -3 -10 0 -13l22 -22v0v0c1 -1 4 -2 6 -2s4 0 6 2l10 9c7 8 17 13 28 13c10 0 19 -4 27 -11s12 -18 12 -28v-15c0 -5 4 -9 9 -9h30c5 0 9 4 9 9v15c0 10 4 21 12 28s17 11 27 11c11 0 21 -5 29 -13l9 -9c2 -2 4 -2 6 -2s4 0 6 2l23 22
-c3 3 3 10 0 13l-10 9c-8 7 -12 17 -12 28c0 10 4 20 11 28s18 12 28 12h15c5 0 7 4 7 8v15z" />
- <glyph glyph-name="ion-ios7-gear" unicode="&#xf195;" horiz-adv-x="384"
-d="M360 232c14 0 24 -11 24 -25v-15v-15c0 -14 -10 -25 -24 -25h-15c-12 0 -23 -10 -23 -23c0 -6 3 -13 8 -17l10 -9c10 -10 10 -25 0 -35l-23 -22c-4 -4 -10 -7 -17 -7s-14 3 -18 7l-9 9c-5 5 -11 8 -17 8c-13 0 -24 -11 -24 -23v-15c0 -14 -10 -25 -24 -25h-30
-c-14 0 -25 11 -25 25v15c0 12 -10 23 -23 23c-6 0 -13 -2 -17 -7l-10 -10c-4 -4 -10 -7 -17 -7s-14 3 -18 7l-22 22c-10 10 -10 25 0 35l9 9c5 4 8 11 8 17c0 13 -11 23 -23 23h-15c-14 0 -25 11 -25 25v15v15c0 14 11 25 25 25h15c12 0 23 10 23 23c0 6 -3 13 -8 17l-9 9
-c-10 10 -10 25 0 35l22 22c4 4 11 7 18 7s14 -3 18 -7l9 -10c4 -5 11 -7 17 -7c13 0 23 11 23 23v15c0 14 11 25 25 25h30c14 0 25 -11 25 -25v-15c0 -12 10 -23 23 -23c6 0 13 3 17 8l9 9c4 4 11 7 18 7s14 -3 18 -7l22 -22c10 -10 10 -25 0 -35l-10 -10
-c-5 -4 -8 -10 -8 -16c0 -13 11 -23 23 -23h15zM273 192v0c0 44 -36 80 -80 80s-80 -36 -80 -80v0v0c0 -44 36 -80 80 -80s80 36 80 80v0z" />
- <glyph glyph-name="ion-ios7-glasses-outline" unicode="&#xf196;"
+ <glyph glyph-name="ion-ios-flame-outline" unicode="&#xf42e;" horiz-adv-x="256"
+d="M96 416c87 -64 170 -179 159 -288c-13 -134 -104 -160 -127 -160s-127 40 -128 160c-1 146 122 143 96 288zM128 -24c0 0 40 36 40 80s-40 80 -40 80s-41 -36 -41 -80s41 -80 41 -80zM239 130c5 47 -10 99 -41 151c-22 36 -50 70 -83 99c0 -57 -24 -91 -49 -123
+c-26 -34 -50 -65 -50 -129c0 -25 5 -48 15 -68c8 -17 20 -32 35 -45c8 -7 16 -12 23 -16c-9 16 -18 35 -18 57c0 51 44 90 46 92l11 9l11 -9c2 -2 45 -41 45 -92c0 -23 -9 -44 -19 -60c7 4 13 8 20 14c14 12 25 27 34 44c11 21 17 47 20 76z" />
+ <glyph glyph-name="ion-ios-flame" unicode="&#xf42f;" horiz-adv-x="256"
+d="M96 416c87 -64 170 -179 159 -288c-13 -134 -104 -160 -127 -160s-127 40 -128 160c-1 146 122 143 96 288zM128 -24c0 0 40 36 40 80s-40 80 -40 80s-41 -36 -41 -80s41 -80 41 -80z" />
+ <glyph glyph-name="ion-ios-flask-outline" unicode="&#xf430;" horiz-adv-x="384"
+d="M373 78c8 -16 11 -32 11 -46c-1 -36 -27 -64 -63 -64h-256c-36 0 -64 27 -65 64c0 14 4 30 12 46l116 195v127h-16v16h16h16v-16v-16h48v-16h-48v-32h32v-16h-32v-32h48v-16h-48v-3l-2 -4l-15 -25h49v-16h-58l-92 -154c-13 -25 -14 -43 -2 -63c9 -14 23 -23 41 -23h256
+c17 0 33 8 41 22c5 8 6 17 6 26c0 12 -2 25 -9 38l-116 195l-3 4v131v16h16h16v-16h-16v-127zM44 73l72 119h153l72 -119c7 -11 10 -24 10 -33c-1 -24 -16 -40 -46 -40h-226c-30 0 -46 12 -46 40c0 9 4 22 11 33zM260 176h-135l-67 -111v0v0c-5 -8 -9 -19 -9 -25
+c0 -13 5 -17 6 -18c4 -4 13 -6 24 -6h226c10 0 18 3 23 7c4 4 7 10 7 18c0 6 -3 16 -8 24v0v0z" />
+ <glyph glyph-name="ion-ios-flask" unicode="&#xf431;" horiz-adv-x="384"
+d="M327 65v0c5 -8 8 -18 8 -24c0 -8 -3 -14 -7 -18c-5 -4 -13 -7 -23 -7h-226c-11 0 -20 2 -24 6c-1 1 -6 5 -6 18c0 6 4 17 9 25v0v0l67 111h135l67 -111v0zM373 78c8 -16 11 -32 11 -46c-1 -36 -27 -64 -63 -64h-256c-36 0 -64 27 -65 64c0 14 4 30 12 46l116 195v127h-16
+v16h160v-16h-16v-127zM144 384v-16h48v16h-48zM144 336v-16h32v16h-32zM144 288v-16h48v16h-48zM127 240l-9 -16h58v16h-49zM351 40c0 9 -3 22 -10 33l-72 119h-154l-71 -119c-7 -11 -11 -24 -11 -33c0 -28 16 -40 46 -40h226c30 0 45 16 46 40z" />
+ <glyph glyph-name="ion-ios-flower-outline" unicode="&#xf432;"
+d="M363 164c-29 0 -65 7 -93 14c-1 -3 -2 -6 -4 -9c25 -15 56 -36 76 -56c40 -40 53 -68 41 -80c-3 -3 -7 -4 -12 -4c-15 0 -38 15 -68 45c-20 20 -41 51 -56 76c-3 -2 -7 -3 -10 -4c7 -28 15 -64 15 -93c0 -56 -12 -85 -28 -85s-28 29 -28 85c0 29 8 65 15 93
+c-3 1 -7 2 -10 4c-15 -25 -36 -56 -56 -76c-30 -30 -53 -45 -68 -45c-5 0 -9 1 -12 4c-12 12 1 40 41 80c20 20 51 41 76 56c-2 3 -3 6 -4 9c-28 -7 -64 -14 -93 -14c-56 0 -85 12 -85 28s29 28 85 28c29 0 65 -8 93 -15c1 3 2 7 4 10c-25 15 -56 35 -76 55
+c-40 40 -53 68 -41 80c3 3 7 4 12 4c15 0 38 -14 68 -44c20 -20 41 -51 56 -76c3 2 7 3 10 4c-7 28 -15 64 -15 93c0 56 12 85 28 85s28 -29 28 -85c0 -29 -8 -65 -15 -93c3 -1 7 -2 10 -4c15 25 36 56 56 76c30 30 53 44 68 44c5 0 9 -1 12 -4c12 -12 -1 -40 -41 -80
+c-20 -20 -51 -40 -76 -55c2 -3 3 -7 4 -10c28 7 64 15 93 15c56 0 85 -12 85 -28s-29 -28 -85 -28zM288 193v-3c30 -7 56 -10 75 -10c21 0 39 2 52 5c10 3 14 6 16 7c-2 1 -6 4 -16 7c-13 3 -31 5 -52 5c-19 0 -45 -4 -75 -11zM314 299c-14 -14 -30 -35 -46 -61l2 -2
+c26 16 47 32 61 46c15 15 26 28 33 40c5 9 7 14 7 16c-4 0 -22 -4 -57 -39zM178 236l2 2c-16 26 -32 47 -46 61c-35 35 -53 39 -57 39c0 -2 2 -7 7 -16c7 -12 18 -25 33 -40c14 -14 35 -30 61 -46zM85 180c19 0 45 3 75 10v3c-30 7 -56 11 -75 11c-21 0 -39 -2 -52 -5
+c-10 -3 -14 -6 -16 -7c2 -1 5 -4 15 -7c13 -3 32 -5 53 -5zM134 85c14 14 30 35 46 61l-2 2c-26 -16 -47 -32 -61 -46c-15 -15 -26 -29 -33 -41c-5 -9 -7 -14 -7 -16c4 0 22 5 57 40zM270 148l-2 -2c16 -26 32 -47 46 -61c35 -35 53 -40 57 -40c0 2 -2 7 -7 16
+c-7 12 -18 26 -33 41c-14 14 -35 30 -61 46zM217 383c-3 -13 -5 -31 -5 -52c0 -19 4 -45 11 -75h2c7 30 11 56 11 75c0 21 -2 39 -5 52c-3 10 -6 14 -7 16c-1 -2 -4 -6 -7 -16zM231 0c3 13 5 32 5 53c0 19 -4 45 -11 75h-2c-7 -30 -11 -56 -11 -75c0 -21 2 -40 5 -53
+c3 -10 6 -13 7 -15c1 2 4 5 7 15zM224 160c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM313 42c10 -34 7 -53 -5 -58c-2 -1 -3 -1 -5 -1c-11 0 -25 13 -37 35c5 35 -2 76 -2 76s24 -34 49 -52zM302 -1c1 4 2 14 -3 34c-5 4 -10 9 -15 14
+c0 -9 0 -17 -1 -25c10 -16 16 -22 19 -23zM182 365c-6 -35 1 -75 1 -75s-27 35 -48 51c-10 35 -7 54 5 59c2 1 3 1 5 1c11 0 24 -12 37 -36zM164 337c0 9 0 17 1 25c-10 16 -16 21 -19 22c-1 -4 -2 -14 3 -34c5 -4 10 -8 15 -13zM50 149c35 -4 76 2 76 2s-34 -24 -51 -48
+c-12 -4 -26 -6 -35 -6c-13 0 -21 4 -24 11c-5 11 7 25 34 41zM66 117c4 5 8 10 13 15c-9 0 -17 0 -25 1c-16 -10 -21 -16 -22 -19c1 0 4 -1 8 -1c7 0 16 1 26 4zM432 276c5 -11 -7 -26 -34 -42c-35 5 -76 -2 -76 -2s33 25 51 49c13 4 26 5 35 5c13 0 21 -3 24 -10zM394 250
+c16 10 21 16 22 19c-1 0 -4 1 -8 1c-7 0 -16 -1 -26 -4c-4 -5 -8 -9 -13 -14c9 0 17 -1 25 -2zM131 39c31 24 53 55 53 55s-7 -39 -3 -71c-15 -26 -28 -39 -39 -39c-2 0 -4 0 -6 1c-11 5 -13 24 -5 54zM143 1c4 2 12 8 22 26c0 6 -1 13 -1 20c-6 -6 -13 -12 -19 -17
+c-4 -18 -3 -26 -2 -29zM312 398c11 -5 13 -22 5 -54c-29 -21 -53 -55 -53 -55s8 48 3 71c13 25 28 39 39 39c2 0 4 0 6 -1zM303 353c5 18 3 27 2 30c-4 -2 -12 -8 -22 -26c0 -6 1 -14 1 -21c6 6 13 12 19 17zM71 285c18 -24 55 -53 55 -53s-40 7 -70 3c-28 15 -43 32 -38 44
+c3 7 10 11 22 11c8 0 21 -1 31 -5zM33 273c2 -4 8 -12 26 -22c6 0 13 1 20 1c-6 6 -12 12 -17 18c-8 2 -16 4 -22 4c-4 0 -6 -1 -7 -1zM392 149c30 -17 43 -33 38 -45c-3 -7 -10 -10 -22 -10c-8 0 -19 1 -31 5c-20 27 -55 52 -55 52s45 -8 70 -2zM408 110c4 0 6 1 7 1
+c-2 4 -8 12 -26 22c-6 0 -13 -1 -20 -1c6 -6 12 -13 17 -19c8 -2 16 -3 22 -3z" />
+ <glyph glyph-name="ion-ios-flower" unicode="&#xf433;"
+d="M363 220c56 0 85 -12 85 -28s-29 -28 -85 -28c-29 0 -65 7 -93 14c-1 -3 -2 -6 -4 -9c25 -15 56 -36 76 -56c40 -40 53 -68 41 -80s-40 1 -80 41c-20 20 -41 51 -56 76c-3 -2 -7 -3 -10 -4c7 -28 15 -64 15 -93c0 -56 -12 -85 -28 -85s-28 29 -28 85c0 29 8 65 15 93
+c-3 1 -7 2 -10 4c-15 -25 -36 -56 -56 -76c-40 -40 -68 -53 -80 -41s1 40 41 80c20 20 51 41 76 56c-2 3 -3 6 -4 9c-28 -7 -64 -14 -93 -14c-56 0 -85 12 -85 28s29 28 85 28c29 0 65 -8 93 -15c1 3 2 7 4 10c-25 15 -56 35 -76 55c-40 40 -53 68 -41 80s40 0 80 -40
+c20 -20 41 -51 56 -76c3 2 6 3 9 4c-7 28 -14 64 -14 93c0 56 12 85 28 85s28 -29 28 -85c0 -29 -7 -65 -14 -93c3 -1 6 -2 9 -4c15 25 36 56 56 76c40 40 68 52 80 40s-1 -40 -41 -80c-20 -20 -51 -40 -76 -55c2 -3 3 -7 4 -10c28 7 64 15 93 15zM264 94c0 0 24 -34 49 -52
+c10 -34 7 -53 -5 -58c-2 -1 -3 -1 -5 -1c-11 0 -25 13 -37 35c5 35 -2 76 -2 76zM183 290c0 0 -27 35 -48 51c-10 35 -7 54 5 59c2 1 3 1 5 1c11 0 24 -12 37 -36c-6 -35 1 -75 1 -75zM126 151c0 0 -34 -24 -51 -48c-12 -4 -26 -6 -35 -6c-13 0 -21 4 -24 11
+c-5 11 7 25 34 41c35 -4 76 2 76 2zM322 232c0 0 33 25 51 49c13 4 26 5 35 5c13 0 21 -3 24 -10c5 -11 -7 -26 -34 -42c-35 5 -76 -2 -76 -2zM131 39c31 24 53 55 53 55s-7 -39 -3 -71c-15 -26 -28 -39 -39 -39c-2 0 -4 0 -6 1c-11 5 -13 24 -5 54zM317 344
+c-29 -21 -53 -55 -53 -55s8 48 3 71c13 25 28 39 39 39c2 0 4 0 6 -1c11 -5 13 -22 5 -54zM56 235c-28 15 -43 32 -38 44c3 7 10 11 22 11c8 0 21 -1 31 -5c18 -24 55 -53 55 -53s-40 7 -70 3zM392 149c30 -17 43 -33 38 -45c-3 -7 -10 -10 -22 -10c-8 0 -19 1 -31 5
+c-20 27 -55 52 -55 52s45 -8 70 -2z" />
+ <glyph glyph-name="ion-ios-folder-outline" unicode="&#xf434;"
+d="M425 352c13 0 23 -10 23 -23v-304c0 -14 -10 -25 -23 -25h-400c-13 0 -25 12 -25 25v336c0 13 11 23 25 23h112c8 0 12 -2 17 -7v0l23 -23c2 -2 3 -2 6 -2h242zM25 368c-4 0 -9 -3 -9 -7v-74c3 1 5 1 8 1h400c3 0 5 0 8 -1v42c0 4 -3 7 -7 7h-242c-7 0 -12 2 -17 7
+l-23 23c-2 2 -3 2 -6 2h-112zM432 25v239c0 4 -4 8 -8 8h-400c-4 0 -8 -4 -8 -8v-239c0 -4 5 -9 9 -9h400c4 0 7 5 7 9z" />
+ <glyph glyph-name="ion-ios-folder" unicode="&#xf435;"
+d="M440 272c4 0 8 -4 8 -8v-239c0 -14 -10 -25 -23 -25h-400c-13 0 -25 12 -25 25v239c0 4 4 8 8 8h432zM425 352c13 0 23 -10 23 -23v-42c-3 1 -5 1 -8 1h-432c-3 0 -5 0 -8 -1v74c0 13 11 23 25 23h112c8 0 12 -2 17 -7v0l23 -23c2 -2 3 -2 6 -2h242z" />
+ <glyph glyph-name="ion-ios-football-outline" unicode="&#xf436;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM249 6c3 1 5 1 8 2l24 64l-20 39v1h-106l-20 -39l25 -65c2 -1 5 -1 7 -2c12 -3 25 -5 38 -5c14 0 30 2 44 5zM41 284c-15 -27 -23 -57 -24 -89l43 37v0zM142 371
+c-36 -14 -68 -38 -90 -69l22 -64l5 -2l49 -23l71 60v58zM277 201l-70 58l-69 -58v-1l18 -72h104l18 72zM399 195c-1 32 -9 63 -24 90l-19 -53v0zM364 302c-22 31 -54 56 -90 69l-58 -40v-58l71 -60l54 24zM18 175c3 -34 15 -66 33 -92l70 -1l21 39l-20 77l-1 1l-49 22z
+M295 82l70 1c18 26 30 58 33 92l-54 46l-50 -23l-20 -77zM207 345l47 32c-15 4 -30 6 -46 6s-32 -2 -47 -6zM118 66l-54 1c20 -23 46 -42 75 -53l-20 50zM277 14c29 11 55 30 75 53l-56 -1l-2 -3z" />
+ <glyph glyph-name="ion-ios-football" unicode="&#xf437;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM249 6c3 1 5 1 8 2l24 64l-20 39v1h-106l-20 -39l25 -65c2 -1 5 -1 7 -2c12 -3 25 -5 38 -5c14 0 30 2 44 5zM142 371c-36 -14 -68 -38 -90 -69l22 -64l5 -2l49 -23l71 60v58z
+M364 302c-22 31 -54 56 -90 69l-58 -40v-58l71 -60l54 24zM18 175c3 -34 15 -66 33 -92l70 -1l21 39l-20 77l-1 1l-49 22zM295 82l70 1c18 26 30 58 33 92l-54 46l-50 -23l-20 -77z" />
+ <glyph glyph-name="ion-ios-game-controller-a-outline" unicode="&#xf438;"
+d="M163 208c3 0 5 -2 5 -5v-22c0 -3 -2 -5 -5 -5h-35v-35c0 -3 -3 -5 -6 -5h-21c-3 0 -5 2 -5 5v35h-35c-3 0 -5 3 -5 6v21c0 3 2 5 5 5h35v35c0 3 2 5 5 5h22c3 0 5 -2 5 -5v-35h35zM330 169c11 0 20 -8 20 -19s-9 -19 -20 -19s-19 8 -19 19s8 19 19 19zM288 211
+c11 0 19 -8 19 -19s-8 -19 -19 -19s-20 8 -20 19s9 19 20 19zM373 211c11 0 19 -8 19 -19s-8 -19 -19 -19s-20 8 -20 19s9 19 20 19zM330 253c11 0 20 -8 20 -19s-9 -20 -20 -20s-19 9 -19 20s8 19 19 19zM337 286h-226c-26 0 -49 -9 -67 -26s-28 -41 -28 -67s10 -51 28 -68
+s41 -27 67 -27h226c26 0 49 10 67 27s28 42 28 68s-10 50 -28 67s-41 26 -67 26zM337 302v0c61 0 111 -45 111 -109s-50 -111 -111 -111h-226c-61 0 -111 47 -111 111s50 109 111 109h226z" />
+ <glyph glyph-name="ion-ios-game-controller-a" unicode="&#xf439;"
+d="M337 302c61 0 111 -45 111 -109s-50 -111 -111 -111h-226c-61 0 -111 47 -111 111s50 109 111 109h226zM168 181v0v22c0 3 -2 5 -5 5h-35v35c0 3 -2 5 -5 5h-22c-3 0 -5 -2 -5 -5v-35h-35c-3 0 -5 -2 -5 -5v-21c0 -3 2 -6 5 -6h35v-35c0 -3 2 -5 5 -5h21c3 0 6 2 6 5v35
+h35c3 0 5 2 5 5zM288 173c11 0 19 8 19 19s-8 19 -19 19s-20 -8 -20 -19s9 -19 20 -19zM330 131c11 0 20 8 20 19s-9 19 -20 19s-19 -8 -19 -19s8 -19 19 -19zM330 214c11 0 20 9 20 20s-9 19 -20 19s-19 -8 -19 -19s8 -20 19 -20zM373 173c11 0 19 8 19 19s-8 19 -19 19
+s-20 -8 -20 -19s9 -19 20 -19z" />
+ <glyph glyph-name="ion-ios-game-controller-b-outline" unicode="&#xf43a;"
+d="M276 244c11 0 20 -9 20 -20s-9 -20 -20 -20s-20 9 -20 20s9 20 20 20zM320 200c11 0 20 -9 20 -20s-9 -20 -20 -20s-20 9 -20 20s9 20 20 20zM103 264c22 0 39 -18 39 -40s-17 -40 -39 -40s-39 18 -39 40s17 40 39 40zM103 205c11 0 19 8 19 19s-8 19 -19 19
+s-19 -8 -19 -19s8 -19 19 -19zM320 288c11 0 20 -9 20 -20s-9 -20 -20 -20s-20 9 -20 20s9 20 20 20zM364 244c11 0 20 -9 20 -20s-9 -20 -20 -20s-20 9 -20 20s9 20 20 20zM434 199c21 -88 18 -152 -7 -164c-4 -2 -9 -3 -13 -3c-22 0 -45 24 -68 52c-26 32 -32 33 -110 33
+h-24c-78 0 -84 -1 -110 -33c-23 -28 -46 -52 -68 -52c-4 0 -9 1 -13 3c-25 12 -28 76 -7 164s43 136 88 149c10 3 18 4 26 4c28 0 47 -15 96 -15s68 15 96 15c8 0 16 -1 26 -4c45 -13 67 -61 88 -149zM420 49c10 5 23 48 -1 146c-21 90 -43 128 -78 138c-8 2 -14 3 -21 3
+c-10 0 -19 -2 -30 -5c-16 -4 -36 -10 -66 -10s-50 6 -66 10c-11 3 -20 5 -30 5c-7 0 -13 -1 -21 -3c-35 -10 -57 -48 -78 -138c-24 -98 -11 -141 -1 -146c2 -1 4 -1 6 -1c6 0 14 4 23 12s19 18 32 34s24 28 44 34c17 5 38 5 79 5h24c41 0 62 0 79 -5c20 -6 31 -18 44 -34
+s23 -26 32 -34s17 -12 23 -12c2 0 4 0 6 1z" />
+ <glyph glyph-name="ion-ios-game-controller-b" unicode="&#xf43b;"
+d="M103 243c11 0 19 -8 19 -19s-8 -19 -19 -19s-19 8 -19 19s8 19 19 19zM434 199c21 -88 18 -152 -7 -164c-4 -2 -9 -3 -13 -3c-22 0 -45 24 -68 52c-26 32 -32 33 -110 33h-24c-78 0 -84 -1 -110 -33c-23 -28 -46 -52 -68 -52c-4 0 -9 1 -13 3c-25 12 -28 76 -7 164
+s43 136 88 149c10 3 18 4 26 4c28 0 47 -15 96 -15s68 15 96 15c8 0 16 -1 26 -4c45 -13 67 -61 88 -149zM103 184c22 0 39 18 39 40s-17 40 -39 40s-39 -18 -39 -40s17 -40 39 -40zM276 204c11 0 20 9 20 20s-9 20 -20 20s-20 -9 -20 -20s9 -20 20 -20zM320 160
+c11 0 20 9 20 20s-9 20 -20 20s-20 -9 -20 -20s9 -20 20 -20zM320 248c11 0 20 9 20 20s-9 20 -20 20s-20 -9 -20 -20s9 -20 20 -20zM364 204c11 0 20 9 20 20s-9 20 -20 20s-20 -9 -20 -20s9 -20 20 -20z" />
+ <glyph glyph-name="ion-ios-gear-outline" unicode="&#xf43c;" horiz-adv-x="384"
+d="M193 288c26 0 50 -10 68 -28s28 -42 28 -68s-10 -50 -28 -68s-42 -28 -68 -28s-50 10 -68 28s-28 42 -28 68s10 50 28 68s42 28 68 28zM193 112c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80zM138 365c-10 -3 -20 -7 -30 -12c2 -8 1 -16 0 -24
+c-2 -13 -8 -25 -18 -35c-12 -12 -29 -19 -46 -19c-4 0 -9 0 -13 1c-5 -10 -9 -20 -12 -30c7 -4 12 -10 17 -17c8 -11 12 -24 12 -37s-4 -26 -12 -37c-5 -7 -10 -13 -17 -17c3 -10 7 -20 12 -30c4 1 9 1 13 1c17 0 34 -7 46 -19c10 -10 16 -22 18 -35c1 -8 2 -16 0 -24
+c10 -5 20 -9 30 -12c4 7 10 12 17 17c11 8 24 12 37 12s26 -4 37 -12c7 -5 13 -10 17 -17c10 3 20 7 30 12c-2 8 -1 16 0 24c2 13 8 25 18 35c12 12 29 19 46 19c4 0 9 0 13 -1c5 10 9 20 12 30c-7 4 -12 10 -17 17c-8 11 -12 24 -12 37s4 26 12 37c5 7 10 13 17 17
+c-3 10 -7 20 -12 30c-4 -1 -9 -1 -13 -1c-17 0 -34 7 -46 19c-10 10 -16 22 -18 35c-1 8 -2 16 0 24c-10 5 -20 9 -30 12c-4 -7 -10 -12 -17 -17c-11 -8 -24 -12 -37 -12s-26 4 -37 12c-7 5 -13 10 -17 17zM238 384v0c20 -5 40 -13 57 -24c-8 -18 -5 -40 10 -55
+c10 -10 22 -14 35 -14c7 0 14 1 20 4c11 -17 19 -37 24 -57c-19 -7 -32 -25 -32 -46s14 -39 32 -46c-5 -20 -13 -40 -24 -57c-6 3 -13 4 -20 4c-13 0 -25 -4 -35 -14c-15 -15 -18 -37 -10 -55c-17 -11 -37 -19 -57 -24c-7 18 -25 32 -46 32s-39 -14 -46 -32
+c-20 5 -40 13 -57 24c8 18 5 40 -10 55c-10 10 -22 14 -35 14c-7 0 -14 -1 -20 -4c-11 17 -19 37 -24 57c18 7 32 25 32 46s-13 39 -32 46c5 20 13 40 24 57c6 -3 13 -4 20 -4c13 0 25 4 35 14c15 15 18 37 10 55c17 11 37 19 57 24c7 -19 25 -32 46 -32s39 13 46 32z" />
+ <glyph glyph-name="ion-ios-gear" unicode="&#xf43d;" horiz-adv-x="384"
+d="M352 192c0 -21 14 -39 32 -46c-5 -20 -13 -40 -24 -57c-6 3 -13 4 -20 4c-13 0 -25 -4 -35 -14c-15 -15 -18 -37 -10 -55c-17 -11 -37 -19 -57 -24c-7 18 -25 32 -46 32s-39 -14 -46 -32c-20 5 -40 13 -57 24c8 18 5 40 -10 55c-10 10 -22 14 -35 14c-7 0 -14 -1 -20 -4
+c-11 17 -19 37 -24 57c18 7 32 25 32 46s-13 39 -32 46c5 20 13 40 24 57c6 -3 13 -4 20 -4c13 0 25 4 35 14c15 15 18 37 10 55c17 11 37 19 57 24c7 -19 25 -32 46 -32s39 13 46 32c20 -5 40 -13 57 -24c-8 -18 -5 -40 10 -55c10 -10 22 -14 35 -14c7 0 14 1 20 4
+c11 -17 19 -37 24 -57c-19 -7 -32 -25 -32 -46zM193 112c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80z" />
+ <glyph glyph-name="ion-ios-glasses-outline" unicode="&#xf43e;"
d="M433 201v0h15v-18h-15c-2 -22 -13 -43 -29 -58c-17 -16 -39 -25 -62 -25c-51 0 -92 41 -92 92v0v0c0 10 -12 22 -26 22s-26 -12 -26 -22v0v0c0 -51 -41 -92 -92 -92c-23 0 -45 9 -62 25c-16 15 -27 36 -29 58h-15v18h15c2 22 13 43 29 59c17 16 39 24 62 24
c42 0 78 -27 89 -67c7 7 18 12 29 12s22 -5 29 -12c11 40 47 67 89 67c23 0 45 -9 62 -25c16 -15 27 -36 29 -58zM342 115c42 0 77 35 77 77s-35 77 -77 77s-77 -35 -77 -77s35 -77 77 -77zM106 115c42 0 77 35 77 77s-35 77 -77 77s-77 -35 -77 -77s35 -77 77 -77z" />
- <glyph glyph-name="ion-ios7-glasses" unicode="&#xf197;"
+ <glyph glyph-name="ion-ios-glasses" unicode="&#xf43f;"
d="M433 201v0h15v-18h-15c-2 -22 -13 -43 -29 -58c-17 -16 -39 -25 -62 -25c-51 0 -92 41 -92 92v0v0c0 10 -12 22 -26 22s-26 -12 -26 -22v0v0c0 -51 -41 -92 -92 -92c-23 0 -45 9 -62 25c-16 15 -27 36 -29 58h-15v18h15c2 22 13 43 29 59c17 16 39 24 62 24
c42 0 78 -27 89 -67c7 7 18 12 29 12s22 -5 29 -12c11 40 47 67 89 67c23 0 45 -9 62 -25c16 -15 27 -36 29 -58z" />
- <glyph glyph-name="ion-ios7-heart-outline" unicode="&#xf198;" horiz-adv-x="384"
-d="M277 350c-38 0 -71 -24 -85 -57c-14 33 -47 57 -85 57c-51 0 -92 -42 -92 -93c0 -25 10 -47 26 -64l151 -152l148 150c17 17 29 40 29 66c0 51 -41 93 -92 93zM277 365v0c59 0 107 -49 107 -108c0 -30 -12 -57 -33 -77l-148 -150l-11 -11l-11 11l-151 153
-c-19 20 -30 46 -30 74c0 59 48 108 107 108c34 0 65 -16 85 -42c20 26 51 42 85 42z" />
- <glyph glyph-name="ion-ios7-heart" unicode="&#xf199;" horiz-adv-x="384"
-d="M277 365v0c59 0 107 -49 107 -108c0 -30 -12 -57 -33 -77l-148 -150l-11 -11l-11 11l-151 153c-19 20 -30 46 -30 74c0 59 48 108 107 108c34 0 65 -16 85 -42c20 26 51 42 85 42z" />
- <glyph glyph-name="ion-ios7-help-empty" unicode="&#xf19a;" horiz-adv-x="128"
+ <glyph glyph-name="ion-ios-grid-view-outline" unicode="&#xf440;" horiz-adv-x="384"
+d="M384 256h-112v-128h112v-16h-112v-112h-16v112h-128v-112h-16v112h-112v16h112v128h-112v16h112v112h16v-112h128v112h16v-112h112v-16zM256 128v128h-128v-128h128z" />
+ <glyph glyph-name="ion-ios-grid-view" unicode="&#xf441;" horiz-adv-x="384"
+d="M128 128v128h128v-128h-128zM0 384h384v-384h-384v384zM352 256v16h-80v80h-16v-80h-128v80h-16v-80h-80v-16h80v-128h-80v-16h80v-80h16v80h128v-80h16v80h80v16h-80v128h80z" />
+ <glyph glyph-name="ion-ios-heart-outline" unicode="&#xf442;"
+d="M327 368c69 0 121 -43 121 -116c0 -31 -13 -71 -41 -105s-45 -52 -100 -88s-83 -43 -83 -43s-28 7 -83 43s-72 54 -100 88s-41 74 -41 105c0 73 52 116 121 116c39 0 82 -18 103 -53c21 35 64 53 103 53zM395 157c12 14 22 31 28 49c6 16 9 31 9 46c0 30 -10 56 -29 74
+c-9 8 -20 15 -33 19c-13 5 -28 7 -43 7c-38 0 -73 -18 -89 -45l-14 -23l-14 23c-16 27 -51 45 -89 45c-15 0 -30 -2 -43 -7c-13 -4 -24 -11 -33 -19c-19 -18 -29 -44 -29 -74c0 -15 3 -30 9 -46c6 -18 16 -35 28 -49c27 -32 42 -49 97 -85c40 -27 65 -36 74 -39
+c9 3 34 12 74 39c55 36 70 53 97 85z" />
+ <glyph glyph-name="ion-ios-heart" unicode="&#xf443;"
+d="M327 368c69 0 121 -43 121 -116c0 -31 -13 -71 -41 -105s-45 -52 -100 -88s-83 -43 -83 -43s-28 7 -83 43s-72 54 -100 88s-41 74 -41 105c0 73 52 116 121 116c39 0 82 -18 103 -53c21 35 64 53 103 53z" />
+ <glyph glyph-name="ion-ios-help-empty" unicode="&#xf444;" horiz-adv-x="128"
d="M68 82c-9 0 -17 8 -17 17s8 17 17 17s17 -8 17 -17s-8 -17 -17 -17zM102 197c-23 -22 -22 -27 -23 -53h-19c1 28 7 43 30 64c11 10 19 24 19 39c0 24 -19 39 -42 39c-32 0 -49 -16 -48 -46h-19c0 42 25 62 68 62c33 0 60 -20 60 -54c0 -22 -11 -37 -26 -51z" />
- <glyph glyph-name="ion-ios7-help-outline" unicode="&#xf19b;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-help-outline" unicode="&#xf445;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM212 302c33 0 60 -21 60 -55c0 -22 -11 -36 -26 -50c-23 -23 -22 -27 -23 -53h-19
c1 28 7 43 30 64c11 10 19 23 19 38c0 24 -19 40 -42 40c-32 0 -49 -16 -48 -46h-19c0 42 25 62 68 62zM212 116c9 0 17 -8 17 -17s-8 -17 -17 -17s-17 8 -17 17s8 17 17 17z" />
- <glyph glyph-name="ion-ios7-help" unicode="&#xf19c;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-help" unicode="&#xf446;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM212 82c9 0 17 8 17 17s-8 17 -17 17s-17 -8 -17 -17s8 -17 17 -17zM246 197c15 14 26 29 26 51c0 34 -27 54 -60 54c-43 0 -68 -20 -68 -62h19c-1 30 16 46 48 46
c23 0 42 -15 42 -39c0 -15 -8 -29 -19 -39c-23 -21 -29 -36 -30 -64h19c1 26 0 31 23 53z" />
- <glyph glyph-name="ion-ios7-home-outline" unicode="&#xf32a;" horiz-adv-x="384"
-d="M192 336l160 -128v-208h-112v128h-96v-128h-112v208zM336 16v184l-144 116l-144 -116v-184h80v128h128v-128h80zM192 384l192 -154v-20l-192 154l-192 -154v20l32 26v96h64v-45zM80 294v42h-32v-67z" />
- <glyph glyph-name="ion-ios7-home" unicode="&#xf32b;" horiz-adv-x="384"
-d="M192 336l160 -128v-208h-112v128h-96v-128h-112v208zM192 384l192 -154v-20l-192 154l-192 -154v20l32 26v96h64v-45z" />
- <glyph glyph-name="ion-ios7-infinite-outline" unicode="&#xf19d;" horiz-adv-x="384"
-d="M359 249c33 -31 33 -82 0 -113c-16 -15 -36 -24 -59 -24c-22 0 -44 9 -60 24l-108 102c-13 12 -30 18 -48 18s-35 -6 -48 -18c-26 -25 -26 -66 0 -91c13 -12 30 -19 48 -19s35 7 48 19l36 34l12 -11l-36 -34c-16 -15 -37 -24 -60 -24s-43 9 -59 24c-33 31 -33 82 0 113
-c16 15 36 23 59 23c22 0 44 -8 60 -23l108 -102c13 -12 30 -19 48 -19s34 7 47 19c26 25 26 66 0 91c-13 12 -29 18 -47 18s-35 -6 -48 -18l-37 -35l-11 11l36 35c16 15 37 23 60 23s43 -8 59 -23z" />
- <glyph glyph-name="ion-ios7-infinite" unicode="&#xf19e;" horiz-adv-x="384"
-d="M358 249c17 -15 26 -36 26 -57c0 -22 -9 -42 -26 -57s-39 -23 -63 -23s-45 8 -62 23l-103 93c-11 10 -26 15 -41 15s-30 -5 -41 -15s-16 -22 -16 -36s5 -26 16 -36s26 -15 41 -15s30 5 41 15l30 28l23 -20l-32 -29c-17 -15 -38 -23 -62 -23s-46 8 -63 23s-26 35 -26 57
-s9 42 26 57s39 23 63 23s45 -8 62 -23l104 -93c11 -10 25 -15 40 -15s30 5 41 15s17 22 17 36s-6 26 -17 36s-26 15 -41 15s-29 -5 -40 -15l-31 -28l-23 20l32 29c17 15 38 23 62 23s46 -8 63 -23z" />
- <glyph glyph-name="ion-ios7-information-empty" unicode="&#xf19f;" horiz-adv-x="64"
+ <glyph glyph-name="ion-ios-home-outline" unicode="&#xf447;" horiz-adv-x="384"
+d="M192 336l160 -128v-208h-112v128h-96v-128h-112v208zM336 16v184l-144 116l-144 -116v-184h80v128h128v-128h80zM192 384l192 -153l-12 -12l-180 145l-180 -145l-12 12l32 25v96h64v-45zM80 294v42h-32v-67z" />
+ <glyph glyph-name="ion-ios-home" unicode="&#xf448;" horiz-adv-x="384"
+d="M192 336l160 -128v-208h-112v128h-96v-128h-112v208zM192 384l192 -153l-12 -12l-180 145l-180 -145l-12 12l32 25v96h64v-45z" />
+ <glyph glyph-name="ion-ios-infinite-outline" unicode="&#xf449;"
+d="M419 260c19 -19 29 -43 29 -68s-10 -49 -29 -68c-19 -18 -44 -28 -70 -28s-50 10 -69 28l-126 123c-15 15 -35 22 -56 22s-40 -7 -55 -22c-31 -30 -31 -80 0 -110c15 -15 34 -22 55 -22s41 7 56 22l43 42l13 -14l-42 -41c-19 -18 -44 -28 -70 -28s-50 10 -69 28
+c-19 19 -29 43 -29 68s10 49 29 68c19 18 43 28 69 28s51 -10 70 -28l126 -123c15 -15 34 -22 55 -22s41 7 56 22c31 30 31 80 0 110c-15 15 -35 22 -56 22s-40 -7 -55 -22l-43 -42l-13 14l42 41c19 18 44 28 70 28s50 -10 69 -28z" />
+ <glyph glyph-name="ion-ios-infinite" unicode="&#xf44a;" horiz-adv-x="464"
+d="M433 266c20 -20 31 -46 31 -74s-11 -54 -31 -74s-48 -30 -76 -30s-55 10 -75 30l-125 123c-13 13 -32 20 -51 20s-37 -7 -50 -20s-21 -31 -21 -49c0 -19 8 -36 21 -49s31 -20 50 -20s38 7 51 20l39 38l25 -25l-39 -38c-20 -20 -48 -30 -76 -30s-55 10 -75 30
+s-31 46 -31 74s11 54 31 74s47 30 75 30s56 -10 76 -30l125 -123c13 -13 31 -20 50 -20s38 7 51 20s20 31 20 49c0 19 -7 36 -20 49s-32 20 -51 20s-37 -7 -50 -20l-39 -38l-25 25l39 38c20 20 48 30 76 30s55 -10 75 -30z" />
+ <glyph glyph-name="ion-ios-information-empty" unicode="&#xf44b;" horiz-adv-x="64"
d="M8 276c0 13 7 20 20 20s20 -7 20 -20s-7 -20 -20 -20s-20 7 -20 20zM48 104h16v-8h-64v8h16v120h-16v8h48v-128z" />
- <glyph glyph-name="ion-ios7-information-outline" unicode="&#xf1a0;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-information-outline" unicode="&#xf44c;" horiz-adv-x="416"
d="M184 276c0 13 7 20 20 20s20 -7 20 -20s-7 -20 -20 -20s-20 7 -20 20zM224 104h16v-8h-64v8h16v120h-16v8h48v-128zM208 400c57 0 106 -20 147 -61s61 -90 61 -147s-20 -106 -61 -147s-90 -61 -147 -61s-106 20 -147 61s-61 90 -61 147s20 106 61 147s90 61 147 61z
M208 1c53 0 98 19 135 56s56 82 56 135s-19 98 -56 135s-82 56 -135 56s-98 -19 -135 -56s-56 -82 -56 -135s19 -98 56 -135s82 -56 135 -56z" />
- <glyph glyph-name="ion-ios7-information" unicode="&#xf1a1;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-information" unicode="&#xf44d;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM204 296c-11 0 -20 -9 -20 -20s9 -20 20 -20s20 9 20 20s-9 20 -20 20zM240 96v8h-16v128h-48v-8h16v-120h-16v-8h64z" />
- <glyph glyph-name="ion-ios7-ionic-outline" unicode="&#xf1a2;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-ionic-outline" unicode="&#xf44e;" horiz-adv-x="416"
d="M378 313c24 -34 38 -76 38 -121c0 -115 -92 -208 -207 -208s-209 93 -209 208s94 208 209 208c45 0 86 -14 120 -38c6 5 13 8 21 8c19 0 35 -16 35 -35c0 -8 -2 -16 -7 -22zM350 357c-12 0 -22 -10 -22 -22s10 -22 22 -22s22 10 22 22s-10 22 -22 22zM344 56
c18 18 31 39 41 62c10 24 15 48 15 74s-5 51 -15 75c-5 13 -12 25 -20 36c-5 -2 -10 -3 -15 -3c-19 0 -35 16 -35 35c0 5 2 11 4 15c-11 8 -23 15 -36 20c-24 10 -49 14 -75 14s-51 -4 -75 -14c-23 -10 -43 -24 -61 -42s-31 -38 -41 -61c-10 -24 -15 -49 -15 -75
s5 -50 15 -74c10 -23 23 -44 41 -62s38 -31 61 -41c24 -10 49 -15 75 -15s51 5 75 15c23 10 43 23 61 41zM208 288c53 0 96 -43 96 -96s-43 -96 -96 -96s-96 43 -96 96s43 96 96 96zM208 112c44 0 80 36 80 80s-36 80 -80 80s-79 -36 -79 -80s35 -80 79 -80z" />
- <glyph glyph-name="ion-ios7-keypad-outline" unicode="&#xf1a3;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-keypad-outline" unicode="&#xf44f;" horiz-adv-x="384"
d="M331 107c30 0 53 -24 53 -54s-23 -53 -53 -53s-54 23 -54 53s24 54 54 54zM331 16c21 0 37 16 37 37s-16 38 -37 38s-38 -17 -38 -38s17 -37 38 -37zM192 107c30 0 53 -24 53 -54s-23 -53 -53 -53s-53 23 -53 53s23 54 53 54zM192 16c21 0 37 16 37 37s-16 38 -37 38
s-37 -17 -37 -38s16 -37 37 -37zM53 107c30 0 54 -24 54 -54s-24 -53 -54 -53s-53 23 -53 53s23 54 53 54zM53 16c21 0 38 16 38 37s-17 38 -38 38s-37 -17 -37 -38s16 -37 37 -37zM331 245c30 0 53 -23 53 -53s-23 -53 -53 -53s-54 23 -54 53s24 53 54 53zM331 155
c21 0 37 16 37 37s-16 37 -37 37s-38 -16 -38 -37s17 -37 38 -37zM192 245c30 0 53 -23 53 -53s-23 -53 -53 -53s-53 23 -53 53s23 53 53 53zM192 155c21 0 37 16 37 37s-16 37 -37 37s-37 -16 -37 -37s16 -37 37 -37zM53 245c30 0 54 -23 54 -53s-24 -53 -54 -53
s-53 23 -53 53s23 53 53 53zM53 155c21 0 38 16 38 37s-17 37 -38 37s-37 -16 -37 -37s16 -37 37 -37zM331 277c-30 0 -54 24 -54 54s24 53 54 53s53 -23 53 -53s-23 -54 -53 -54zM331 368c-21 0 -38 -16 -38 -37s17 -38 38 -38s37 17 37 38s-16 37 -37 37zM192 384
c30 0 53 -23 53 -53s-23 -54 -53 -54s-53 24 -53 54s23 53 53 53zM192 293c21 0 37 17 37 38s-16 37 -37 37s-37 -16 -37 -37s16 -38 37 -38zM53 384c30 0 54 -23 54 -53s-24 -54 -54 -54s-53 24 -53 54s23 53 53 53zM53 293c21 0 38 17 38 38s-17 37 -38 37
s-37 -16 -37 -37s16 -38 37 -38z" />
- <glyph glyph-name="ion-ios7-keypad" unicode="&#xf1a4;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-keypad" unicode="&#xf450;" horiz-adv-x="384"
d="M331 107c30 0 53 -24 53 -54s-23 -53 -53 -53s-54 23 -54 53s24 54 54 54zM192 107c30 0 53 -24 53 -54s-23 -53 -53 -53s-53 23 -53 53s23 54 53 54zM53 107c30 0 54 -24 54 -54s-24 -53 -54 -53s-53 23 -53 53s23 54 53 54zM331 245c30 0 53 -23 53 -53
s-23 -53 -53 -53s-54 23 -54 53s24 53 54 53zM192 245c30 0 53 -23 53 -53s-23 -53 -53 -53s-53 23 -53 53s23 53 53 53zM53 245c30 0 54 -23 54 -53s-24 -53 -54 -53s-53 23 -53 53s23 53 53 53zM331 277c-30 0 -54 24 -54 54s24 53 54 53s53 -23 53 -53s-23 -54 -53 -54z
M192 384c30 0 53 -23 53 -53s-23 -54 -53 -54s-53 24 -53 54s23 53 53 53zM53 384c30 0 54 -23 54 -53s-24 -54 -54 -54s-53 24 -53 54s23 53 53 53z" />
- <glyph glyph-name="ion-ios7-lightbulb-outline" unicode="&#xf286;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-lightbulb-outline" unicode="&#xf451;" horiz-adv-x="288"
d="M288 275c0 -31 -13 -59 -30 -83v0c-11 -15 -22 -28 -32 -45c-22 -38 -18 -73 -18 -82v-1h-128v1c0 7 3 44 -19 82c-10 17 -20 30 -31 45v0c-17 24 -30 52 -30 83c0 78 66 141 144 141s144 -63 144 -141zM239 194l6 8c16 22 27 47 27 73c0 33 -16 65 -40 89s-55 36 -88 36
s-64 -12 -88 -36s-40 -56 -40 -89c0 -26 11 -51 27 -73l19 -26v0c5 -6 9 -13 13 -21c17 -29 21 -58 21 -75h16v112l-32 64h17l31 -64v-112h32v112l31 64h17l-32 -64v-112h16c0 17 4 45 21 75c8 14 16 25 24 36c1 1 1 2 2 3zM112 -32v16h64v-16h-64zM96 0v16h96v-16h-96z
M96 32v16h96v-16h-96z" />
- <glyph glyph-name="ion-ios7-lightbulb" unicode="&#xf287;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-lightbulb" unicode="&#xf452;" horiz-adv-x="288"
d="M288 275c0 -31 -13 -59 -30 -83v0c-11 -15 -22 -28 -32 -45c-22 -38 -18 -73 -18 -82v-1h-32v128l32 64h-16l-32 -64v-128h-32v128l-31 64h-17l32 -64v-128h-32v1c0 7 3 44 -19 82c-10 17 -20 30 -31 45v0c-17 24 -30 52 -30 83c0 78 66 141 144 141s144 -63 144 -141z
M112 -32v16h64v-16h-64zM96 0v16h96v-16h-96zM96 32v16h96v-16h-96z" />
- <glyph glyph-name="ion-ios7-location-outline" unicode="&#xf1a5;" horiz-adv-x="268"
-d="M134 416c74 0 134 -59 134 -133c0 -17 -3 -34 -9 -50l-1 -1c0 -1 -1 -3 -1 -4l-1 -1l-122 -259l-122 260c0 1 -2 3 -2 4v0v1v0c-6 16 -10 34 -10 50c0 74 60 133 134 133zM243 239c6 14 9 29 9 44c0 65 -53 117 -118 117s-118 -52 -118 -117c0 -15 3 -31 9 -45
-c0 -1 1 -1 1 -2l1 -2l107 -227l107 227l1 2c0 1 1 1 1 2v1zM134 352c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM134 241c26 0 47 21 47 47s-21 47 -47 47s-47 -21 -47 -47s21 -47 47 -47z" />
- <glyph glyph-name="ion-ios7-location" unicode="&#xf1a6;" horiz-adv-x="268"
-d="M134 416c74 0 134 -59 134 -133c0 -17 -3 -34 -9 -50l-1 -1c0 -1 -1 -3 -1 -4l-1 -1l-122 -259l-122 260c0 1 -2 3 -2 4v1v0c-6 16 -10 34 -10 50c0 74 60 133 134 133zM134 241c26 0 47 21 47 47s-21 47 -47 47s-47 -21 -47 -47s21 -47 47 -47z" />
- <glyph glyph-name="ion-ios7-locked-outline" unicode="&#xf1a7;" horiz-adv-x="320"
-d="M264 224h56v-240h-320v240h56v72c0 57 46 104 104 104c57 0 104 -47 104 -104v-72zM72 296v-72h176v72c0 48 -40 88 -88 88s-88 -40 -88 -88zM304 0v208h-288v-208h288zM192 128c0 -15 -10 -27 -24 -31v-41c0 -4 -4 -8 -8 -8s-8 4 -8 8v41c-14 4 -24 16 -24 31
-c0 18 14 32 32 32s32 -14 32 -32zM160 112c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16z" />
- <glyph glyph-name="ion-ios7-locked" unicode="&#xf1a8;" horiz-adv-x="320"
-d="M160 144c9 0 16 -7 16 -16s-7 -16 -16 -16s-16 7 -16 16s7 16 16 16zM264 224h56v-240h-320v240h56v72c0 57 46 104 104 104c57 0 104 -47 104 -104v-72zM168 97c14 4 24 16 24 31c0 18 -14 32 -32 32s-32 -14 -32 -32c0 -15 10 -27 24 -31v-41c0 -4 4 -8 8 -8s8 4 8 8
-v41zM248 224v72c0 48 -40 88 -88 88s-88 -40 -88 -88v-72h176z" />
- <glyph glyph-name="ion-ios7-loop-strong" unicode="&#xf32c;" horiz-adv-x="512"
+ <glyph glyph-name="ion-ios-list-outline" unicode="&#xf453;" horiz-adv-x="384"
+d="M368 368h-352v-352h352v352zM384 384v0v-384h-384v384h384zM128 280v16h192v-16h-192zM128 184v16h192v-16h-192zM128 88v16h192v-16h-192zM64 288c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16zM64 192c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16
+s-16 5 -16 16zM64 96c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16z" />
+ <glyph glyph-name="ion-ios-list" unicode="&#xf454;" horiz-adv-x="384"
+d="M0 384h384v-384h-384v384zM80 80c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM80 176c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM80 272c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM320 88v16h-192v-16h192zM320 184v16
+h-192v-16h192zM320 280v16h-192v-16h192z" />
+ <glyph glyph-name="ion-ios-location-outline" unicode="&#xf455;" horiz-adv-x="288"
+d="M144 400c-34 0 -67 -13 -91 -37s-37 -57 -37 -91c0 -43 24 -107 70 -186c22 -38 44 -72 58 -91c14 19 36 53 58 91c46 79 70 143 70 186c0 34 -13 67 -37 91s-57 37 -91 37zM144 416v0c80 0 144 -64 144 -144c0 -112 -144 -304 -144 -304s-144 192 -144 304
+c0 80 64 144 144 144zM144 336c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM144 225c26 0 47 21 47 47s-21 47 -47 47s-47 -21 -47 -47s21 -47 47 -47z" />
+ <glyph glyph-name="ion-ios-location" unicode="&#xf456;" horiz-adv-x="288"
+d="M144 416c80 0 144 -64 144 -144c0 -112 -144 -304 -144 -304s-144 192 -144 304c0 80 64 144 144 144zM144 225c26 0 47 21 47 47s-21 47 -47 47s-47 -21 -47 -47s21 -47 47 -47z" />
+ <glyph glyph-name="ion-ios-locked-outline" unicode="&#xf457;" horiz-adv-x="320"
+d="M264 224h56v-240h-320v240h56v72c0 57 47 104 104 104s104 -47 104 -104v-72zM72 296v-72h176v72c0 49 -39 88 -88 88s-88 -39 -88 -88zM304 0v208h-288v-208h288zM160 160c18 0 32 -14 32 -32c0 -15 -10 -27 -24 -31v-33h-16v33c-14 4 -24 16 -24 31c0 18 14 32 32 32z
+M160 112c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16z" />
+ <glyph glyph-name="ion-ios-locked" unicode="&#xf458;" horiz-adv-x="320"
+d="M264 224h56v-240h-320v240h56v72c0 57 47 104 104 104s104 -47 104 -104v-72zM168 97c14 4 24 16 24 31c0 18 -14 32 -32 32s-32 -14 -32 -32c0 -15 10 -27 24 -31v-33h16v33zM248 224v72c0 49 -39 88 -88 88s-88 -39 -88 -88v-72h176zM160 144c9 0 16 -7 16 -16
+s-7 -16 -16 -16s-16 7 -16 16s7 16 16 16z" />
+ <glyph glyph-name="ion-ios-loop-strong" unicode="&#xf459;" horiz-adv-x="512"
d="M256 400c115 0 208 -93 208 -208c0 -14 -1 -28 -4 -42l-1 -4l-24 5l1 4c2 12 4 24 4 37c0 101 -83 184 -184 184c-66 0 -127 -36 -160 -94l-2 -3l-21 11l2 4c37 65 106 106 181 106zM416 102l2 3l21 -11l-2 -4c-37 -65 -106 -106 -181 -106c-115 0 -208 93 -208 208
c0 14 1 28 4 42l1 4l24 -5l-1 -4c-2 -12 -4 -24 -4 -37c0 -101 83 -184 184 -184c66 0 127 36 160 94zM384 192h128l-64 -64zM0 192l64 64l64 -64h-128z" />
- <glyph glyph-name="ion-ios7-loop" unicode="&#xf32d;" horiz-adv-x="489"
+ <glyph glyph-name="ion-ios-loop" unicode="&#xf45a;" horiz-adv-x="489"
d="M478 192l11 -11l-52 -53l-53 53l10 11l43 -41zM449 192v0v0c0 -7 0 -14 -1 -21l-16 1c1 7 1 14 1 21c-1 103 -85 187 -188 187c-68 0 -131 -37 -164 -96l-14 8c36 64 104 104 178 104c112 0 203 -91 204 -202v0v-2zM409 100l14 -8c-36 -64 -104 -104 -178 -104
c-111 0 -202 90 -204 200v0v3v1v0c0 7 0 14 1 21l16 -1c-1 -7 -1 -14 -1 -21c0 -103 85 -187 188 -187c68 0 131 37 164 96zM53 256l52 -53l-11 -11l-41 41l-42 -41l-11 11z" />
- <glyph glyph-name="ion-ios7-medkit-outline" unicode="&#xf288;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-medical-outline" unicode="&#xf45b;" horiz-adv-x="364"
+d="M364 260l-118 -68l118 -68l-32 -56l-118 69v-137h-64v137l-118 -69l-32 56l118 68l-118 68l32 56l118 -69v137h64v-137l118 69zM342 118l-128 74l128 74l-16 28l-128 -74v148h-32v-148l-128 74l-16 -28l128 -74l-128 -74l16 -28l128 74v-148h32v148l128 -74z" />
+ <glyph glyph-name="ion-ios-medical" unicode="&#xf45c;" horiz-adv-x="364"
+d="M364 260l-118 -68l118 -68l-32 -56l-118 69v-137h-64v137l-118 -69l-32 56l118 68l-118 68l32 56l118 -69v137h64v-137l118 69z" />
+ <glyph glyph-name="ion-ios-medkit-outline" unicode="&#xf45d;" horiz-adv-x="416"
d="M224 240h-32v-48v-16h-16h-48v-32h48h16v-16v-48h32v48v16h16h48v32h-48h-16v16v48zM240 256v0v-64h64v-64h-64v-64h-64v64h-64v64h64v64h64zM288 320h128v-320h-416v320h128v32c0 18 10 32 29 32h99c19 0 32 -14 32 -32v-32zM144 350v-30h128v30c0 10 -7 18 -17 18h-97
c-11 0 -14 -8 -14 -18zM400 16v288h-384v-288h384z" />
- <glyph glyph-name="ion-ios7-medkit" unicode="&#xf289;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-medkit" unicode="&#xf45e;" horiz-adv-x="416"
d="M224 176h16h48v-32h-48h-16v-16v-48h-32v48v16h-16h-48v32h48h16v16v48h32v-48v-16zM288 320h128v-320h-416v320h128v32c0 18 10 32 29 32h99c19 0 32 -14 32 -32v-32zM144 350v-30h128v30c0 10 -7 18 -17 18h-97c-11 0 -14 -8 -14 -18zM304 128v64h-64v64h-64v-64h-64
v-64h64v-64h64v64h64z" />
- <glyph glyph-name="ion-ios7-mic-off" unicode="&#xf1a9;" horiz-adv-x="280"
+ <glyph glyph-name="ion-ios-mic-off" unicode="&#xf45f;" horiz-adv-x="280"
d="M266 -32l-258 440l14 8l258 -440zM128 95c-44 0 -79 37 -79 83v118l113 -193c-10 -5 -22 -8 -34 -8zM207 178c0 -10 -2 -19 -5 -28l-136 234c14 20 37 32 62 32c44 0 79 -38 79 -84v-154zM256 176c0 -28 -9 -54 -24 -75l-10 17c11 17 17 36 17 58v80h17v-80zM139 49v0
v-63h69v-18h-161v18h73v63c-67 5 -120 60 -120 127v80h19v-80c0 -60 50 -109 110 -109c17 0 34 4 48 11l9 -16c-14 -7 -30 -12 -47 -13z" />
- <glyph glyph-name="ion-ios7-mic-outline" unicode="&#xf1aa;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-mic-outline" unicode="&#xf460;" horiz-adv-x="256"
d="M128 416c44 0 79 -38 79 -84v-154c0 -46 -35 -84 -79 -84s-79 38 -79 84v154c0 46 35 84 79 84zM191 178v154c0 37 -28 68 -63 68s-63 -31 -63 -68v-154c0 -37 28 -68 63 -68s63 31 63 68zM239 256h17v-80c0 -67 -51 -122 -117 -127v-63h69v-18h-161v18h73v63
c-67 5 -120 60 -120 127v80h19v-80c0 -60 50 -109 110 -109s110 49 110 109v80z" />
- <glyph glyph-name="ion-ios7-mic" unicode="&#xf1ab;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-mic" unicode="&#xf461;" horiz-adv-x="256"
d="M128 94c-44 0 -79 38 -79 84v154c0 46 35 84 79 84s79 -38 79 -84v-154c0 -46 -35 -84 -79 -84zM239 256h17v-80c0 -67 -51 -122 -117 -127v-63h69v-18h-161v18h73v63c-67 5 -120 60 -120 127v80h19v-80c0 -60 50 -109 110 -109s110 49 110 109v80z" />
- <glyph glyph-name="ion-ios7-minus-empty" unicode="&#xf1ac;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-minus-empty" unicode="&#xf462;" horiz-adv-x="256"
d="M256 183h-256v17h256v-17z" />
- <glyph glyph-name="ion-ios7-minus-outline" unicode="&#xf1ad;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-minus-outline" unicode="&#xf463;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM80 183v17h256v-17h-256z" />
- <glyph glyph-name="ion-ios7-minus" unicode="&#xf1ae;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-minus" unicode="&#xf464;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM336 183v17h-256v-17h256z" />
- <glyph glyph-name="ion-ios7-monitor-outline" unicode="&#xf1af;" horiz-adv-x="480"
+ <glyph glyph-name="ion-ios-monitor-outline" unicode="&#xf465;" horiz-adv-x="480"
d="M480 64h-176v-16h64v-16h-257v16h64v16h-175v288h480v-288zM16 336v-256h448v256h-448z" />
- <glyph glyph-name="ion-ios7-monitor" unicode="&#xf1b0;" horiz-adv-x="480"
+ <glyph glyph-name="ion-ios-monitor" unicode="&#xf466;" horiz-adv-x="480"
d="M480 64h-176v-16h64v-16h-257v16h64v16h-175v288h480v-288zM16 336v-256h448v256h-448zM32 96v224h416v-224h-416z" />
- <glyph glyph-name="ion-ios7-moon-outline" unicode="&#xf1b1;" horiz-adv-x="216"
+ <glyph glyph-name="ion-ios-moon-outline" unicode="&#xf467;" horiz-adv-x="216"
d="M195 133c7 0 14 1 21 3c-4 -7 -7 -12 -12 -18c-21 -25 -53 -41 -88 -41c-64 0 -116 51 -116 115c0 52 34 96 81 111c7 2 14 3 22 4c-4 -6 -8 -12 -11 -18c-7 -14 -11 -30 -11 -47c0 -29 11 -56 32 -77s48 -32 77 -32h5zM116 93c25 0 48 9 65 24c-65 5 -116 59 -116 125
c0 14 2 28 6 40c-33 -16 -55 -51 -55 -90c0 -55 45 -99 100 -99z" />
- <glyph glyph-name="ion-ios7-moon" unicode="&#xf1b2;" horiz-adv-x="216"
+ <glyph glyph-name="ion-ios-moon" unicode="&#xf468;" horiz-adv-x="216"
d="M195 133c7 0 14 1 21 3c-4 -7 -7 -12 -12 -18c-21 -25 -53 -41 -88 -41c-64 0 -116 51 -116 115c0 52 34 96 81 111c7 2 14 3 22 4c-4 -6 -8 -12 -11 -18c-7 -14 -11 -30 -11 -47c0 -29 11 -56 32 -77s48 -32 77 -32h5z" />
- <glyph glyph-name="ion-ios7-more-outline" unicode="&#xf1b3;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-more-outline" unicode="&#xf469;" horiz-adv-x="320"
d="M160 210c-10 0 -18 -8 -18 -18s8 -18 18 -18s18 8 18 18s-8 18 -18 18zM160 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM32 210c-10 0 -18 -8 -18 -18s8 -18 18 -18s18 8 18 18s-8 18 -18 18zM32 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32
s-32 14 -32 32s14 32 32 32zM288 210c-10 0 -18 -8 -18 -18s8 -18 18 -18s18 8 18 18s-8 18 -18 18zM288 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32z" />
- <glyph glyph-name="ion-ios7-more" unicode="&#xf1b4;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-more" unicode="&#xf46a;" horiz-adv-x="320"
d="M160 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM32 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM288 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32z" />
- <glyph glyph-name="ion-ios7-musical-note" unicode="&#xf1b5;" horiz-adv-x="192"
+ <glyph glyph-name="ion-ios-musical-note" unicode="&#xf46b;" horiz-adv-x="192"
d="M192 346v-1v-65c0 -3 -3 -6 -6 -5v0l-73 13v-192c0 -33 1 -80 -51 -82c-48 -2 -62 16 -62 41c0 19 9 39 51 41c22 1 37 1 45 1v273l90 -19l2 -1c2 0 3 -1 4 -3v0v-1v0z" />
- <glyph glyph-name="ion-ios7-musical-notes" unicode="&#xf1b6;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-musical-notes" unicode="&#xf46c;" horiz-adv-x="320"
d="M320 128c0 -34 4 -80 -49 -82c-49 -2 -62 16 -62 41c0 20 9 39 52 41c23 1 34 2 43 2v160l-191 -32v-161c0 -34 3 -81 -50 -83c-49 -2 -63 17 -63 42c0 20 9 39 52 41c23 1 35 1 44 1v237l224 35v-242z" />
- <glyph glyph-name="ion-ios7-navigate-outline" unicode="&#xf1b7;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-navigate-outline" unicode="&#xf46d;" horiz-adv-x="416"
d="M208 384c-51 0 -99 -21 -135 -57s-57 -84 -57 -135s21 -99 57 -135s84 -57 135 -57s99 21 135 57s57 84 57 135s-21 99 -57 135s-84 57 -135 57zM208 400v0c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM304 288l-96 -224v128h-128z" />
- <glyph glyph-name="ion-ios7-navigate" unicode="&#xf1b8;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-navigate" unicode="&#xf46e;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 64l96 224l-224 -96h128v-128z" />
- <glyph glyph-name="ion-ios7-paper-outline" unicode="&#xf32e;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-nutrition-outline" unicode="&#xf46f;" horiz-adv-x="384"
+d="M294 214v0c6 -6 10 -14 10 -23c0 -11 -5 -20 -13 -26v0s-51 -37 -106 -77l-38 31c-2 2 -4 3 -6 3c-1 0 -2 0 -3 -1v0c-2 -2 -2 -6 1 -10l29 -35l-115 -84c-6 -4 -13 -8 -21 -8c-18 0 -32 14 -32 32c0 7 1 13 4 18v0c2 2 17 25 37 57l21 -17c2 -2 4 -2 6 -2c1 0 3 0 4 1v0
+c2 2 1 6 -2 10l-19 23c27 43 60 96 84 134l36 -30c2 -2 4 -3 6 -3c1 0 2 1 3 2v0c2 2 2 5 -1 9l-33 40c11 18 19 29 19 29v0c6 10 15 16 27 16c9 0 18 -4 24 -10v0l78 -79v0v0zM282 178c4 3 6 8 6 13c0 4 -2 9 -5 12l-5 4v1l-69 69v0l-5 5c-3 3 -8 5 -12 5
+c-6 0 -10 -3 -13 -8l-5 -8c-2 -3 -5 -7 -8 -12l25 -30v0l1 -1c8 -10 8 -22 0 -30l-1 -1l-1 -1c-4 -3 -8 -5 -13 -5s-11 2 -16 6v1h-1l-21 18l-24 -39l-44 -70l12 -14v0v0c8 -10 8 -23 0 -31v0c-4 -4 -9 -6 -15 -6c-5 0 -11 2 -16 6v0v0l-7 5c-3 -5 -5 -9 -8 -13
+c-12 -19 -16 -26 -18 -29c-1 -3 -2 -6 -2 -9c0 -9 7 -16 16 -16c3 0 6 2 11 5l101 74l-18 22h-1v0c-8 10 -8 23 0 31v0v0v0c4 4 10 6 15 6s11 -2 16 -6v0h1l28 -24c49 36 93 68 96 70zM376 333l8 -14l-5 -3l-103 -60l-17 17l71 123l2 4l14 -8l-3 -4l-63 -111l91 53z" />
+ <glyph glyph-name="ion-ios-nutrition" unicode="&#xf470;" horiz-adv-x="384"
+d="M295 214v0c6 -6 9 -13 9 -22c0 -11 -5 -20 -13 -26v0s-51 -38 -106 -78l-38 32c-4 3 -8 3 -10 1v0c-2 -2 -2 -6 1 -10l29 -35l-114 -84c-6 -4 -13 -8 -21 -8c-18 0 -32 14 -32 32c0 7 2 13 5 18v0c1 2 16 25 36 57l20 -17c4 -3 8 -3 10 -1v0c2 2 2 6 -1 10l-20 23
+c27 43 60 96 84 134l36 -30c4 -3 8 -3 10 -1v0c2 2 2 6 -1 10l-33 40c11 18 18 29 18 29v0c6 10 16 16 28 16c9 0 18 -4 24 -10v0l78 -79l1 -1v0zM384 309l-103 -59l-28 29l70 121l28 -16l-50 -85l67 38z" />
+ <glyph glyph-name="ion-ios-paper-outline" unicode="&#xf471;" horiz-adv-x="384"
d="M48 384h336v-353c0 -17 -14 -31 -31 -31h-322c-17 0 -31 14 -31 31v305h32v-16h-16v-289c0 -8 7 -15 15 -15h322c8 0 15 7 15 15v337h-304v-320h-16v320v16zM96 320v16h128v-16h-128zM96 240v16h240v-16h-240zM96 160v16h192v-16h-192zM96 80v16h240v-16h-240z" />
- <glyph glyph-name="ion-ios7-paper" unicode="&#xf32f;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-paper" unicode="&#xf472;" horiz-adv-x="384"
d="M48 384h336v-353c0 -17 -14 -31 -31 -31h-322c-17 0 -31 14 -31 31v305h32v-288h16v288v32v16zM96 336v-16h128v16h-128zM96 176v-16h192v16h-192zM336 80v16h-240v-16h240zM336 240v16h-240v-16h240z" />
- <glyph glyph-name="ion-ios7-paperplane-outline" unicode="&#xf1b9;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-paperplane-outline" unicode="&#xf473;" horiz-adv-x="320"
d="M0 198l320 154l-146 -320l-57 115zM132 152l41 -83l115 249zM286 320l-248 -121l83 -36z" />
- <glyph glyph-name="ion-ios7-paperplane" unicode="&#xf1ba;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-paperplane" unicode="&#xf474;" horiz-adv-x="320"
d="M0 198l320 154l-214 -200zM320 352l-146 -320l-52 104z" />
- <glyph glyph-name="ion-ios7-partlysunny-outline" unicode="&#xf1bb;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-partlysunny-outline" unicode="&#xf475;" horiz-adv-x="384"
d="M144 298v54h16v-54h-16zM0 192v16h55v-16h-55zM44 299l10 11l32 -32l-11 -11zM223 268l-11 11l32 32l11 -11zM56 96l-10 11l31 31l11 -11zM129 153c-4 -3 -8 -7 -12 -12c-23 12 -39 36 -39 63c0 39 32 71 71 71c21 0 40 -10 53 -25c-4 -2 -9 -4 -14 -8
c-10 11 -23 17 -39 17c-30 0 -55 -25 -55 -55c0 -23 15 -43 35 -51zM235 208c-34 0 -63 -28 -63 -62v-12s1 -10 1 -10c-5 0 -12 -1 -14 -1c-19 -3 -33 -18 -33 -37c0 -10 3 -19 10 -26s16 -11 26 -11h157c27 0 49 22 49 49s-22 50 -49 50c-2 0 -4 -1 -6 -1l-14 -2l-3 14
c-3 14 -11 26 -22 35s-25 14 -39 14zM235 224v0c37 0 68 -26 76 -61h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78z" />
- <glyph glyph-name="ion-ios7-partlysunny" unicode="&#xf1bc;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-partlysunny" unicode="&#xf476;" horiz-adv-x="384"
d="M144 298v54h16v-54h-16zM0 192v16h55v-16h-55zM44 299l10 11l32 -32l-11 -11zM223 268l-11 11l32 32l11 -11zM56 96l-10 11l31 31l11 -11zM235 224v0c37 0 68 -26 76 -61h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8
c0 43 35 78 78 78zM201 252l1 -2v0c-31 -5 -62 -43 -62 -75c0 -2 1 -5 1 -7l-1 -1h-1c-11 -6 -18 -14 -22 -26v1v-1c-23 12 -39 36 -39 63c0 39 32 71 71 71c21 0 39 -9 52 -23z" />
- <glyph glyph-name="ion-ios7-pause-outline" unicode="&#xf1bd;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-pause-outline" unicode="&#xf477;" horiz-adv-x="256"
d="M63 336h-47v-288h47v288zM79 352v0v-320h-79v320h79zM240 336h-47v-288h47v288zM256 352v0v-320h-79v320h79z" />
- <glyph glyph-name="ion-ios7-pause" unicode="&#xf1be;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-pause" unicode="&#xf478;" horiz-adv-x="256"
d="M0 32v320h79v-320h-79zM177 32v320h79v-320h-79z" />
- <glyph glyph-name="ion-ios7-paw-outline" unicode="&#xf330;" horiz-adv-x="416"
-d="M262 238c-11 2 -20 7 -27 17c-12 16 -15 41 -11 65c6 37 27 64 54 64h6c12 -2 22 -8 30 -19c12 -16 16 -39 13 -61c-6 -37 -31 -66 -59 -66h-6zM278 368c-18 0 -34 -21 -38 -50c-3 -20 -1 -41 8 -53c5 -6 11 -10 17 -11h3c19 0 39 23 43 52c3 18 -2 37 -11 49
-c-4 5 -10 12 -19 13h-3zM412 244c6 -17 5 -38 -3 -57c-10 -25 -31 -43 -51 -43c-5 0 -10 1 -15 3c-22 10 -30 45 -17 79c10 28 31 46 51 46c5 0 10 -1 14 -3c10 -4 17 -13 21 -25zM357 162c14 0 29 13 37 32c6 15 7 31 2 44c-2 5 -5 12 -12 15c-2 1 -4 2 -7 2
-c-13 0 -28 -15 -36 -36c-9 -25 -6 -50 8 -56c2 -1 5 -1 8 -1zM7 187c-8 19 -9 40 -3 57c4 12 11 21 21 25c4 2 9 3 14 3c20 0 41 -18 51 -46c13 -34 5 -69 -17 -79c-5 -2 -10 -3 -15 -3c-20 0 -41 18 -51 43zM22 194c8 -19 23 -32 37 -32c3 0 6 0 8 1c14 6 17 31 8 56
-c-8 21 -23 36 -36 36c-3 0 -5 -1 -7 -2c-7 -3 -10 -10 -12 -15c-5 -13 -4 -29 2 -44zM149 238c-28 0 -53 29 -59 66c-3 22 1 45 13 61c8 11 18 17 30 19h6c27 0 47 -28 53 -65c4 -24 2 -48 -10 -64c-7 -10 -17 -15 -28 -17h-5zM139 368h-4c-9 -1 -15 -8 -19 -13
-c-9 -12 -13 -31 -10 -49c4 -29 24 -52 43 -52h3c6 1 11 5 16 11c9 12 11 32 8 52c-4 29 -19 51 -37 51zM208 192c64 0 128 -71 128 -138c0 -20 -11 -36 -22 -43c-13 -8 -23 -11 -42 -11c-23 0 -29 7 -40 14c-8 5 -14 9 -24 9s-16 -4 -24 -9c-11 -7 -17 -14 -40 -14
-c-19 0 -29 3 -42 11c-11 7 -22 23 -22 43c0 67 64 138 128 138zM306 25c6 3 14 14 14 29c0 28 -14 59 -36 83c-11 12 -23 22 -36 29s-27 10 -40 10s-27 -3 -40 -10s-25 -17 -36 -29c-22 -24 -36 -55 -36 -83c0 -15 8 -26 14 -29c11 -7 18 -9 34 -9c14 0 19 3 26 8
-c2 1 4 3 6 4c9 5 18 11 32 11s23 -6 32 -11c2 -1 4 -3 6 -4c7 -5 12 -8 26 -8c16 0 23 2 34 9z" />
- <glyph glyph-name="ion-ios7-paw" unicode="&#xf331;" horiz-adv-x="416"
-d="M262 238c-11 2 -20 7 -27 17c-12 16 -15 41 -11 65c6 37 27 64 54 64h6c12 -2 22 -8 30 -19c12 -16 16 -39 13 -61c-6 -37 -31 -66 -59 -66h-6zM412 244c6 -17 5 -38 -3 -57c-10 -25 -31 -43 -51 -43c-5 0 -10 1 -15 3c-22 10 -30 45 -17 79c10 28 31 46 51 46
-c5 0 10 -1 14 -3c10 -4 17 -13 21 -25zM7 187c-8 19 -9 40 -3 57c4 12 11 21 21 25c4 2 9 3 14 3c20 0 41 -18 51 -46c13 -34 5 -69 -17 -79c-5 -2 -10 -3 -15 -3c-20 0 -41 18 -51 43zM149 238c-28 0 -53 29 -59 66c-3 22 1 45 13 61c8 11 18 17 30 19h6
-c27 0 47 -28 53 -65c4 -24 2 -48 -10 -64c-7 -10 -17 -15 -28 -17h-5zM208 192c64 0 128 -71 128 -138c0 -20 -11 -36 -22 -43c-13 -8 -23 -11 -42 -11c-23 0 -29 7 -40 14c-8 5 -14 9 -24 9s-16 -4 -24 -9c-11 -7 -17 -14 -40 -14c-19 0 -29 3 -42 11c-11 7 -22 23 -22 43
-c0 67 64 138 128 138z" />
- <glyph glyph-name="ion-ios7-people-outline" unicode="&#xf1bf;"
+ <glyph glyph-name="ion-ios-paw-outline" unicode="&#xf479;" horiz-adv-x="384"
+d="M380 252c6 -17 5 -38 -3 -57c-10 -25 -31 -43 -51 -43c-5 0 -10 1 -15 3c-22 10 -30 45 -17 79c10 28 31 46 51 46c5 0 10 -1 14 -3c10 -4 17 -13 21 -25zM362 202c6 15 7 31 2 44c-2 5 -5 12 -12 15c-2 1 -4 2 -7 2c-13 0 -28 -15 -36 -36c-9 -25 -6 -50 8 -56
+c2 -1 5 -1 8 -1c14 0 29 13 37 32zM90 234c13 -34 5 -69 -17 -79c-5 -2 -10 -3 -15 -3c-20 0 -41 18 -51 43c-8 19 -9 40 -3 57c4 12 11 21 21 25c4 2 9 3 14 3c20 0 41 -18 51 -46zM67 171c14 6 17 31 8 56c-8 21 -23 36 -36 36c-3 0 -5 -1 -7 -2c-7 -3 -10 -10 -12 -15
+c-5 -13 -4 -29 2 -44c8 -19 23 -32 37 -32c3 0 6 0 8 1zM134 237c-28 1 -52 32 -56 69c-2 23 4 45 16 60c8 10 19 17 31 18h6c27 -1 46 -29 50 -67c3 -24 -1 -48 -13 -63c-8 -9 -17 -15 -28 -16c-2 0 -4 -1 -6 -1zM107 356c-10 -12 -14 -29 -12 -48c3 -29 21 -53 40 -54h3
+c6 1 12 4 17 10c10 12 12 31 10 51c-3 29 -17 52 -35 53h-3c-9 -1 -16 -7 -20 -12zM192 208c64 0 128 -76 128 -149c0 -22 -11 -40 -22 -47c-13 -9 -23 -12 -42 -12c-23 0 -29 8 -40 15c-8 5 -14 10 -24 10s-16 -5 -24 -10c-11 -7 -17 -15 -40 -15c-19 0 -29 3 -42 12
+c-11 7 -22 25 -22 47c0 73 64 149 128 149zM290 27c6 4 14 16 14 32c0 30 -14 64 -36 91c-11 13 -23 24 -36 31c-13 8 -27 11 -40 11s-27 -3 -40 -11c-13 -7 -25 -18 -36 -31c-22 -27 -36 -61 -36 -91c0 -16 8 -28 14 -32c11 -7 18 -10 34 -10c14 0 19 4 26 9c2 1 4 3 6 4
+c9 6 18 12 32 12s23 -6 32 -12c2 -1 4 -3 6 -4c7 -5 12 -9 26 -9c16 0 23 3 34 10zM244 238c-11 1 -20 7 -28 16c-12 15 -16 39 -13 63c4 38 23 66 50 67h7c12 -1 22 -8 30 -18c12 -15 18 -37 16 -60c-4 -37 -28 -67 -56 -68h-6zM219 315c-2 -20 0 -39 10 -51
+c5 -6 11 -9 17 -10h3c19 1 38 25 41 54c2 19 -3 36 -13 48c-4 5 -10 11 -19 12h-4c-18 -1 -32 -24 -35 -53z" />
+ <glyph glyph-name="ion-ios-paw" unicode="&#xf47a;" horiz-adv-x="384"
+d="M380 252c6 -17 5 -38 -3 -57c-10 -25 -31 -43 -51 -43c-5 0 -10 1 -15 3c-22 10 -30 45 -17 79c10 28 31 46 51 46c5 0 10 -1 14 -3c10 -4 17 -13 21 -25zM90 234c13 -34 5 -69 -17 -79c-5 -2 -10 -3 -15 -3c-20 0 -41 18 -51 43c-8 19 -9 40 -3 57c4 12 11 21 21 25
+c4 2 9 3 14 3c20 0 41 -18 51 -46zM134 237c-28 1 -52 32 -56 69c-2 23 4 45 16 60c8 10 19 17 31 18h6c27 -1 46 -29 50 -67c3 -24 -1 -48 -13 -63c-8 -9 -17 -15 -28 -16c-2 0 -4 -1 -6 -1zM192 208c64 0 128 -76 128 -149c0 -22 -11 -40 -22 -47c-13 -9 -23 -12 -42 -12
+c-23 0 -29 8 -40 15c-8 5 -14 10 -24 10s-16 -5 -24 -10c-11 -7 -17 -15 -40 -15c-19 0 -29 3 -42 12c-11 7 -22 25 -22 47c0 73 64 149 128 149zM244 238c-11 1 -20 7 -28 16c-12 15 -16 39 -13 63c4 38 23 66 50 67h7c12 -1 22 -8 30 -18c12 -15 18 -37 16 -60
+c-4 -37 -28 -67 -56 -68h-6z" />
+ <glyph glyph-name="ion-ios-people-outline" unicode="&#xf47b;"
d="M224 336v0v0zM317 113c11 -4 -11 4 0 0c28 -10 46 -35 46 -65h-28h-250c0 22 9 42 27 55c15 11 31 12 49 16c7 1 24 5 26 13s1 15 1 23c0 3 0 3 -2 5c-4 4 -6 9 -8 14c-2 8 -3 16 -4 24c-9 -2 -10 16 -12 21c-1 4 -7 24 3 21c-3 5 -4 13 -5 19c-2 13 -2 26 3 39
c10 26 37 39 64 38c26 -1 51 -16 59 -42c4 -12 3 -26 1 -39c-1 -5 -2 -11 -4 -15c10 3 4 -20 3 -23c-2 -5 -3 -21 -12 -19c-1 -10 -2 -22 -7 -31c-1 -2 -7 -8 -7 -10v-11c0 -5 0 -10 2 -15s10 -7 14 -8c14 -5 27 -5 41 -10zM115 84c-6 -6 9 10 0 0c-6 -6 -10 -12 -12 -20h4
h238c-4 15 -17 27 -30 33s-28 4 -41 9s-25 9 -28 25c-2 11 -2 22 -2 33c0 2 7 7 8 9c3 5 4 11 5 17c1 5 0 12 4 15c5 4 7 7 9 13c2 8 3 12 -1 19c-3 5 0 8 1 13c3 11 4 24 2 36c-8 37 -62 45 -86 19c-12 -13 -12 -31 -9 -47c1 -6 6 -14 3 -19c-1 -3 -5 -6 -4 -10
@@ -1031,254 +1238,271 @@ c6 -2 19 -3 23 -8c2 -3 1 -5 -2 -5c-8 -1 -15 -1 -22 -5zM71 112c6 10 16 18 26 24c-
c-1 -12 -8 -18 -19 -22c-12 -4 -29 -3 -36 -15h49zM368 96c-2 8 -10 14 -16 19c-8 6 -18 13 -28 15c-3 1 -16 -1 -13 5c2 4 9 5 13 6s15 2 16 7c0 1 1 14 0 14c-6 0 -12 1 -18 2c-4 1 -7 2 -11 4c-6 3 -2 6 0 11c14 32 -10 88 32 105c15 6 34 5 48 -3c15 -9 20 -27 20 -44
c0 -20 -4 -44 7 -62c2 -3 4 -4 0 -6c-2 -1 -4 -1 -6 -2l-12 -3s-9 -1 -13 -1c0 -4 -2 -13 1 -17c6 -7 21 -7 29 -10c18 -6 31 -20 31 -40h-80zM367 123c4 -4 -5 5 0 0s8 -11 15 -11h16h28c-7 12 -26 11 -38 16c-11 4 -16 12 -17 24c0 2 -1 27 1 27c9 0 18 0 26 1
c-7 23 1 47 -4 70c-3 15 -15 23 -30 23c-17 0 -28 -8 -31 -25c-4 -23 2 -46 -5 -68c6 -2 12 -2 18 -2s8 1 9 -5c1 -11 5 -28 -4 -37c6 -4 11 -8 16 -13z" />
- <glyph glyph-name="ion-ios7-people" unicode="&#xf1c0;"
+ <glyph glyph-name="ion-ios-people" unicode="&#xf47c;"
d="M317 113c11 -4 -11 4 0 0v0zM317 113c28 -10 46 -35 46 -65h-28h-250c0 22 9 42 27 55c15 11 31 12 49 16c7 1 24 5 26 13s1 15 1 23c0 3 0 3 -2 5c-4 4 -6 9 -8 14c-2 8 -3 16 -4 24c-9 -2 -10 16 -12 21c-1 4 -7 24 3 21c-3 5 -4 13 -5 19c-2 13 -2 26 3 39
c10 26 37 39 64 38c26 -1 51 -16 59 -42c4 -12 3 -26 1 -39c-1 -5 -2 -11 -4 -15c10 3 4 -20 3 -23c-2 -5 -3 -21 -12 -19c-1 -10 -2 -22 -7 -31c-1 -2 -7 -8 -7 -10v-11c0 -5 0 -10 2 -15s10 -7 14 -8c14 -5 27 -5 41 -10zM111 126h2h-1h-1zM111 126c-9 -5 -17 -11 -24 -19
c-1 -2 -6 -11 -7 -11h-25h-55c0 20 12 34 30 40c6 2 27 4 30 11c2 5 1 11 1 16c-10 -1 -24 1 -32 7c-2 2 3 9 4 12c1 4 2 7 3 11c1 9 1 19 1 28c0 16 -1 35 8 49c8 13 23 18 38 18c24 0 43 -13 47 -37c3 -16 1 -32 2 -48c0 -8 2 -16 5 -24c1 -2 5 -7 3 -9l-6 -3
c-5 -2 -11 -3 -17 -4c-1 0 -8 0 -9 -1s0 -9 0 -11c0 -4 1 -6 5 -7c6 -2 19 -3 23 -8c2 -3 1 -5 -2 -5c-7 -1 -14 -2 -21 -5c2 1 2 2 -1 0c-8 -4 -4 -2 -1 0zM417 136c18 -6 31 -20 31 -40h-80c-2 8 -10 14 -16 19c-8 6 -18 13 -28 15c-3 1 -16 -1 -13 5c2 4 9 5 13 6
s15 2 16 7c0 1 1 14 0 14c-6 0 -12 1 -18 2c-4 1 -7 2 -11 4c-6 3 -2 6 0 11c14 32 -10 88 32 105c15 6 34 5 48 -3c15 -9 20 -27 20 -44c0 -20 -4 -44 7 -62c2 -3 4 -4 0 -6c-2 -1 -4 -1 -6 -2l-12 -3s-9 -1 -13 -1c0 -4 -2 -13 1 -17c6 -7 21 -7 29 -10z" />
- <glyph glyph-name="ion-ios7-person-outline" unicode="&#xf1c1;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-person-outline" unicode="&#xf47d;" horiz-adv-x="320"
d="M106 246v0v0zM267 84c13 -5 53 -20 53 -52h-160h-160c0 32 40 47 53 52s31 6 43 9c7 2 17 5 20 9s1 41 1 41s-6 10 -9 18s-7 32 -7 32s-7 0 -9 12c-2 13 -6 17 -6 27c0 9 5 10 5 10v0s-4 13 -5 42c-1 34 25 68 74 68s75 -34 74 -68c-1 -29 -5 -42 -5 -42v0s5 -1 5 -10
c0 -10 -3 -15 -6 -28c-2 -12 -9 -12 -9 -12s-4 -23 -7 -31s-9 -18 -9 -18s-2 -37 1 -41s13 -7 20 -9c12 -3 30 -4 43 -9zM160 48v0h137c-2 3 -4 6 -8 8c-7 5 -16 9 -27 13c-7 2 -17 4 -26 5c-6 1 -10 2 -15 3c-3 1 -21 5 -29 15c-4 5 -6 12 -6 32c0 10 1 20 1 20v4l2 4
c1 2 6 9 8 15c2 5 5 19 6 28c0 0 0 -1 1 4s8 4 9 8s3 7 5 18s-5 12 -5 17c0 4 1 5 1 5v0c0 1 4 14 4 38c0 13 -5 26 -14 35c-11 11 -25 16 -44 16c-18 0 -34 -5 -45 -16c-9 -9 -13 -22 -13 -35c1 -24 4 -37 4 -38v0s1 -3 0 -6c-1 -5 -6 -5 -4 -16s4 -14 5 -18s8 -3 9 -8
s1 -4 1 -4c1 -9 4 -23 6 -28c2 -6 6 -13 8 -15l2 -4v-4s1 -10 1 -20c0 -20 -2 -27 -6 -32c-8 -10 -26 -14 -29 -15c-5 -1 -10 -2 -16 -3c-9 -1 -18 -3 -25 -5c-11 -4 -20 -8 -27 -13c-4 -2 -6 -5 -8 -8h137z" />
- <glyph glyph-name="ion-ios7-person" unicode="&#xf1c2;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-person" unicode="&#xf47e;" horiz-adv-x="320"
d="M267 84c13 -5 53 -20 53 -52h-160h-160c0 32 40 47 53 52s31 6 43 9c7 2 17 5 20 9s1 41 1 41s-6 10 -9 18s-7 32 -7 32s-7 0 -9 12c-2 13 -6 17 -6 27c0 9 5 10 5 10v0s-4 13 -5 42c-1 34 25 68 74 68s75 -34 74 -68c-1 -29 -5 -42 -5 -42v0s5 -1 5 -10
c0 -10 -3 -15 -6 -28c-2 -12 -9 -12 -9 -12s-4 -23 -7 -31s-9 -18 -9 -18s-2 -37 1 -41s13 -7 20 -9c12 -3 30 -4 43 -9z" />
- <glyph glyph-name="ion-ios7-personadd-outline" unicode="&#xf1c3;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-personadd-outline" unicode="&#xf47f;" horiz-adv-x="320"
d="M320 295v-14h-25v-25h-14v25h-25v14h25v25h14v-25h25zM106 246v0v0zM267 84c13 -5 53 -20 53 -52h-160h-160c0 32 40 47 53 52s31 6 43 9c7 2 17 5 20 9s1 41 1 41s-6 10 -9 18s-7 32 -7 32s-7 0 -9 12c-2 13 -6 17 -6 27c0 9 5 10 5 10v0s-4 13 -5 42c-1 34 25 68 74 68
s75 -34 74 -68c-1 -29 -5 -42 -5 -42v0s5 -1 5 -10c0 -10 -3 -15 -6 -28c-2 -12 -9 -12 -9 -12s-4 -23 -7 -31s-9 -18 -9 -18s-2 -37 1 -41s13 -7 20 -9c12 -3 30 -4 43 -9zM160 48v0h137c-2 3 -4 6 -8 8c-7 5 -16 9 -27 13c-7 2 -17 4 -26 5c-6 1 -10 2 -15 3
c-3 1 -21 5 -29 15c-4 5 -6 12 -6 32c0 10 1 20 1 20v4l2 4c1 2 6 9 8 15c2 5 5 19 6 28c0 0 0 -1 1 4s8 4 9 8s3 7 5 18s-5 12 -5 17c0 4 1 5 1 5v0c0 1 4 14 4 38c0 13 -5 26 -14 35c-11 11 -25 16 -44 16c-18 0 -34 -5 -45 -16c-9 -9 -13 -22 -13 -35c1 -24 4 -37 4 -38
v0s1 -3 0 -6c-1 -5 -6 -5 -4 -16s4 -14 5 -18s8 -3 9 -8s1 -4 1 -4c1 -9 4 -23 6 -28c2 -6 6 -13 8 -15l2 -4v-4s1 -10 1 -20c0 -20 -2 -27 -6 -32c-8 -10 -26 -14 -29 -15c-5 -1 -10 -2 -16 -3c-9 -1 -18 -3 -25 -5c-11 -4 -20 -8 -27 -13c-4 -2 -6 -5 -8 -8h137z" />
- <glyph glyph-name="ion-ios7-personadd" unicode="&#xf1c4;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-personadd" unicode="&#xf480;" horiz-adv-x="320"
d="M320 295v-14h-25v-25h-14v25h-25v14h25v25h14v-25h25zM267 84c13 -5 53 -20 53 -52h-160h-160c0 32 40 47 53 52s31 6 43 9c7 2 17 5 20 9s1 41 1 41s-6 10 -9 18s-7 32 -7 32s-7 0 -9 12c-2 13 -6 17 -6 27c0 9 5 10 5 10v0s-4 13 -5 42c-1 34 25 68 74 68
s75 -34 74 -68c-1 -29 -5 -42 -5 -42v0s5 -1 5 -10c0 -10 -3 -15 -6 -28c-2 -12 -9 -12 -9 -12s-4 -23 -7 -31s-9 -18 -9 -18s-2 -37 1 -41s13 -7 20 -9c12 -3 30 -4 43 -9z" />
- <glyph glyph-name="ion-ios7-photos-outline" unicode="&#xf1c5;"
+ <glyph glyph-name="ion-ios-photos-outline" unicode="&#xf481;"
d="M64 320h384v-320h-384v320zM432 16v288h-352v-288h352zM0 384h384v-48h-16v32h-352v-288h32v-16h-48v320z" />
- <glyph glyph-name="ion-ios7-photos" unicode="&#xf1c6;"
+ <glyph glyph-name="ion-ios-photos" unicode="&#xf482;"
d="M64 320h384v-320h-384v320zM384 384v-48h-336v-272h-48v320h384z" />
- <glyph glyph-name="ion-ios7-pie-outline" unicode="&#xf28a;"
-d="M32 176h208v208c5 0 11 -1 16 -1c17 -1 33 -4 49 -9c24 -8 46 -21 65 -36c47 -38 78 -96 78 -162c0 -115 -93 -208 -208 -208c-66 0 -124 31 -162 78c-15 19 -28 41 -36 65c-5 16 -8 32 -9 49c0 5 -1 11 -1 16zM49 160c2 -20 6 -40 14 -59c7 -16 15 -30 26 -44
-c5 -6 10 -12 15 -17c12 -12 24 -22 38 -30c7 -4 15 -8 23 -11c24 -10 49 -15 75 -15s51 5 75 15c23 10 43 23 61 41s31 38 41 61c10 24 15 49 15 75s-5 51 -15 75c-3 8 -8 15 -12 22c-8 14 -17 27 -29 39c-5 5 -11 10 -17 15c-14 11 -28 19 -44 26c-19 8 -39 12 -59 14v-191
-v-16h-16h-191zM0 208c0 115 93 208 208 208c5 0 11 -1 16 -1v-207v-16h-16h-207c0 5 -1 11 -1 16zM16 208h192v192c-26 0 -51 -5 -75 -15c-23 -10 -43 -23 -61 -41s-31 -38 -41 -61c-10 -24 -15 -49 -15 -75z" />
- <glyph glyph-name="ion-ios7-pie" unicode="&#xf28b;"
-d="M32 176h208v208c5 0 11 -1 16 -1c17 -1 33 -4 49 -9c24 -8 46 -21 65 -36c47 -38 78 -96 78 -162c0 -115 -93 -208 -208 -208c-66 0 -124 31 -162 78c-15 19 -28 41 -36 65c-5 16 -8 32 -9 49c0 5 -1 11 -1 16zM0 208c0 115 93 208 208 208c5 0 11 -1 16 -1v-207v-16h-16
-h-207c0 5 -1 11 -1 16z" />
- <glyph glyph-name="ion-ios7-play-outline" unicode="&#xf1c7;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-pie-outline" unicode="&#xf483;"
+d="M256 367v0v-207v-12l-12 -4l-180 -45c6 -13 13 -25 21 -36c12 -16 25 -30 41 -42c33 -24 73 -37 114 -37c26 0 51 5 75 15c23 10 43 23 61 41s31 38 41 61c10 24 15 49 15 75c0 51 -20 100 -56 136c-32 32 -75 51 -120 55zM240 384v0c115 0 208 -93 208 -208
+s-93 -208 -208 -208c-92 0 -171 60 -198 143l198 49v224zM208 400c-31 -1 -60 -7 -85 -18c-24 -11 -44 -26 -61 -46c-29 -34 -46 -80 -46 -127v0v0c0 -13 3 -46 12 -70l180 46v215zM224 416v0v-244l-205 -52c-19 32 -19 89 -19 89c0 91 58 207 218 207h6z" />
+ <glyph glyph-name="ion-ios-pie" unicode="&#xf484;"
+d="M240 384v0c115 0 208 -93 208 -208s-93 -208 -208 -208c-92 0 -171 60 -198 143l198 49v224zM224 416v0v-244l-205 -52c-19 32 -19 89 -19 89c0 91 58 207 218 207h6z" />
+ <glyph glyph-name="ion-ios-pint-outline" unicode="&#xf485;" horiz-adv-x="224"
+d="M224 278c0 -98 -32 -101 -32 -181c0 -40 16 -71 16 -99c0 -27 -9 -30 -32 -30h-128c-23 0 -32 2 -32 29c0 28 16 60 16 100c0 80 -32 83 -32 181c0 21 1 89 19 125c4 9 13 13 32 13h122c19 0 28 -4 32 -13c18 -36 19 -104 19 -125zM34 396c-8 -16 -14 -43 -17 -76h190
+c-3 33 -9 60 -17 76c-1 2 -1 1 -2 2c-2 1 -6 2 -15 2h-122c-9 0 -13 -1 -15 -2c-1 -1 -1 0 -2 -2zM191 -15c0 1 1 5 1 13c0 11 -4 23 -7 37c-4 18 -9 39 -9 62c0 41 8 64 16 86c8 23 16 46 16 95c0 9 -1 18 -1 26h-190c0 -8 -1 -17 -1 -26c0 -49 8 -72 16 -95
+c8 -22 16 -45 16 -86c0 -23 -5 -44 -9 -62c-3 -14 -7 -26 -7 -37c0 -8 1 -12 1 -13c2 -1 7 -1 15 -1h128c8 0 13 0 15 1z" />
+ <glyph glyph-name="ion-ios-pint" unicode="&#xf486;" horiz-adv-x="224"
+d="M224 278c0 -98 -32 -101 -32 -181c0 -40 16 -71 16 -99c0 -27 -9 -30 -32 -30h-128c-23 0 -32 2 -32 29c0 28 16 60 16 100c0 80 -32 83 -32 181c0 21 1 89 19 125c4 9 13 13 32 13h122c19 0 28 -4 32 -13c18 -36 19 -104 19 -125zM34 396c-8 -16 -14 -43 -17 -76h190
+c-3 33 -9 60 -17 76c-1 2 -1 1 -2 2c-2 1 -6 2 -15 2h-122c-9 0 -13 -1 -15 -2c-1 -1 -1 0 -2 -2z" />
+ <glyph glyph-name="ion-ios-play-outline" unicode="&#xf487;" horiz-adv-x="256"
d="M16 323v-262l210 131zM0 352v0l256 -160l-256 -160v320z" />
- <glyph glyph-name="ion-ios7-play" unicode="&#xf1c8;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-play" unicode="&#xf488;" horiz-adv-x="256"
d="M0 352v0l256 -160l-256 -160v320z" />
- <glyph glyph-name="ion-ios7-plus-empty" unicode="&#xf1c9;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-plus-empty" unicode="&#xf489;" horiz-adv-x="256"
d="M256 183h-120v-119h-17v119h-119v17h119v120h17v-120h120v-17z" />
- <glyph glyph-name="ion-ios7-plus-outline" unicode="&#xf1ca;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-plus-outline" unicode="&#xf48a;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM216 320v-120h120v-17h-120v-119h-17v119h-119v17h119v120h17z" />
- <glyph glyph-name="ion-ios7-plus" unicode="&#xf1cb;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-plus" unicode="&#xf48b;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM336 183v17h-120v120h-17v-120h-119v-17h119v-119h17v119h120z" />
- <glyph glyph-name="ion-ios7-pricetag-outline" unicode="&#xf28c;" horiz-adv-x="384"
-d="M143 368h-111c-9 0 -16 -7 -16 -16v-108c0 -6 3 -12 7 -16l213 -207h1v-1c3 -3 7 -4 11 -4s8 1 11 4l104 105c3 3 5 7 5 11s-2 8 -5 11v1v0l-204 213c-4 4 -10 7 -16 7zM143 384v0c10 0 20 -4 28 -12l204 -213c6 -6 9 -15 9 -23s-3 -16 -9 -22l-105 -105
-c-6 -6 -14 -9 -22 -9s-17 3 -23 9l-214 207c-7 7 -11 17 -11 28v108c0 18 14 32 32 32h111zM96 320c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM96 336v0c26 0 48 -22 48 -48s-22 -48 -48 -48s-48 22 -48 48s22 48 48 48z" />
- <glyph glyph-name="ion-ios7-pricetag" unicode="&#xf28d;" horiz-adv-x="384"
-d="M64 288c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32zM375 159c6 -6 9 -14 9 -23s-3 -16 -9 -22l-105 -105c-6 -6 -13 -9 -22 -9s-17 3 -23 9l-214 207c-8 8 -11 17 -11 28v108c0 9 3 17 9 23s14 9 23 9h111c11 0 20 -4 28 -12zM96 240
-c13 0 25 5 34 14s14 21 14 34s-5 25 -14 34s-21 14 -34 14s-25 -5 -34 -14s-14 -21 -14 -34s5 -25 14 -34s21 -14 34 -14z" />
- <glyph glyph-name="ion-ios7-pricetags-outline" unicode="&#xf332;"
+ <glyph glyph-name="ion-ios-pricetag-outline" unicode="&#xf48c;" horiz-adv-x="416"
+d="M416 416v-160l-256 -288l-160 160l256 288h160zM400 264v136h-136l-240 -272l136 -136zM320 288c-18 0 -32 14 -32 32s14 32 32 32s32 -14 32 -32s-14 -32 -32 -32zM320 336c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16z" />
+ <glyph glyph-name="ion-ios-pricetag" unicode="&#xf48d;" horiz-adv-x="416"
+d="M304 320c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16zM256 416h160v-160l-256 -288l-160 160zM320 288c9 0 16 4 22 10s10 13 10 22s-4 16 -10 22s-13 10 -22 10s-16 -4 -22 -10s-10 -13 -10 -22s4 -16 10 -22s13 -10 22 -10z" />
+ <glyph glyph-name="ion-ios-pricetags-outline" unicode="&#xf48e;"
d="M416 384h32v-144l-240 -272l-25 24l-23 -24l-160 160l256 288h160v-32zM160 -9l12 12l11 12l217 248v105v16v16h-137l-241 -272zM432 247v121h-16v-112l-221 -253l13 -12zM320 288c-18 0 -32 14 -32 32s14 32 32 32s32 -14 32 -32s-14 -32 -32 -32zM320 336
c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16z" />
- <glyph glyph-name="ion-ios7-pricetags" unicode="&#xf333;"
+ <glyph glyph-name="ion-ios-pricetags" unicode="&#xf48f;"
d="M432 384h16v-144l-240 -272l-13 13l237 266v137zM256 416h160v-32v-16v-112l-221 -253l-12 -11l-23 -24l-160 160zM320 288c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM304 320c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16z" />
- <glyph glyph-name="ion-ios7-printer-outline" unicode="&#xf1cc;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-printer-outline" unicode="&#xf490;" horiz-adv-x="416"
d="M384 336c18 0 32 -13 32 -31v-159c0 -18 -14 -32 -32 -32h-48v-114h-256v114h-48c-18 0 -32 14 -32 32v159c0 18 14 31 32 31h32v48h288v-48h32zM80 368v-32h256v32h-256zM320 16v192h-224v-192h224zM400 146v159c0 9 -7 15 -16 15v0h-352c-9 0 -16 -6 -16 -15v-159
c0 -9 7 -16 16 -16h48v94h256v-94h48c9 0 16 7 16 16z" />
- <glyph glyph-name="ion-ios7-printer" unicode="&#xf1cd;" horiz-adv-x="416"
-d="M384 336c18 0 32 -13 32 -31v-159c0 -18 -14 -32 -32 -32h-32v126h-288v-126h-32c-18 0 -32 14 -32 32v159c0 18 14 31 32 31h32v48h288v-48h32zM80 0v224h256v-224h-256z" />
- <glyph glyph-name="ion-ios7-pulse-strong" unicode="&#xf334;" horiz-adv-x="480"
+ <glyph glyph-name="ion-ios-printer" unicode="&#xf491;" horiz-adv-x="416"
+d="M80 0v224h256v-224h-256zM80 -0v224h256v-224h-256zM64 352v32h288v-32h-288zM385 336c18 0 31 -14 31 -31v-158c0 -17 -13 -34 -31 -34h-33v126h-288v-126h-31c-18 0 -33 17 -33 34v158c0 17 15 31 33 31h352z" />
+ <glyph glyph-name="ion-ios-pulse-strong" unicode="&#xf492;" horiz-adv-x="480"
d="M432 175c27 0 48 -20 48 -47s-21 -49 -48 -49c-21 0 -38 13 -45 31h-51c-7 0 -13 4 -15 11l-16 47l-50 -173c-2 -7 -8 -11 -15 -11h-1c-7 0 -14 5 -15 12l-51 308l-45 -182c-2 -7 -9 -12 -16 -12h-112v32h99l61 245c2 7 8 13 16 13s15 -7 16 -14l52 -314l45 155
c2 7 8 11 15 11v0c7 0 13 -4 15 -11l29 -85h38c6 19 25 33 46 33z" />
- <glyph glyph-name="ion-ios7-pulse" unicode="&#xf335;"
+ <glyph glyph-name="ion-ios-pulse" unicode="&#xf493;"
d="M416 160c18 0 32 -14 32 -32s-14 -32 -32 -32c-15 0 -27 10 -31 23h-65c-3 0 -7 2 -8 5l-23 72l-57 -198c-1 -3 -4 -6 -8 -6v0c-4 0 -7 3 -8 7l-58 346l-54 -220c-1 -4 -4 -6 -8 -6h-96v16h90l62 251c1 4 4 6 8 6s7 -3 8 -7l58 -349l54 190c1 3 4 5 8 5s7 -2 8 -5l30 -91
h59c3 14 16 25 31 25z" />
- <glyph glyph-name="ion-ios7-rainy-outline" unicode="&#xf1ce;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-rainy-outline" unicode="&#xf494;" horiz-adv-x="288"
d="M220 269c38 0 68 -33 68 -71c0 -29 -19 -56 -45 -66l-55 -80c-2 -2 -5 -4 -8 -4c-5 0 -8 3 -8 8c0 2 1 4 2 6l46 66v0h-35l-31 -44c-2 -2 -4 -4 -7 -4c-5 0 -9 3 -9 8c0 2 1 3 2 5l25 35h-37l-53 -76c-2 -2 -4 -4 -7 -4c-5 0 -9 3 -9 8c0 2 2 4 3 6l46 66h-36l-32 -44
c-2 -2 -4 -4 -7 -4c-5 0 -8 3 -8 8c0 2 1 4 2 6l25 34c-29 2 -52 27 -52 56c0 28 22 58 50 60c0 3 -1 5 -1 8c0 46 31 84 82 84c45 0 73 -31 81 -68c3 0 5 1 8 1zM220 146c28 0 52 24 52 52s-24 54 -52 54h-6l-15 -2l-3 15c-3 14 -11 31 -23 40c-12 10 -26 14 -41 14
c-36 0 -66 -31 -66 -67v-12v-10c-6 0 -12 -2 -14 -2c-20 -3 -35 -23 -35 -43c0 -10 4 -20 11 -27s16 -12 26 -12h124v0v0h42z" />
- <glyph glyph-name="ion-ios7-rainy" unicode="&#xf1cf;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-rainy" unicode="&#xf495;" horiz-adv-x="288"
d="M220 269c38 0 68 -33 68 -71c0 -29 -19 -56 -45 -66l-55 -80c-2 -2 -5 -4 -8 -4c-5 0 -8 3 -8 8c0 2 1 4 2 6l46 66v0h-35l-31 -44c-2 -2 -4 -4 -7 -4c-5 0 -9 3 -9 8c0 2 1 3 2 5l25 35h-37l-53 -76c-2 -2 -4 -4 -7 -4c-5 0 -9 3 -9 8c0 2 2 4 3 6l46 66h-36l-32 -44
c-2 -2 -4 -4 -7 -4c-5 0 -8 3 -8 8c0 2 1 4 2 6l25 34c-29 2 -52 27 -52 56c0 28 22 58 50 60c0 3 -1 5 -1 8c0 46 31 84 82 84c45 0 73 -31 81 -68c3 0 5 1 8 1z" />
- <glyph glyph-name="ion-ios7-recording-outline" unicode="&#xf1d0;" horiz-adv-x="480"
+ <glyph glyph-name="ion-ios-recording-outline" unicode="&#xf496;" horiz-adv-x="480"
d="M370 304c61 0 110 -50 110 -112s-49 -112 -110 -112h-260c-61 0 -110 50 -110 112s49 112 110 112s110 -50 110 -112c0 -40 -21 -75 -53 -95h146c-32 20 -53 55 -53 95c0 62 49 112 110 112zM16 192c0 -53 42 -95 94 -95s93 42 93 95s-41 95 -93 95s-94 -42 -94 -95z
M370 97c52 0 94 42 94 95s-42 95 -94 95s-93 -42 -93 -95s41 -95 93 -95zM368 240c-26 0 -48 -22 -48 -48s22 -48 48 -48s48 22 48 48s-22 48 -48 48zM368 256v0c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM112 240c-26 0 -48 -22 -48 -48
s22 -48 48 -48s48 22 48 48s-22 48 -48 48zM112 256v0c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64z" />
- <glyph glyph-name="ion-ios7-recording" unicode="&#xf1d1;" horiz-adv-x="480"
+ <glyph glyph-name="ion-ios-recording" unicode="&#xf497;" horiz-adv-x="480"
d="M370 304c61 0 110 -50 110 -112s-49 -112 -110 -112h-260c-61 0 -110 50 -110 112s49 112 110 112s110 -50 110 -112c0 -40 -21 -76 -53 -95h146c-32 19 -53 55 -53 95c0 62 49 112 110 112zM112 128c35 0 64 29 64 64s-29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64z
M368 128c35 0 64 29 64 64s-29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64zM368 240c26 0 48 -22 48 -48s-22 -48 -48 -48s-48 22 -48 48s22 48 48 48zM112 240c26 0 48 -22 48 -48s-22 -48 -48 -48s-48 22 -48 48s22 48 48 48z" />
- <glyph glyph-name="ion-ios7-redo-outline" unicode="&#xf1d2;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-redo-outline" unicode="&#xf498;" horiz-adv-x="384"
d="M0 48v32c0 17 -3 83 49 136c35 36 80 53 143 56v80l192 -128l-192 -128v80c-40 -1 -63 -9 -87 -20c-31 -14 -55 -44 -75 -77l-20 -31h-10zM208 256c-201 0 -192 -169 -192 -169c48 81 101 105 192 105v-65l148 97l-148 97v-65z" />
- <glyph glyph-name="ion-ios7-redo" unicode="&#xf1d3;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-redo" unicode="&#xf499;" horiz-adv-x="384"
d="M0 48v32c0 17 -3 83 49 136c35 36 80 53 143 56v80l192 -128l-192 -128v80c-40 -1 -63 -9 -87 -20c-31 -14 -55 -44 -75 -77l-20 -31h-10z" />
- <glyph glyph-name="ion-ios7-refresh-empty" unicode="&#xf1d4;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-refresh-empty" unicode="&#xf49a;" horiz-adv-x="256"
d="M128 64c-71 0 -128 57 -128 128s57 128 128 128v44l96 -64l-96 -56v56c-60 0 -108 -48 -108 -108s48 -108 108 -108s108 48 108 108h20c0 -71 -57 -128 -128 -128z" />
- <glyph glyph-name="ion-ios7-refresh-outline" unicode="&#xf1d5;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-refresh-outline" unicode="&#xf49b;" horiz-adv-x="416"
d="M316 192v0h20c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128v44l96 -64l-96 -56v56c-60 0 -108 -48 -108 -108s48 -108 108 -108s108 48 108 108zM208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1
c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191z" />
- <glyph glyph-name="ion-ios7-refresh" unicode="&#xf1d6;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-refresh" unicode="&#xf49c;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 64c71 0 128 57 128 128h-20c0 -60 -48 -108 -108 -108s-108 48 -108 108s48 108 108 108v-56l96 56l-96 64v-44c-71 0 -128 -57 -128 -128s57 -128 128 -128z" />
- <glyph glyph-name="ion-ios7-reload" unicode="&#xf28e;" horiz-adv-x="512"
-d="M256 384c105.9 0 191.7 -85.7002 191.9 -191.5l55 52.5l9 -9.09961l-70.3008 -67.9004l-66.5996 67.9004l9 9.09961l51.0996 -52.4004c-0.299805 98.5 -80.5 178.601 -179.1 178.601c-98.7998 0 -179.2 -80.4004 -179.2 -179.2s80.4004 -179.2 179.2 -179.2
-c78.5996 0 145.5 51 169.5 121.601l12.4004 -3.5c-25.6006 -76.1006 -97.3008 -130.9 -181.9 -130.9c-106 0 -192 86 -192 192s86 192 192 192z" />
- <glyph glyph-name="ion-ios7-reverse-camera-outline" unicode="&#xf336;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-reload" unicode="&#xf49d;"
+d="M192 384c106 0 192 -86 192 -192l55 53l9 -9l-70 -68l-67 68l9 9l51 -52c0 98 -80 178 -179 178s-179 -80 -179 -179s80 -179 179 -179c79 0 146 50 170 121l12 -3c-26 -76 -97 -131 -182 -131c-106 0 -192 86 -192 192s86 192 192 192z" />
+ <glyph glyph-name="ion-ios-reverse-camera-outline" unicode="&#xf49e;" horiz-adv-x="384"
d="M238 129l2 2l11 -12l-2 -2c-16 -14 -36 -21 -57 -21c-45 0 -82 36 -87 78h-30l38 50l39 -50h-31c5 -33 35 -62 71 -62c17 0 33 6 46 17zM252 249c16 -14 25 -37 27 -57h30l-38 -51l-39 51h31c-5 35 -35 64 -71 64c-17 0 -33 -6 -46 -17l-2 -2l-11 12l2 2
c16 14 36 21 57 21c22 0 44 -8 60 -23zM354 288c18 0 30 -14 30 -31v-176c0 -17 -12 -33 -30 -33h-320c-18 0 -34 16 -34 33v176c0 17 16 31 34 31h13v16h34v-16h13c32 36 43 48 55 48h88c12 0 23 -12 55 -48h62zM368 81v176c0 9 -5 15 -14 15h-62h-6s-4 1 -6 3s-6 8 -9 11
c-12 13 -21 24 -27 30c-5 5 -7 4 -7 4h-88s-1 0 -6 -4c-6 -5 -15 -14 -26 -27c-3 -4 -8 -11 -11 -14s-4 -3 -6 -3h-6h-60c-9 0 -18 -7 -18 -15v-176c0 -9 9 -17 18 -17h320c8 0 14 8 14 17z" />
- <glyph glyph-name="ion-ios7-reverse-camera" unicode="&#xf337;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-reverse-camera" unicode="&#xf49f;" horiz-adv-x="384"
d="M354 288c18 0 30 -14 30 -31v-176c0 -17 -12 -33 -30 -33h-320c-18 0 -34 16 -34 33v176c0 17 16 31 34 31h13v16h34v-16h13c32 36 43 48 55 48h88c12 0 23 -12 55 -48h62zM249 117l2 2l-11 12l-2 -2c-13 -11 -29 -17 -46 -17c-36 0 -66 29 -71 62h31l-39 50l-38 -50h30
c5 -42 42 -78 87 -78c21 0 41 7 57 21zM271 141l38 51h-30c-2 20 -11 43 -27 57c-16 15 -38 23 -60 23c-21 0 -41 -7 -57 -21l-2 -2l11 -12l2 2c13 11 29 17 46 17c36 0 66 -29 71 -64h-31z" />
- <glyph glyph-name="ion-ios7-rewind-outline" unicode="&#xf1d7;"
+ <glyph glyph-name="ion-ios-rewind-outline" unicode="&#xf4a0;"
d="M432 293l-184 -101l184 -101v202zM208 292v0l-176 -100l176 -100v95v27v78zM224 320v0v-123l224 123v-256l-224 123v-123l-224 128z" />
- <glyph glyph-name="ion-ios7-rewind" unicode="&#xf1d8;"
+ <glyph glyph-name="ion-ios-rewind" unicode="&#xf4a1;"
d="M224 320v0v-123l224 123v-256l-224 123v-123l-224 128z" />
- <glyph glyph-name="ion-ios7-search-strong" unicode="&#xf1d9;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-rose-outline" unicode="&#xf4a2;" horiz-adv-x="320"
+d="M284 295c-4 -1 -9 -3 -13 -4c-37 -11 -71 -24 -103 -39c-17 -8 -24 -12 -44 -24l-7 -4c-31 -18 -50 -33 -63 -51c-15 -21 -22 -45 -22 -77c0 -16 3 -30 9 -44c6 -13 14 -26 25 -36c23 -21 55 -32 94 -32s71 11 94 32c11 10 19 23 25 36c6 14 9 28 9 44c0 20 -5 40 -11 60
+c-11 40 -23 83 7 139zM320 320v0c-77 -96 -16 -151 -16 -224s-56 -128 -144 -128s-144 55 -144 128s35 109 93 142c25 14 33 19 52 28c30 14 65 28 105 40c17 5 35 10 54 14zM38 325c14 -28 18 -57 19 -83c9 7 20 13 30 20c7 4 14 9 21 13c5 3 10 6 16 9c-5 4 -11 7 -17 11
+c-22 13 -48 23 -69 30zM0 352v0s66 -15 115 -43c15 -8 28 -18 37 -29c-12 -6 -24 -12 -36 -19c-7 -4 -14 -8 -20 -12c-25 -16 -44 -31 -57 -42c5 41 2 98 -39 145zM249 367c-8 -1 -20 -2 -35 -7c-25 -8 -47 -20 -64 -36c8 -6 15 -12 21 -18c29 12 65 26 95 34
+c-5 10 -12 20 -17 27zM256 384v0s26 -32 32 -55c-33 -8 -84 -25 -121 -42l-3 3c-9 11 -22 22 -39 32c52 60 131 62 131 62zM85 394c-6 -10 -10 -20 -14 -28c12 -4 22 -10 36 -17c4 5 9 10 14 14c-13 15 -27 25 -36 31zM80 416v0s35 -16 64 -56c-12 -9 -23 -20 -33 -31
+c-26 13 -40 21 -61 27c5 15 15 38 30 60z" />
+ <glyph glyph-name="ion-ios-rose" unicode="&#xf4a3;" horiz-adv-x="320"
+d="M320 320v0c-77 -96 -16 -151 -16 -224s-56 -128 -144 -128s-144 55 -144 128s35 109 93 142c25 14 33 19 52 28c30 14 65 28 105 40c17 5 35 10 54 14zM0 352v0s66 -15 115 -43c15 -8 28 -18 37 -29c-12 -6 -24 -12 -36 -19c-7 -4 -14 -8 -20 -12
+c-25 -16 -44 -31 -57 -42c5 41 2 98 -39 145zM256 384v0s26 -32 32 -55c-33 -8 -84 -25 -121 -42l-3 3c-9 11 -22 22 -39 32c52 60 131 62 131 62zM80 416v0s35 -16 64 -56c-12 -9 -23 -20 -33 -31c-26 13 -40 21 -61 27c5 15 15 38 30 60z" />
+ <glyph glyph-name="ion-ios-search-strong" unicode="&#xf4a4;" horiz-adv-x="384"
d="M280 150l-4 -7l108 -109l-34 -34l-108 109l-7 -5c-24 -15 -53 -25 -83 -25c-84 0 -152 69 -152 153s68 152 152 152s152 -68 152 -152c0 -30 -9 -58 -24 -82zM237 317c-23 23 -53 35 -85 35s-62 -12 -85 -35s-35 -53 -35 -85s12 -62 35 -85s53 -35 85 -35s62 12 85 35
s36 53 36 85s-13 62 -36 85z" />
- <glyph glyph-name="ion-ios7-search" unicode="&#xf1da;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-search" unicode="&#xf4a5;" horiz-adv-x="384"
d="M384 23l-23 -23l-113 113c-26 -21 -60 -33 -96 -33c-84 0 -152 68 -152 152s68 152 152 152s152 -68 152 -152c0 -36 -12 -69 -33 -95zM56 135c26 -26 60 -39 96 -39s70 14 96 40s40 60 40 96s-14 70 -40 96s-60 40 -96 40s-70 -14 -96 -40s-40 -60 -40 -96
s14 -71 40 -97z" />
- <glyph glyph-name="ion-ios7-settings-strong" unicode="&#xf338;"
+ <glyph glyph-name="ion-ios-settings-strong" unicode="&#xf4a6;"
d="M0 72h283c6 14 21 24 37 24s31 -10 37 -24h91v-32h-91c-6 -14 -21 -24 -37 -24s-31 10 -37 24h-283zM0 208h91c6 14 21 24 37 24s31 -10 37 -24h283v-32h-283c-6 -14 -21 -24 -37 -24s-31 10 -37 24h-91zM0 344h283c6 14 21 24 37 24s31 -10 37 -24h91v-32h-91
c-6 -14 -21 -24 -37 -24s-31 10 -37 24h-283z" />
- <glyph glyph-name="ion-ios7-settings" unicode="&#xf339;"
+ <glyph glyph-name="ion-ios-settings" unicode="&#xf4a7;"
d="M320 344c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16zM320 360v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM320 72c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16zM320 88v0c18 0 32 -14 32 -32s-14 -32 -32 -32
s-32 14 -32 32s14 32 32 32zM128 208c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16zM128 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM175 200h273v-16h-273c0 3 1 5 1 8s-1 5 -1 8zM80 192c0 -3 1 -5 1 -8h-81v16h81
c0 -3 -1 -5 -1 -8zM367 64h81v-16h-81c0 3 1 5 1 8s-1 5 -1 8zM272 56c0 -3 1 -5 1 -8h-273v16h273c0 -3 -1 -5 -1 -8zM367 336h81v-16h-81c0 3 1 5 1 8s-1 5 -1 8zM273 336c0 -3 -1 -5 -1 -8s1 -5 1 -8h-273v16h273z" />
- <glyph glyph-name="ion-ios7-shrink" unicode="&#xf30e;" horiz-adv-x="364"
-d="M364 18l-8 -8l-92 92l-50 -50v108h108l-50 -50zM0 366l8 8l92 -92l50 50v-108h-108l50 50z" />
- <glyph glyph-name="ion-ios7-skipbackward-outline" unicode="&#xf1db;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-shuffle-strong" unicode="&#xf4a8;" horiz-adv-x="384"
+d="M301 296c-85 0 -119 -64 -152 -126c-1 -3 -3 -5 -4 -8l-1 -1c-2 -3 -2 -5 -4 -8c-21 -38 -43 -68 -68 -83c-15 -9 -34 -18 -72 -18v32c45 0 76 18 112 84c2 3 2 6 4 9h1c1 2 3 4 4 7c34 64 76 144 180 144h15l-52 43l21 25l99 -84l-99 -82l-21 24l51 42h-14zM285 154
+l99 -82l-99 -84l-21 25l52 43h-15c-78 0 -122 45 -153 95l18 33c29 -51 64 -96 135 -96h14l-51 42zM112 216c-36 66 -67 84 -112 84v32c38 0 57 -9 72 -18c25 -15 47 -44 67 -81c-7 -11 -13 -22 -19 -33c-1 2 -2 5 -3 7h-1c-2 3 -2 6 -4 9z" />
+ <glyph glyph-name="ion-ios-shuffle" unicode="&#xf4a9;" horiz-adv-x="384"
+d="M298 241l-10 12l62 51h-46c-93 0 -129 -75 -164 -139c-2 -3 -3 -6 -5 -9c-20 -37 -41 -61 -65 -75c-14 -8 -33 -17 -70 -17v16c48 0 83 14 121 84c2 3 3 6 5 9c35 65 75 147 178 147h46l-62 52l10 12l86 -72zM135 228c0 -1 1 -2 1 -3c-3 -5 -6 -11 -9 -16c0 1 -1 1 -1 2
+c-2 3 -3 6 -5 9c-38 70 -73 84 -121 84v16c37 0 56 -9 70 -17c24 -14 45 -38 65 -75zM298 143l86 -71l-86 -72l-10 12l62 52h-46c-76 0 -118 45 -149 95c1 2 2 5 3 7c2 3 4 7 6 10c30 -50 67 -96 140 -96h46l-62 51z" />
+ <glyph glyph-name="ion-ios-skipbackward-outline" unicode="&#xf4aa;" horiz-adv-x="320"
d="M0 352h79v-142l241 142v-320l-241 142v-142h-79v320zM80 192l7 -4l217 -128v264v0l-217 -128zM16 336v-288h47v126v8v28v126h-47z" />
- <glyph glyph-name="ion-ios7-skipbackward" unicode="&#xf1dc;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-skipbackward" unicode="&#xf4ab;" horiz-adv-x="320"
d="M0 352h79v-142l241 142v-320l-241 142v-142h-79v320z" />
- <glyph glyph-name="ion-ios7-skipforward-outline" unicode="&#xf1dd;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-skipforward-outline" unicode="&#xf4ac;" horiz-adv-x="320"
d="M241 352h79v-320h-79v142l-241 -142v320l241 -142v142zM233 188l7 4l-7 4l-217 128v0v-264zM304 48v288h-47v-126v-28v-8v-126h47z" />
- <glyph glyph-name="ion-ios7-skipforward" unicode="&#xf1de;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-skipforward" unicode="&#xf4ad;" horiz-adv-x="320"
d="M241 352h79v-320h-79v142l-241 -142v320l241 -142v142z" />
- <glyph glyph-name="ion-ios7-snowy" unicode="&#xf309;" horiz-adv-x="256"
+ <glyph glyph-name="ion-ios-snowy" unicode="&#xf4ae;" horiz-adv-x="256"
d="M252 131c4 -2 5 -7 3 -11s-7 -5 -11 -3l-29 17c-2 -8 -2 -16 0 -24c1 -4 -3 -9 -7 -10s-8 2 -9 6c-2 12 -3 24 1 36l-64 36v-73c11 -3 22 -8 31 -16c3 -3 4 -8 1 -11s-8 -4 -11 -1c-6 5 -13 10 -21 12v-33c0 -4 -4 -8 -8 -8s-8 4 -8 8v33c-8 -2 -15 -7 -21 -12
c-3 -3 -8 -2 -11 1s-3 8 0 11c9 8 20 13 32 16v73l-65 -36c4 -12 4 -23 2 -35c-1 -4 -5 -8 -9 -7s-8 6 -7 10c2 8 2 16 0 24l-29 -17c-4 -2 -9 -1 -11 3s-1 9 3 11l29 16c-6 6 -13 10 -21 13c-4 1 -6 6 -5 10c2 4 6 6 10 5c12 -4 22 -11 30 -19l65 36l-65 37
c-8 -9 -18 -15 -30 -19c-4 -1 -9 0 -10 4s1 10 5 11c8 3 15 6 21 12l-29 16c-4 2 -5 7 -3 11s7 5 11 3l29 -16c2 8 2 15 0 23c-1 4 3 9 7 10s8 -2 9 -6c2 -12 1 -25 -2 -36l65 -36v73c-12 3 -23 8 -32 16c-3 3 -3 8 0 11s8 4 11 1c6 -5 13 -10 21 -12v33c0 4 4 8 8 8
s8 -4 8 -8v-33c8 2 15 7 21 12c3 3 8 2 11 -1s2 -8 -1 -11c-9 -8 -20 -13 -31 -16v-73l64 36c-3 11 -4 24 -2 36c1 4 6 7 10 6s7 -6 6 -10c-2 -8 -1 -15 1 -23l29 16c4 2 9 1 11 -3s1 -9 -3 -11l-29 -16c6 -6 13 -10 21 -13c4 -1 6 -6 5 -10s-6 -6 -10 -5
c-12 4 -23 10 -31 19l-64 -36l64 -36c8 8 19 15 31 19c4 1 9 -1 10 -5s-1 -9 -5 -10c-8 -3 -15 -7 -21 -13z" />
- <glyph glyph-name="ion-ios7-speedometer-outline" unicode="&#xf28f;"
-d="M448 163v0v0c0 -63 -27 -120 -70 -160l-2 -3l-37 37l11 11l26 -25c16 17 28 36 38 57c10 23 17 47 18 72h-32v16h32c-1 26 -6 51 -16 75c-9 22 -22 42 -38 59l-28 -28l-6 6l-5 5v0h-1l28 28c-18 17 -38 30 -61 40s-48 14 -73 15v-37h-16v37c-25 -1 -50 -5 -73 -15
-s-43 -23 -61 -40l27 -28v0v0l-5 -5l-6 -6l-28 28c-16 -17 -29 -37 -38 -59c-10 -24 -15 -49 -16 -75h32v-16h-32c1 -25 8 -49 18 -72c9 -21 22 -40 38 -57l25 25l12 -11l-37 -37v1c-44 40 -72 97 -72 161v1v0c0 122 100 221 224 221v0v0h1c124 0 223 -99 223 -221zM208 193
-l110 68l10 -11l-82 -94l-1 -1c-5 -6 -13 -10 -21 -10c-15 0 -27 11 -27 26c0 8 4 15 9 20z" />
- <glyph glyph-name="ion-ios7-speedometer" unicode="&#xf290;"
-d="M224 384c124 0 224 -99 224 -221c0 -64 -28 -122 -72 -163h-304c-44 41 -72 99 -72 163c0 122 100 221 224 221zM246 156l82 94l-10 11l-110 -68l-2 -2c-5 -5 -9 -12 -9 -20c0 -15 12 -26 27 -26c8 0 16 4 21 10zM372 18c35 35 60 87 60 145v0v1c0 84 -52 157 -125 188
-c-25 11 -54 16 -83 16v0v0v0c-29 0 -57 -5 -82 -16c-72 -30 -126 -104 -126 -188v0v-1c0 -50 21 -109 62 -146l1 -1l15 15l19 19l-11 10l-23 -23c-15 16 -23 31 -32 50c-10 21 -15 43 -16 67h29v15h-29c0 23 5 47 15 69c9 20 20 38 35 54l26 -26l5 5l5 5v0v0l-25 26
-c17 16 36 28 57 37c22 9 44 13 68 14v-35h14v35c24 -1 46 -5 68 -14c21 -9 40 -21 57 -37l-26 -26h1v0l5 -5l5 -5l26 26c15 -16 26 -34 35 -54c10 -22 14 -46 15 -69h-29v-15h29c-1 -24 -6 -46 -16 -67c-9 -19 -17 -34 -32 -50l-23 24l-11 -11l19 -19l15 -15z" />
- <glyph glyph-name="ion-ios7-star-half" unicode="&#xf33a;"
+ <glyph glyph-name="ion-ios-speedometer-outline" unicode="&#xf4af;"
+d="M224 384c124 0 224 -100 224 -224c0 -57 -21 -108 -56 -148c-4 -4 -7 -8 -11 -12l-10 10l-1 2c-19 18 -41 33 -65 43c-26 11 -53 16 -81 16s-55 -5 -81 -16c-24 -10 -46 -25 -65 -43l-1 -2l-10 -10c-4 4 -7 8 -11 12c-35 40 -56 91 -56 148c0 124 100 224 224 224z
+M416 79c10 23 15 48 16 73h-32v16h32c-1 25 -6 50 -16 73c-9 22 -23 42 -39 60l-27 -27l-6 6l-5 5v0h-1l27 27c-18 17 -38 31 -60 40c-23 10 -48 15 -74 16v-38h-16v38c-25 -1 -49 -6 -72 -16c-22 -10 -43 -23 -61 -40l27 -27v0v0l-6 -6l-5 -5l-27 27
+c-16 -18 -30 -38 -39 -60c-10 -23 -15 -49 -16 -74h32v-16h-32c1 -25 6 -49 16 -72c9 -20 20 -39 35 -56c40 40 96 64 157 64s117 -24 157 -64c15 17 26 36 35 56zM336 273l2 -1l-75 -84c6 -8 9 -18 9 -28c0 -26 -22 -48 -48 -48c-10 0 -19 4 -27 9l-13 -12l-11 11l12 12
+c-6 8 -9 18 -9 28c0 26 22 48 48 48c10 0 19 -3 27 -8zM224 128c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
+ <glyph glyph-name="ion-ios-speedometer" unicode="&#xf4b0;"
+d="M385 169v-15h30c-1 -22 -6 -44 -15 -65c-8 -18 -19 -35 -32 -50c-39 37 -90 58 -144 58s-105 -21 -144 -58c-13 15 -24 32 -32 50c-9 21 -14 43 -15 65h28h1v16h-29c1 23 6 45 15 66c9 20 20 38 35 54l25 -24l10 10l1 1v0v0l-25 25c16 15 36 26 56 35c21 9 43 14 66 15
+v-34h14h1v34c23 -1 46 -6 67 -15s39 -20 55 -35l-24 -25l11 -11l25 25c15 -16 26 -35 35 -55c9 -21 14 -43 15 -66h-30v-1zM272 160c0 10 -3 20 -9 28l63 76l-2 1l-73 -65c-8 5 -17 8 -27 8c-26 0 -48 -22 -48 -48c0 -10 3 -20 9 -28l-12 -12l11 -11l13 12c8 -5 17 -9 27 -9
+c26 0 48 22 48 48zM224 384c124 0 224 -100 224 -224c0 -57 -21 -108 -56 -148c-4 -4 -7 -8 -11 -12h-23c-32 39 -80 64 -134 64s-102 -25 -134 -64h-23c-4 4 -7 8 -11 12c-35 40 -56 91 -56 148c0 124 100 224 224 224zM379 27c34 37 52 86 52 136c0 55 -22 106 -61 145
+s-91 60 -146 60s-107 -21 -146 -60s-61 -90 -61 -145c0 -50 18 -99 52 -136l10 -10l1 -1v1l9 9l1 1v0c17 17 38 30 60 39c24 10 48 15 74 15s50 -5 74 -15c22 -9 43 -22 60 -39v0l1 -1l9 -9v-1l1 1zM192 160c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32z
+" />
+ <glyph glyph-name="ion-ios-star-half" unicode="&#xf4b1;"
d="M140 143l-140 98h171l53 159l53 -159h171l-140 -98l54 -159l-138 99l-138 -99zM224 347v-244l107 -76l-43 122l108 75h-131z" />
- <glyph glyph-name="ion-ios7-star-outline" unicode="&#xf1df;"
+ <glyph glyph-name="ion-ios-star-outline" unicode="&#xf4b2;"
d="M448 241l-140 -98l54 -159l-138 99l-138 -99l54 159l-140 98h171l53 159l53 -159h171zM331 27l-43 122l108 75h-131l-41 123l-41 -123h-131l108 -75l-43 -122l107 76z" />
- <glyph glyph-name="ion-ios7-star" unicode="&#xf1e0;"
+ <glyph glyph-name="ion-ios-star" unicode="&#xf4b3;"
d="M448 241l-140 -98l54 -159l-138 99l-138 -99l54 159l-140 98h171l53 159l53 -159h171z" />
- <glyph glyph-name="ion-ios7-stopwatch-outline" unicode="&#xf1e1;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-stopwatch-outline" unicode="&#xf4b4;" horiz-adv-x="384"
d="M334 301c32 -35 50 -80 50 -128c0 -104 -86 -189 -192 -189s-192 85 -192 189c0 48 18 94 51 129l1 1h-18l-8 -8l-23 23l41 40l23 -22l-9 -9v-18c31 30 72 50 116 53h2v38h32v-38c43 -4 82 -21 113 -49l5 -5v19l-9 9l23 22l41 -40l-22 -23l-9 8h-18zM192 2
c96 0 173 77 173 171s-77 171 -173 171c-95 0 -173 -77 -173 -171s77 -171 173 -171zM200 191c14 -4 24 -17 24 -31c0 -15 -10 -26 -24 -30l-8 -18v0l-8 18c-14 4 -24 15 -24 30c0 14 12 27 24 31v129h16v-129z" />
- <glyph glyph-name="ion-ios7-stopwatch" unicode="&#xf1e2;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-stopwatch" unicode="&#xf4b5;" horiz-adv-x="384"
d="M334 301c32 -35 50 -80 50 -128c0 -104 -86 -189 -192 -189s-192 85 -192 189c0 48 18 94 51 129l1 1h-18l-8 -8l-23 23l41 40l23 -22l-9 -9v-18c31 30 72 50 116 53h2v38h32v-38c43 -4 82 -21 113 -49l5 -5v19l-9 9l23 22l41 -40l-22 -23l-9 8h-18zM200 130
c14 4 24 15 24 30c0 14 -10 27 -24 31v129h-16v-129c-12 -4 -24 -17 -24 -31c0 -15 10 -26 24 -30l8 -18z" />
- <glyph glyph-name="ion-ios7-sunny-outline" unicode="&#xf1e3;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-sunny-outline" unicode="&#xf4b6;" horiz-adv-x="320"
d="M151 296v56h18v-56h-18zM151 32v60h18v-60h-18zM264 183v18h56v-18h-56zM0 183v18h60v-18h-60zM240 130l34 -34l-12 -12l-33 34zM64 306l34 -33l-12 -12l-34 34zM229 272l33 34l12 -12l-34 -33zM52 96l34 34l11 -12l-33 -34zM160 116c-42 0 -76 34 -76 76s34 76 76 76
s76 -34 76 -76s-34 -76 -76 -76zM160 251c-32 0 -59 -27 -59 -59s27 -59 59 -59s59 27 59 59s-27 59 -59 59z" />
- <glyph glyph-name="ion-ios7-sunny" unicode="&#xf1e4;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-sunny" unicode="&#xf4b7;" horiz-adv-x="320"
d="M151 296v56h18v-56h-18zM151 32v60h18v-60h-18zM264 183v18h56v-18h-56zM0 183v18h60v-18h-60zM240 130l34 -34l-12 -12l-33 34zM64 306l34 -33l-12 -12l-34 34zM229 272l33 34l12 -12l-34 -33zM52 96l34 34l11 -12l-33 -34zM160 116c-42 0 -76 34 -76 76s34 76 76 76
s76 -34 76 -76s-34 -76 -76 -76z" />
- <glyph glyph-name="ion-ios7-telephone-outline" unicode="&#xf1e5;" horiz-adv-x="352"
+ <glyph glyph-name="ion-ios-telephone-outline" unicode="&#xf4b8;" horiz-adv-x="352"
d="M336 112c16 -16 26 -35 0 -66c-25 -30 -42 -30 -64 -30c-24 0 -58 14 -93 40c-32 23 -46 34 -78 67c-34 35 -55 64 -79 107c-27 50 -24 74 -18 92c4 12 14 24 28 33l1 1c6 4 18 12 32 12c13 0 24 -6 34 -18l1 -1c11 -14 24 -31 32 -47c10 -21 10 -38 -1 -53
c-9 -12 -12 -19 -12 -23s5 -9 13 -18l1 -1c16 -18 20 -23 26 -29c1 -1 3 -2 4 -3l2 -2c7 -7 11 -12 29 -28l1 -1c7 -6 9 -8 12 -8c5 0 16 7 29 15c4 3 11 5 17 5c27 0 68 -29 83 -44zM324 57c19 22 13 31 1 43c-13 14 -50 39 -72 39c-3 0 -6 -1 -8 -2
c-19 -12 -28 -18 -37 -18s-15 6 -23 13h-1c-19 16 -23 21 -30 29l-2 2c-1 1 -3 2 -4 3c-6 6 -11 12 -27 30v1c-10 11 -17 18 -18 28s5 20 16 34c15 20 -5 48 -31 79l-1 1c-7 8 -14 12 -22 12c-10 0 -18 -6 -23 -9c-1 0 -2 -1 -2 -1c-11 -7 -18 -16 -21 -24
c-5 -16 -7 -35 17 -79c23 -42 43 -70 76 -104c31 -32 45 -42 76 -64c32 -23 64 -38 84 -38c21 0 32 1 52 25z" />
- <glyph glyph-name="ion-ios7-telephone" unicode="&#xf1e6;" horiz-adv-x="352"
+ <glyph glyph-name="ion-ios-telephone" unicode="&#xf4b9;" horiz-adv-x="352"
d="M336 112c16 -16 26 -35 0 -66c-25 -30 -42 -30 -64 -30c-24 0 -58 14 -93 40c-32 23 -46 34 -78 67c-34 35 -55 64 -79 107c-27 50 -24 74 -18 92c4 12 14 24 28 33l1 1c6 4 18 12 32 12c13 0 24 -6 34 -18l1 -1c11 -14 24 -31 32 -47c10 -21 10 -38 -1 -53
c-9 -12 -12 -19 -12 -23s5 -9 13 -18l1 -1c16 -18 20 -23 26 -29c1 -1 3 -2 4 -3l2 -2c7 -7 11 -12 29 -28l1 -1c7 -6 9 -8 12 -8c5 0 16 7 29 15c4 3 11 5 17 5c27 0 68 -29 83 -44z" />
- <glyph glyph-name="ion-ios7-tennisball-outline" unicode="&#xf33b;"
-d="M378 355c43 -41 70 -99 70 -163s-27 -122 -70 -163c-4 -4 -8 -8 -12 -11c-39 -31 -88 -50 -142 -50c-55 0 -105 19 -144 52c-4 3 -8 7 -12 11c-42 41 -68 98 -68 161s26 120 68 161c4 4 8 8 12 11c39 33 89 52 144 52c54 0 103 -19 142 -50c4 -3 8 -7 12 -11zM77 45l3 -3
-l3 3c19 19 35 41 45 66c11 26 16 53 16 81s-5 55 -16 81c-10 25 -26 47 -45 66l-3 3l-3 -3c-19 -19 -35 -41 -45 -66c-11 -26 -16 -53 -16 -81s5 -55 16 -81c10 -25 26 -47 45 -66zM305 0c17 7 33 17 48 29c-43 41 -70 99 -70 163s27 122 70 163c-15 12 -31 22 -48 29
-c-26 11 -53 16 -81 16s-55 -5 -81 -16c-19 -8 -36 -18 -51 -31c42 -41 68 -98 68 -161s-26 -120 -68 -161c15 -13 32 -23 51 -31c26 -11 53 -16 81 -16s55 5 81 16zM371 45c19 19 35 41 45 66c11 26 16 53 16 81s-5 55 -16 81c-10 25 -26 47 -45 66l-5 5c-2 -2 -4 -3 -6 -5
-c-19 -19 -35 -41 -45 -66c-11 -26 -16 -53 -16 -81s5 -55 16 -81c10 -25 26 -47 45 -66c2 -2 4 -3 6 -5z" />
- <glyph glyph-name="ion-ios7-tennisball" unicode="&#xf33c;"
-d="M283 192c0 -64 27 -122 70 -163c4 -4 9 -8 13 -11c-39 -31 -88 -50 -142 -50c-55 0 -105 19 -144 52c4 3 8 7 12 11c42 41 68 98 68 161s-26 120 -68 161c-4 4 -8 8 -12 11c39 33 89 52 144 52c54 0 103 -19 142 -50c-4 -3 -9 -7 -13 -11c-43 -41 -70 -99 -70 -163z
-M448 192c0 -64 -27 -122 -70 -163c-4 3 -8 7 -12 11c-2 2 -4 3 -6 5c-19 19 -35 41 -45 66c-11 26 -16 53 -16 81s5 55 16 81c10 25 26 47 45 66c2 2 4 3 6 5c4 4 8 8 12 11c43 -41 70 -99 70 -163zM83 45l-3 -3c-4 -4 -8 -8 -12 -11c-42 41 -68 98 -68 161s26 120 68 161
-c4 -3 8 -7 12 -11l3 -3c19 -19 35 -41 45 -66c11 -26 16 -53 16 -81s-5 -55 -16 -81c-10 -25 -26 -47 -45 -66zM68 353v0v0v0zM80 20v0v0v0zM68 31v0v0zM80 364v0v0zM378 29v0v0v0zM366 18v0v0zM378 355v0v0zM366 366v0v0v0z" />
- <glyph glyph-name="ion-ios7-thunderstorm-outline" unicode="&#xf1e7;" horiz-adv-x="274"
+ <glyph glyph-name="ion-ios-tennisball-outline" unicode="&#xf4ba;" horiz-adv-x="416"
+d="M416 192v-8v0c0 -5 0 -11 -1 -16v0c-11 -97 -90 -174 -187 -183v0h-4h-2s-1 -1 -2 -1h-3h-1h-8c-115 0 -208 93 -208 208s93 208 208 208s208 -93 208 -208zM399 192c0 105 -86 191 -191 191c-3 0 -5 -1 -8 -1c1 -24 6 -46 15 -68c10 -26 26 -49 46 -69s43 -36 69 -46
+c22 -9 44 -14 68 -15c0 3 1 5 1 8zM17 192c0 -105 86 -191 191 -191h4c-1 22 -7 45 -15 66c-10 26 -26 48 -46 68s-42 36 -68 46c-21 8 -44 14 -66 15v-4zM228 2c88 9 158 78 169 166c-54 3 -106 25 -147 66s-63 93 -66 147c-88 -11 -157 -81 -166 -169
+c53 -3 105 -25 145 -65s62 -92 65 -145z" />
+ <glyph glyph-name="ion-ios-tennisball" unicode="&#xf4bb;" horiz-adv-x="416"
+d="M0 196v0v0v0zM212 -16h1h-1v0zM208 400c115 0 208 -93 208 -208c0 -8 0 -16 -1 -24v0v0c-11 -97 -90 -174 -187 -183v0v0c-6 -1 -13 -1 -20 -1c-115 0 -208 93 -208 208v4v0v0c0 6 0 11 1 16v0v0c9 97 86 176 183 187v0v0c6 1 11 1 16 1v0v0h8zM83 181
+c26 -10 48 -26 68 -46s36 -42 46 -68c8 -21 14 -44 15 -66c5 0 11 0 16 1c-3 53 -25 105 -65 145s-92 62 -145 65c-1 -5 -1 -11 -1 -16c22 -1 45 -7 66 -15zM250 234c41 -41 93 -63 147 -66c1 5 1 11 1 16c-24 1 -46 6 -68 15c-26 10 -49 26 -69 46s-36 43 -46 69
+c-9 22 -14 44 -15 68c-5 0 -11 0 -16 -1c3 -54 25 -106 66 -147z" />
+ <glyph glyph-name="ion-ios-thunderstorm-outline" unicode="&#xf4bc;" horiz-adv-x="274"
d="M193 176l-88 -128l29 96h-52l15 80h72l-16 -48h40zM209 275c36 0 65 -29 65 -65s-29 -66 -65 -66h-8v17h8c27 0 49 22 49 49s-22 50 -49 50h-6l-14 -2l-3 14c-3 14 -11 26 -22 35s-25 13 -39 13c-34 0 -63 -27 -63 -62v-12s1 -9 1 -9c-5 0 -12 -2 -14 -2
c-19 -3 -33 -18 -33 -37c0 -10 3 -19 10 -26s16 -11 26 -11h11v-17h-11c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78c37 0 68 -26 76 -61h8z" />
- <glyph glyph-name="ion-ios7-thunderstorm" unicode="&#xf1e8;" horiz-adv-x="274"
+ <glyph glyph-name="ion-ios-thunderstorm" unicode="&#xf4bd;" horiz-adv-x="274"
d="M153 176h40l-22 -32l-66 -96l29 96h-52l15 80h72zM84 240h107l-16 -48h18h30l-33 -48h19c36 0 65 30 65 66s-29 65 -65 65h-8c-8 35 -39 61 -76 61c-43 0 -78 -35 -78 -78v-8c-26 -2 -47 -26 -47 -53c0 -29 24 -53 52 -53h14z" />
- <glyph glyph-name="ion-ios7-time-outline" unicode="&#xf291;"
+ <glyph glyph-name="ion-ios-time-outline" unicode="&#xf4be;"
d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM371 45c19 19 35 41 45 66c11 26 16 53 16 81s-5 55 -16 81c-10 25 -26 47 -45 66s-41 35 -66 45c-26 11 -53 16 -81 16s-55 -5 -81 -16c-25 -10 -47 -26 -66 -45
s-35 -41 -45 -66c-11 -26 -16 -53 -16 -81s5 -55 16 -81c10 -25 26 -47 45 -66s41 -35 66 -45c26 -11 53 -16 81 -16s55 5 81 16c25 10 47 26 66 45zM216 368c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM216 16c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM392 192
c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM40 192c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM128 344c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM304 40c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM368 280c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8
zM64 104c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM64 280c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM368 104c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM304 344c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM128 40c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8
s-8 3 -8 8zM238 200c4 -8 2 -18 -6 -22v-122c0 -4 -4 -8 -8 -8s-8 4 -8 8v122c-2 1 -4 4 -6 6c-3 5 -3 11 0 16l-37 63c-2 4 -1 9 3 11s8 1 10 -3l38 -63c5 0 11 -3 14 -8z" />
- <glyph glyph-name="ion-ios7-time" unicode="&#xf292;"
+ <glyph glyph-name="ion-ios-time" unicode="&#xf4bf;"
d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM224 376c-4 0 -8 -4 -8 -8s4 -8 8 -8s8 4 8 8s-4 8 -8 8zM48 184c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM76 97c4 2 4 7 2 11s-6 5 -10 3s-5 -7 -3 -11s7 -5 11 -3z
M78 276c2 4 2 9 -2 11s-9 1 -11 -3s-1 -9 3 -11s8 -1 10 3zM132 351c-4 -2 -5 -7 -3 -11s7 -4 11 -2s5 6 3 10s-7 5 -11 3zM143 36c2 4 1 8 -3 10s-9 2 -11 -2s-1 -9 3 -11s9 -1 11 3zM224 8c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM232 178c8 4 10 14 6 22
c-3 5 -9 8 -14 8l-38 64c-2 4 -7 4 -11 2s-4 -7 -2 -11l37 -63c-3 -5 -3 -11 0 -16c2 -2 4 -5 6 -6v-122c0 -4 4 -8 8 -8s8 4 8 8v122zM316 33c4 2 5 7 3 11s-7 4 -11 2s-5 -6 -3 -10s7 -5 11 -3zM319 340c2 4 1 9 -3 11s-9 1 -11 -3s-1 -8 3 -10s9 -2 11 2zM383 100
c2 4 1 9 -3 11s-8 1 -10 -3s-2 -9 2 -11s9 -1 11 3zM380 273c4 2 5 7 3 11s-7 5 -11 3s-4 -7 -2 -11s6 -5 10 -3zM400 184c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8z" />
- <glyph glyph-name="ion-ios7-timer-outline" unicode="&#xf1e9;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-timer-outline" unicode="&#xf4c0;" horiz-adv-x="416"
d="M189 176l-1 2s-89 118 -86 120s121 -85 121 -85c1 -1 1 -2 2 -3c5 -5 8 -11 8 -18c0 -14 -11 -25 -25 -25c-8 0 -14 3 -19 9zM208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208c0 57 23 109 61 147l12 -12c-35 -35 -56 -82 -56 -135
c0 -106 85 -191 191 -191s191 85 191 191c0 100 -77 183 -175 191v-95h-16v112v0v0z" />
- <glyph glyph-name="ion-ios7-timer" unicode="&#xf1ea;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-timer" unicode="&#xf4c1;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM102 298c-2 -2 86 -120 86 -120l1 -1c5 -6 11 -10 19 -10c14 0 25 11 25 25c0 7 -3 13 -8 18l-3 3c0 0 -117 87 -120 85zM208 1c106 0 192 85 192 191s-86 192 -192 192v-96h16v78
c88 -9 158 -84 158 -174c0 -96 -78 -174 -174 -174s-175 78 -175 174c0 48 19 92 51 124l-11 12c-35 -35 -56 -83 -56 -136c0 -106 85 -191 191 -191z" />
- <glyph glyph-name="ion-ios7-toggle-outline" unicode="&#xf33d;"
+ <glyph glyph-name="ion-ios-toggle-outline" unicode="&#xf4c2;"
d="M96 128c-26 0 -48 -22 -48 -48s22 -48 48 -48s48 22 48 48s-22 48 -48 48zM96 144v0c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM351 160v0h-255c-44 0 -80 -36 -80 -80s36 -80 80 -80h256c44 0 80 36 80 80s-37 80 -81 80zM352 176v0
c53 0 96 -43 96 -96s-43 -96 -96 -96h-256c-53 0 -96 43 -96 96s43 96 96 96h256zM352 352c-26 0 -48 -22 -48 -48s22 -48 48 -48s48 22 48 48s-22 48 -48 48zM352 368v0c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM97 384v0c-44 0 -81 -36 -81 -80
s36 -80 80 -80h256c44 0 80 36 80 80s-36 80 -80 80h-255zM96 400v0h256c53 0 96 -43 96 -96s-43 -96 -96 -96h-256c-53 0 -96 43 -96 96s43 96 96 96z" />
- <glyph glyph-name="ion-ios7-toggle" unicode="&#xf33e;"
+ <glyph glyph-name="ion-ios-toggle" unicode="&#xf4c3;"
d="M96 128c26 0 48 -22 48 -48s-22 -48 -48 -48s-48 22 -48 48s22 48 48 48zM352 176c53 0 96 -43 96 -96s-43 -96 -96 -96h-256c-53 0 -96 43 -96 96s43 96 96 96h256zM96 16c35 0 64 29 64 64s-29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64zM352 256c-26 0 -48 22 -48 48
s22 48 48 48s48 -22 48 -48s-22 -48 -48 -48zM96 208c-53 0 -96 43 -96 96s43 96 96 96h256c53 0 96 -43 96 -96s-43 -96 -96 -96h-256zM352 368c-35 0 -64 -29 -64 -64s29 -64 64 -64s64 29 64 64s-29 64 -64 64z" />
- <glyph glyph-name="ion-ios7-trash-outline" unicode="&#xf1eb;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-trash-outline" unicode="&#xf4c4;" horiz-adv-x="288"
d="M288 335v-15h-20l-24 -291c0 -16 -13 -29 -29 -29h-141c-16 0 -29 13 -29 29l-24 291h-21v15h80v20c0 16 13 29 29 29h70c16 0 29 -13 29 -29v-20h80zM95 355v-20h98v20c0 8 -6 14 -14 14h-70c-8 0 -14 -6 -14 -14zM230 30l23 290h-217l23 -290v0v-1c0 -8 7 -14 15 -14
h141c8 0 15 6 15 14v1v0zM137 47v241h14v-241h-14zM208 288l-11 -241h-14l10 241h15zM94 288l11 -241h-14l-11 241h14z" />
- <glyph glyph-name="ion-ios7-trash" unicode="&#xf1ec;" horiz-adv-x="288"
+ <glyph glyph-name="ion-ios-trash" unicode="&#xf4c5;" horiz-adv-x="288"
d="M208 335h80v-15h-20l-24 -291c0 -16 -13 -29 -29 -29h-141c-16 0 -29 13 -29 29l-24 291h-21v15h80v20c0 16 13 29 29 29h70c16 0 29 -13 29 -29v-20zM95 355v0v-20h98v20c0 8 -6 14 -14 14h-70c-8 0 -14 -6 -14 -14zM91 47h14l-11 241h-14zM151 47v241h-14v-241h14z
M197 47l11 241h-14l-11 -241h14z" />
- <glyph glyph-name="ion-ios7-undo-outline" unicode="&#xf1ed;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-undo-outline" unicode="&#xf4c6;" horiz-adv-x="384"
d="M384 80v-32h-10l-20 31c-20 33 -44 63 -75 77c-24 11 -47 19 -87 20v-80l-192 128l192 128v-80c63 -3 108 -21 143 -56c52 -53 49 -119 49 -136zM368 87c0 0 9 169 -192 169v65l-148 -97l148 -97v65c91 0 144 -24 192 -105z" />
- <glyph glyph-name="ion-ios7-undo" unicode="&#xf1ee;" horiz-adv-x="384"
+ <glyph glyph-name="ion-ios-undo" unicode="&#xf4c7;" horiz-adv-x="384"
d="M384 80v-32h-10l-20 31c-20 33 -44 63 -75 77c-24 11 -47 19 -87 20v-80l-192 128l192 128v-80c63 -3 108 -21 143 -56c52 -53 49 -119 49 -136z" />
- <glyph glyph-name="ion-ios7-unlocked-outline" unicode="&#xf1ef;" horiz-adv-x="320"
-d="M72 224h248v-240h-320v240h56v72c0 57 46 104 104 104c57 0 104 -47 104 -104v-8h-16v8c0 48 -40 88 -88 88s-88 -40 -88 -88v-72zM304 0v208h-288v-208h288zM160 160c18 0 32 -14 32 -32c0 -15 -10 -27 -24 -31v-41c0 -4 -4 -8 -8 -8s-8 4 -8 8v41c-14 4 -24 16 -24 31
-c0 18 14 32 32 32zM160 112c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16z" />
- <glyph glyph-name="ion-ios7-unlocked" unicode="&#xf1f0;" horiz-adv-x="320"
-d="M160 144c9 0 16 -7 16 -16s-7 -16 -16 -16s-16 7 -16 16s7 16 16 16zM72 224h248v-240h-320v240h56v72c0 57 46 104 104 104c57 0 104 -47 104 -104v-8h-16v8c0 48 -40 88 -88 88s-88 -40 -88 -88v-72zM168 97c14 4 24 16 24 31c0 18 -14 32 -32 32s-32 -14 -32 -32
-c0 -15 10 -27 24 -31v-41c0 -4 4 -8 8 -8s8 4 8 8v41z" />
- <glyph glyph-name="ion-ios7-upload-outline" unicode="&#xf1f1;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-unlocked-outline" unicode="&#xf4c8;" horiz-adv-x="320"
+d="M160 160c18 0 32 -14 32 -32c0 -15 -10 -27 -24 -31v-33h-16v33c-14 4 -24 16 -24 31c0 18 14 32 32 32zM160 112c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM72 224h248v-240h-320v240h56v72c0 57 47 104 104 104s104 -47 104 -104v-8h-16v8
+c0 49 -39 88 -88 88s-88 -39 -88 -88v-72zM304 0v208h-288v-208h288z" />
+ <glyph glyph-name="ion-ios-unlocked" unicode="&#xf4c9;" horiz-adv-x="320"
+d="M160 144c9 0 16 -7 16 -16s-7 -16 -16 -16s-16 7 -16 16s7 16 16 16zM72 224h248v-240h-320v240h56v72c0 57 47 104 104 104s104 -47 104 -104v-8h-16v8c0 49 -39 88 -88 88s-88 -39 -88 -88v-72zM168 97c14 4 24 16 24 31c0 18 -14 32 -32 32s-32 -14 -32 -32
+c0 -15 10 -27 24 -31v-33h16v33z" />
+ <glyph glyph-name="ion-ios-upload-outline" unicode="&#xf4ca;" horiz-adv-x="320"
d="M192 304h128v-304h-320v304h128v-16h-112v-272h288v272h-112v16zM97 330l-11 12l74 74l74 -74l-11 -12l-55 55v-243h-16v243z" />
- <glyph glyph-name="ion-ios7-upload" unicode="&#xf1f2;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-upload" unicode="&#xf4cb;" horiz-adv-x="320"
d="M168 304h152v-304h-320v304h152v-162h16v162zM168 385v-81h-16v81l-55 -55l-11 12l74 74l74 -74l-11 -12z" />
- <glyph glyph-name="ion-ios7-videocam-outline" unicode="&#xf1f3;" horiz-adv-x="418"
+ <glyph glyph-name="ion-ios-videocam-outline" unicode="&#xf4cc;" horiz-adv-x="418"
d="M257 320c19 0 33 -14 33 -33v-188c0 -19 -14 -35 -33 -35h-221c-19 0 -36 16 -36 35v188c0 19 17 33 36 33h221zM273 99v188c0 9 -8 16 -17 16h-221c-9 0 -18 -7 -18 -16v-188c0 -9 10 -18 19 -18h221c9 0 16 9 16 18zM320 235l98 53v-192l-98 53v86zM401 258v0l-64 -33
v-66l64 -33v132z" />
- <glyph glyph-name="ion-ios7-videocam" unicode="&#xf1f4;" horiz-adv-x="418"
+ <glyph glyph-name="ion-ios-videocam" unicode="&#xf4cd;" horiz-adv-x="418"
d="M257 320c19 0 33 -14 33 -33v-188c0 -19 -14 -35 -33 -35h-221c-19 0 -36 16 -36 35v188c0 19 17 33 36 33h221zM320 235l98 53v-192l-98 53v86z" />
- <glyph glyph-name="ion-ios7-volume-high" unicode="&#xf1f5;" horiz-adv-x="320"
+ <glyph glyph-name="ion-ios-volume-high" unicode="&#xf4ce;" horiz-adv-x="320"
d="M278 320c26 -36 42 -80 42 -128s-16 -92 -42 -128l-14 10c24 33 39 74 39 118s-15 85 -39 118zM224 96l-14 10c18 24 29 54 29 86s-11 62 -29 86l14 10c20 -27 32 -60 32 -96s-12 -69 -32 -96zM177 128l-13 10c12 15 18 34 18 54s-6 39 -18 54l13 10
c14 -18 22 -40 22 -64s-8 -46 -22 -64zM58 232l70 56v-192l-70 56h-58v80h58z" />
- <glyph glyph-name="ion-ios7-volume-low" unicode="&#xf1f6;" horiz-adv-x="128"
+ <glyph glyph-name="ion-ios-volume-low" unicode="&#xf4cf;" horiz-adv-x="128"
d="M58 232l70 56v-192l-70 56h-58v80h58z" />
- <glyph glyph-name="ion-ios7-wineglass-outline" unicode="&#xf293;" horiz-adv-x="224"
-d="M129 179c-5 -3 -9 -14 -9 -19v-160h71v-16h-160v16h73v160c0 4 -6 16 -11 19c-9 6 -22 15 -43 30c-18 13 -50 36 -50 97c0 49 29 94 29 94h166s29 -44 29 -93c0 -61 -31 -85 -50 -98c-21 -15 -35 -23 -45 -30zM40 384c-7 -13 -24 -45 -24 -78v-2h192v3
-c0 33 -17 77 -24 77h-144zM112 192c7 0 13 2 18 6c9 6 20 13 35 24c14 10 37 26 42 66h-190c2 -15 7 -28 14 -39c9 -13 20 -22 28 -27c17 -12 29 -21 37 -26c5 -3 10 -4 16 -4z" />
- <glyph glyph-name="ion-ios7-wineglass" unicode="&#xf294;" horiz-adv-x="224"
-d="M129 179c-5 -3 -9 -14 -9 -19v-160h71v-16h-160v16h73v160c0 4 -6 16 -11 19c-9 6 -22 15 -43 30c-18 13 -50 36 -50 97c0 49 29 94 29 94h166s29 -44 29 -93c0 -61 -31 -85 -50 -98c-21 -15 -35 -23 -45 -30zM40 384c-7 -13 -24 -45 -24 -78v-2h192v3
-c0 33 -17 77 -24 77h-144z" />
- <glyph glyph-name="ion-ios7-world-outline" unicode="&#xf1f7;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-wineglass-outline" unicode="&#xf4d0;" horiz-adv-x="192"
+d="M104 139v-155h72v-16h-80h-80v16h72v155c0 22 -20 39 -40 55c-8 6 -16 13 -22 19c-27 28 -26 52 -26 71v4c0 44 31 125 32 128h64h64c1 -3 32 -84 32 -128v-4c0 -19 1 -43 -26 -71c-6 -6 -14 -13 -22 -19c-20 -16 -40 -33 -40 -55zM43 400c-5 -16 -20 -63 -25 -96h156
+c-5 33 -20 80 -25 96h-53h-53zM96 175c3 0 5 0 7 2v0c9 11 20 20 31 29c8 6 15 12 20 18c22 23 22 41 22 60v4h-160v-4c0 -19 0 -37 22 -60c5 -6 12 -12 20 -18c11 -9 22 -18 31 -29v0c2 -2 4 -2 7 -2z" />
+ <glyph glyph-name="ion-ios-wineglass" unicode="&#xf4d1;" horiz-adv-x="192"
+d="M104 139v-155h72v-16h-80h-80v16h72v155c0 22 -20 39 -40 55c-8 6 -16 13 -22 19c-27 28 -26 52 -26 71v4c0 44 31 125 32 128h64h64c1 -3 32 -84 32 -128v-4c0 -19 1 -43 -26 -71c-6 -6 -14 -13 -22 -19c-20 -16 -40 -33 -40 -55zM43 400c-5 -16 -20 -63 -25 -96h156
+c-5 33 -20 80 -25 96h-53h-53z" />
+ <glyph glyph-name="ion-ios-world-outline" unicode="&#xf4d2;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208v0v0v0c-115 0 -208 93 -208 208s93 208 208 208v0v0v0zM216 276v-76h75c-1 31 -5 60 -11 84c-21 -5 -42 -7 -64 -8zM216 292c20 1 41 3 60 8c-14 46 -38 76 -60 82v-90zM200 382c-23 -6 -45 -36 -60 -82
c19 -5 39 -7 60 -8v90zM200 276c-22 1 -44 3 -65 8c-6 -24 -10 -53 -11 -84h76v76zM108 200c1 32 4 62 11 88c-21 6 -41 15 -59 25c-26 -31 -41 -70 -43 -113h91zM108 184h-91c2 -43 17 -82 43 -113c19 10 38 19 59 25c-7 26 -10 56 -11 88zM124 184c1 -31 5 -60 11 -84
c21 5 43 8 65 9v75h-76zM200 92c-21 -1 -41 -3 -60 -8c15 -46 37 -76 60 -82v90zM216 2c22 6 46 36 60 82c-19 5 -40 7 -60 8v-90zM216 109c22 -1 43 -4 64 -9c6 24 10 53 11 84h-75v-75zM308 184c-1 -32 -5 -62 -12 -88c21 -6 41 -15 60 -25c26 31 41 70 43 113h-91z
M308 200v0h91c-2 43 -17 82 -43 113c-19 -10 -38 -19 -59 -25c7 -26 10 -56 11 -88zM344 326c-25 25 -56 44 -91 52c16 -17 29 -43 39 -74c18 6 35 13 52 22zM163 378c-35 -8 -67 -27 -91 -52c16 -9 34 -15 52 -21c10 31 23 56 39 73zM72 58c25 -25 56 -44 91 -52
c-16 17 -30 43 -40 74c-18 -6 -35 -13 -51 -22zM253 6c35 8 66 27 91 52c-17 9 -34 16 -52 22c-10 -31 -23 -57 -39 -74z" />
- <glyph glyph-name="ion-ios7-world" unicode="&#xf1f8;" horiz-adv-x="416"
+ <glyph glyph-name="ion-ios-world" unicode="&#xf4d3;" horiz-adv-x="416"
d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208v0v0v0c-115 0 -208 93 -208 208s93 208 208 208v0v0v0zM208 1c106 0 191 85 191 191s-85 191 -191 191v0v0v0c-106 0 -191 -85 -191 -191s86 -191 191 -191v0v0v0zM274 276c6 -22 9 -48 10 -76h-68v68c20 1 39 4 58 8
zM216 366c20 -6 41 -34 54 -75c-17 -4 -36 -6 -54 -7v82zM145 291c13 42 35 69 55 75v-82c-19 1 -37 3 -55 7zM333 315c-15 -8 -31 -15 -48 -20c-9 29 -21 52 -36 67c32 -8 61 -24 84 -47zM299 200c-1 29 -4 56 -10 80c19 6 37 14 54 23c23 -28 38 -64 40 -103h-84zM132 200
c1 28 3 54 9 76c19 -5 39 -7 59 -8v-68h-68zM284 184c-1 -28 -4 -54 -10 -76c-19 5 -38 7 -58 8v68h68zM141 108c-6 22 -8 48 -9 76h68v-68c-20 -1 -40 -3 -59 -8zM200 18c-20 6 -42 33 -55 75c18 4 36 6 55 7v-82zM249 22c15 15 27 38 36 67c17 -5 33 -11 48 -19
@@ -1315,56 +1539,45 @@ c2 2 3 4 3 7s-1 5 -3 8v1c-1 2 -2 4 -2 6s1 3 2 5v1c2 3 3 5 3 8s-1 4 -3 7v1v0c-1 2
<glyph glyph-name="ion-link" unicode="&#xf1fe;" horiz-adv-x="384"
d="M192 240v0v0v0zM304 288c44 0 80 -36 80 -80v-32c0 -44 -36 -80 -80 -80h-112c-33 0 -60 20 -73 48c-4 10 -7 20 -7 32v32h48v-32c0 -18 14 -32 32 -32h112c18 0 32 14 32 32v32c0 18 -14 32 -32 32v0h-16c-6 31 -32 48 -32 48h48zM266 240c4 -10 6 -21 6 -32v-32v0h-48
v0v32c0 18 -14 32 -32 32v0h-112c-18 0 -32 -14 -32 -32v-32c0 -18 14 -32 32 -32h16c6 -31 32 -48 32 -48h-48c-44 0 -80 36 -80 80v32c0 44 36 80 80 80h112c33 0 62 -20 74 -48z" />
- <glyph glyph-name="ion-load-a" unicode="&#xf29a;" horiz-adv-x="512"
-d="M192 352c0 42.6667 21.3333 64 64 64c42.6667 0 64 -21.3333 64 -64s-21.3333 -64 -64 -64c-42.6667 0 -64 21.3333 -64 64zM48 192c0 32 16 48 48 48s48 -16 48 -48s-16 -48 -48 -48s-48 16 -48 48zM360 304c0 5.33333 2.66667 8 8 8s8 -2.66667 8 -8s-2.66667 -8 -8 -8
-s-8 2.66667 -8 8zM180.1 340.4c9.9502 -10.0503 14.9253 -22.1838 14.9253 -36.4004c0 -14.2166 -4.9751 -26.3501 -14.9253 -36.4004c-9.94971 -10.0498 -21.9662 -15.0747 -36.0494 -15.0747s-26.1 5.0249 -36.0502 15.0747
-c-9.9502 10.0503 -14.9253 22.1838 -14.9253 36.4004s4.9751 26.3501 14.9253 36.4004c9.9502 10.0498 21.9669 15.0747 36.0502 15.0747c14.0833 0 26.0997 -5.0249 36.0494 -15.0747zM400 192c0 10.6667 5.33333 16 16 16s16 -5.33333 16 -16s-5.33333 -16 -16 -16
-s-16 5.33333 -16 16zM345 79c0 16 8 24 24 24s24 -8 24 -24s-8 -24 -24 -24s-24 8 -24 24zM224 32c0 21.3333 10.6667 32 32 32c21.3333 0 32 -10.6667 32 -32c0 -21.3333 -10.6667 -32 -32 -32c-21.3333 0 -32 10.6667 -32 32zM104 80c0 26.6667 13.3333 40 40 40
-c26.6667 0 40 -13.3333 40 -40s-13.3333 -40 -40 -40c-26.6667 0 -40 13.3333 -40 40z" />
- <glyph glyph-name="ion-load-b" unicode="&#xf29b;" horiz-adv-x="512"
-d="M288 288c0 -17.7002 -14.2998 -32 -32 -32v0c-17.7002 0 -32 14.2998 -32 32v96c0 17.7002 14.2998 32 32 32v0c17.7002 0 32 -14.2998 32 -32v-96zM256 128v0c17.7002 0 32 -14.2998 32 -32v-96c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32v96
-c0 17.7002 14.2998 32 32 32zM448 224v0c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32h-96c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32h96zM160 224v0c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32h-96c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
-h96zM346.5 237.3c-12.5 -12.5 -32.7998 -12.5 -45.2998 0v0c-12.5 12.5 -12.5 32.7998 0 45.2998l67.8994 67.9004c12.5 12.5 32.8008 12.5 45.3008 0v0c12.5 -12.5 12.5 -32.7998 0 -45.2998zM210.7 146.7v0c12.5 -12.5 12.5 -32.7002 0 -45.2998l-67.9004 -67.9004
-c-12.5 -12.5 -32.7998 -12.5 -45.2998 0s-12.5 32.7998 0 45.2998l67.9004 67.9004c12.5 12.5 32.7998 12.5 45.2998 0zM414.4 78.9004v0c12.5 -12.5 12.5 -32.8008 0 -45.3008s-32.8008 -12.5 -45.3008 0l-67.8994 67.9004c-12.5 12.5 -12.5 32.7998 0 45.2998
-s32.7998 12.5 45.2998 0zM210.7 282.5v0c12.5 -12.5 12.5 -32.7998 0 -45.2998s-32.7998 -12.5 -45.2998 0l-67.9004 67.8994c-12.5 12.5 -12.5 32.8008 0 45.3008s32.7998 12.5 45.2998 0z" />
- <glyph glyph-name="ion-load-c" unicode="&#xf29c;" horiz-adv-x="512"
-d="M479.8 221.9c0.5 -2.90039 0.100586 -6 -1.2002 -8.90039c-3.7998 -8.40039 -14.6992 -11.9004 -22.5 -6.7002c-3.69922 2.40039 -6.09961 6.40039 -6.7998 10.7002c-0.799805 4.7002 -1.59961 9.40039 -2.59961 14.0996c-4.40039 20.4004 -11.7002 40 -21.9004 58.2002
-c-12 21.4004 -27.8994 40.4004 -47 55.7998c-18.2002 14.7002 -39.2002 26 -61.5 33c-20.7002 6.5 -42.5 9.30078 -64.2002 8.90039c-1.2998 0 -2.59961 0.0996094 -3.89941 0.0996094c-3.2002 -0.299805 -6.2998 -0.299805 -9.5 -0.599609
-c-6.5 -0.5 -13 -1.5 -19.5 -2.7002c-12.7998 -2.39941 -25.4004 -6 -37.4004 -10.8994c-20.7998 -8.40039 -40 -20.3008 -56.7998 -35.1006c-16.7998 -14.7002 -31.0996 -32.0996 -42.0996 -51.3994c-12.4004 -21.6006 -20.4004 -45.3008 -24.1006 -69.9004
-c-1.7002 -11.2002 -2.39941 -22.9004 -2.09961 -34.2002c0.200195 -5.5 0.700195 -11 1.2998 -16.3994c0.700195 -6.30078 1.7002 -12.7002 3 -18.9004c5.09961 -23.9004 14.4004 -46.7998 27.9004 -67.0996c12.8994 -19.9004 29.2998 -37.5 48.1992 -51.8008
-c19.5 -14.6992 41.7002 -25.8994 65.1006 -32.7998c24.5996 -7.2998 50.7002 -9.7998 76.2998 -7.59961c25 2.2002 49.7002 8.7998 72.2998 19.7998c11.2998 5.40039 22 11.9004 32.1006 19.2998c9.89941 7.2002 18.7998 15.2998 27 24.4004
-c4.09961 4.5 8.19922 9.09961 11.7998 13.8994c3.59961 4.80078 6.89941 9.80078 10.0996 14.9004c6.2002 9.90039 11.9004 20.0996 16.7998 30.7998c3.80078 8.40039 7.80078 16.7998 11 25.5c1.60059 4.10059 3 8.2998 4.10059 12.6006
-c0.899414 3.69922 1.5 7.39941 2.2002 11.1992c0.799805 -8.59961 0.199219 -17.3994 -1.30078 -25.8994c-1 -5.40039 -2.09961 -10.9004 -3.59961 -16.2002c-1.40039 -5 -3.09961 -9.7998 -4.90039 -14.5996c-3.59961 -9.7002 -7.7998 -19.3008 -12.7998 -28.5
-c-5.7998 -10.7002 -12.7998 -20.6006 -20.5996 -30c-7.7002 -9.30078 -15.9004 -18.1006 -25.1006 -25.9004c-18.2998 -15.4004 -39.1992 -27.7002 -61.5 -36.2998c-23.1992 -8.90039 -47.7998 -13.7002 -72.5996 -14.5
-c-25.4004 -0.900391 -51.0996 2.7002 -75.2998 10.3994c-23.2002 7.40039 -45.2998 18.6006 -64.9004 33.1006c-19.2002 14.0996 -36 31.2002 -49.7998 50.5c-6.90039 9.7002 -13.0996 20 -18.4004 30.7002c-5.39941 10.8994 -9.69922 22.0996 -13.2998 33.5996
-c-5.7002 18.0996 -8.59961 37 -9.5 55.9004c-1 19.5 1 39.0996 5.2002 58.0996c5.2002 23.7998 14.7002 46.5 27.4004 67.2998c11.5 18.7002 25.7998 35.7002 42.1992 50.2998c16.4004 14.6006 34.9004 26.8008 54.8008 36.2002c23.1992 10.9004 48.3994 18 73.8994 20.5
-c9.7998 0.900391 19.7002 1.2998 29.6006 1.2002c12.6992 -0.0996094 25.1992 -1.59961 37.5996 -4.09961c24 -4.90039 47 -13.7002 68.0996 -26.1006c21.4004 -12.5 40.7002 -28.7998 56.7002 -47.7002c14.7998 -17.5996 27 -37.3994 35.9004 -58.5996
-c4.39941 -10.2998 8 -21 10.7998 -31.7998c2.2002 -8.5 3.90039 -17.1006 5.2998 -25.7998z" />
- <glyph glyph-name="ion-load-d" unicode="&#xf29d;" horiz-adv-x="512"
-d="M432 208c8.7998 0 16 -7.2002 16 -16s-7.2002 -16 -16 -16h-80c-8.7998 0 -16 7.2002 -16 16s7.2002 16 16 16h80zM176 192c0 -8.7998 -7.2002 -16 -16 -16h-80c-8.7998 0 -16 7.2002 -16 16s7.2002 16 16 16h80c8.7998 0 16 -7.2002 16 -16zM256 112
-c8.7998 0 16 -7.2002 16 -16v-80c0 -8.7998 -7.2002 -16 -16 -16s-16 7.2002 -16 16v80c0 8.7998 7.2002 16 16 16zM256 384c8.7998 0 16 -7.2002 16 -16v-80c0 -8.7998 -7.2002 -16 -16 -16s-16 7.2002 -16 16v80c0 8.7998 7.2002 16 16 16zM325.3 232
-c-4.39941 7.7002 -1.7998 17.4004 5.90039 21.9004l69.2998 40c7.7002 4.39941 17.5 1.7998 21.9004 -5.90039c4.39941 -7.7002 1.7998 -17.5 -5.90039 -21.9004l-69.2998 -40c-7.7002 -4.39941 -17.5 -1.7998 -21.9004 5.90039zM186.7 152
-c4.39941 -7.7002 1.7998 -17.4004 -5.90039 -21.9004l-69.2998 -40c-7.7002 -4.39941 -17.5 -1.7998 -21.9004 5.90039c-4.39941 7.7002 -1.7998 17.5 5.90039 21.9004l69.2998 40c7.7002 4.39941 17.5 1.7998 21.9004 -5.90039zM317.9 116.9l40 -69.3008
-c4.39941 -7.69922 1.7998 -17.5 -5.90039 -21.8994c-7.7002 -4.40039 -17.5 -1.7998 -21.9004 5.89941l-40 69.3008c-4.39941 7.69922 -1.7998 17.5 5.90039 21.8994c7.7002 4.40039 17.5 1.7998 21.9004 -5.89941zM181.9 352.4l40 -69.3008
-c4.39941 -7.69922 1.7998 -17.5 -5.90039 -21.8994c-7.7002 -4.40039 -17.5 -1.7998 -21.9004 5.89941l-40 69.3008c-4.39941 7.69922 -1.7998 17.5 5.90039 21.8994c7.7002 4.40039 17.5 1.7998 21.9004 -5.89941zM296 261.3
-c-7.7002 4.40039 -10.2998 14.2002 -5.90039 21.9004l40 69.2998c4.5 7.7002 14.2002 10.2998 21.9004 5.90039c7.7002 -4.5 10.2998 -14.2002 5.90039 -21.9004l-40 -69.2998c-4.5 -7.7002 -14.2002 -10.2998 -21.9004 -5.90039zM216 122.7
-c7.7002 -4.40039 10.2998 -14.2002 5.90039 -21.9004l-40 -69.2998c-4.5 -7.7002 -14.2002 -10.2998 -21.9004 -5.90039c-7.7002 4.5 -10.2998 14.2002 -5.90039 21.9004l40 69.2998c4.5 7.7002 14.2002 10.2998 21.9004 5.90039zM416.4 117.9
-c7.69922 -4.5 10.2998 -14.2002 5.89941 -21.9004c-4.5 -7.7002 -14.2002 -10.2998 -21.8994 -5.90039l-69.3008 40c-7.69922 4.5 -10.2998 14.2002 -5.89941 21.9004c4.5 7.7002 14.2002 10.2998 21.8994 5.90039zM95.5996 266.1
-c-7.69922 4.5 -10.2998 14.2002 -5.89941 21.9004c4.5 7.7002 14.2002 10.2998 21.8994 5.90039l69.3008 -40c7.69922 -4.5 10.3994 -14.2002 5.89941 -21.9004s-14.2002 -10.2998 -21.8994 -5.90039z" />
+ <glyph glyph-name="ion-load-a" unicode="&#xf29a;" horiz-adv-x="384"
+d="M144 352c0 43 21 64 64 64s64 -21 64 -64s-21 -64 -64 -64s-64 21 -64 64zM0 192c0 32 16 48 48 48s48 -16 48 -48s-16 -48 -48 -48s-48 16 -48 48zM312 304c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM132 340c10 -10 15 -22 15 -36s-5 -26 -15 -36s-22 -15 -36 -15
+s-26 5 -36 15s-15 22 -15 36s5 26 15 36s22 15 36 15s26 -5 36 -15zM352 192c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16zM297 79c0 16 8 24 24 24s24 -8 24 -24s-8 -24 -24 -24s-24 8 -24 24zM176 32c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32
+s-32 11 -32 32zM56 80c0 27 13 40 40 40s40 -13 40 -40s-13 -40 -40 -40s-40 13 -40 40z" />
+ <glyph glyph-name="ion-load-b" unicode="&#xf29b;"
+d="M256 288c0 -18 -14 -32 -32 -32v0c-18 0 -32 14 -32 32v96c0 18 14 32 32 32v0c18 0 32 -14 32 -32v-96zM224 128v0c18 0 32 -14 32 -32v-96c0 -18 -14 -32 -32 -32s-32 14 -32 32v96c0 18 14 32 32 32zM416 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32h-96
+c-18 0 -32 14 -32 32s14 32 32 32h96zM128 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32h-96c-18 0 -32 14 -32 32s14 32 32 32h96zM314 237c-12 -12 -33 -12 -45 0v0c-12 12 -12 34 0 46l68 67c12 12 33 12 45 0v0c12 -12 12 -33 0 -45zM179 147v0c12 -12 12 -33 0 -46
+l-68 -67c-12 -12 -33 -12 -45 0s-12 33 0 45l67 68c12 12 34 12 46 0zM382 79v0c12 -12 12 -33 0 -45s-33 -12 -45 0l-68 68c-12 12 -12 33 0 45s33 12 45 0zM179 282v0c12 -12 12 -33 0 -45s-34 -12 -46 0l-67 68c-12 12 -12 33 0 45s33 12 45 0z" />
+ <glyph glyph-name="ion-load-c" unicode="&#xf29c;"
+d="M448 222c0 -3 0 -6 -1 -9c-4 -8 -15 -12 -23 -7c-4 2 -6 7 -7 11c-1 5 -1 9 -2 14c-4 20 -12 40 -22 58c-12 21 -28 41 -47 56c-18 15 -40 26 -62 33c-21 6 -42 9 -64 9h-4c-3 0 -6 -1 -9 -1c-6 0 -14 -1 -20 -2c-13 -2 -25 -6 -37 -11c-21 -8 -40 -20 -57 -35
+s-31 -33 -42 -52c-12 -22 -20 -45 -24 -70c-2 -11 -2 -23 -2 -34c0 -6 0 -11 1 -16c1 -6 2 -13 3 -19c5 -24 14 -47 28 -67c13 -20 29 -38 48 -52c20 -15 42 -26 65 -33c25 -7 50 -9 76 -7c25 2 50 9 73 20c11 5 22 12 32 19s19 15 27 24c4 4 8 9 12 14s7 10 10 15
+c6 10 12 20 17 31c4 8 8 16 11 25c2 4 3 9 4 13s1 7 2 11c1 -9 1 -18 -1 -26c-1 -5 -2 -11 -4 -16c-1 -5 -3 -10 -5 -15c-4 -10 -8 -19 -13 -28c-6 -11 -12 -21 -20 -30s-16 -18 -25 -26c-18 -15 -40 -27 -62 -36c-23 -9 -48 -14 -73 -15s-51 3 -75 11c-23 7 -45 19 -65 33
+c-19 14 -36 31 -50 50c-7 10 -13 20 -18 31s-9 21 -13 33c-6 18 -9 37 -10 56c-1 20 1 39 5 58c5 24 15 47 28 68c12 19 26 35 42 50s35 27 55 36c23 11 48 19 74 21c10 1 19 1 29 1c13 0 26 -2 38 -4c24 -5 47 -14 68 -26s41 -29 57 -48c15 -18 27 -37 36 -58
+c4 -10 7 -21 10 -32c2 -8 5 -17 6 -26z" />
+ <glyph glyph-name="ion-load-d" unicode="&#xf29d;" horiz-adv-x="384"
+d="M368 208c9 0 16 -7 16 -16s-7 -16 -16 -16h-80c-9 0 -16 7 -16 16s7 16 16 16h80zM112 192c0 -9 -7 -16 -16 -16h-80c-9 0 -16 7 -16 16s7 16 16 16h80c9 0 16 -7 16 -16zM192 112c9 0 16 -7 16 -16v-80c0 -9 -7 -16 -16 -16s-16 7 -16 16v80c0 9 7 16 16 16zM192 384
+c9 0 16 -7 16 -16v-80c0 -9 -7 -16 -16 -16s-16 7 -16 16v80c0 9 7 16 16 16zM261 232c-4 8 -2 18 6 22l69 40c8 4 18 2 22 -6s2 -18 -6 -22l-69 -40c-8 -4 -18 -2 -22 6zM123 152c4 -8 2 -18 -6 -22l-69 -40c-8 -4 -18 -2 -22 6s-2 18 6 22l69 40c8 4 18 2 22 -6zM254 117
+l40 -69c4 -8 2 -18 -6 -22s-18 -2 -22 6l-40 69c-4 8 -2 18 6 22s18 2 22 -6zM118 352l40 -69c4 -8 2 -18 -6 -22s-18 -2 -22 6l-40 69c-4 8 -2 18 6 22s18 2 22 -6zM232 261c-8 4 -10 14 -6 22l40 69c4 8 14 10 22 6s10 -14 6 -22l-40 -69c-4 -8 -14 -10 -22 -6zM152 123
+c8 -4 10 -14 6 -22l-40 -69c-4 -8 -14 -10 -22 -6s-10 14 -6 22l40 69c4 8 14 10 22 6zM352 118c8 -4 10 -14 6 -22s-14 -10 -22 -6l-69 40c-8 4 -10 14 -6 22s14 10 22 6zM32 266c-8 4 -10 14 -6 22s14 10 22 6l69 -40c8 -4 10 -14 6 -22s-14 -10 -22 -6z" />
<glyph glyph-name="ion-location" unicode="&#xf1ff;" horiz-adv-x="239"
d="M119 384c66 0 120 -54 120 -120c0 -115 -120 -264 -120 -264s-119 149 -119 264c0 66 53 120 119 120zM119 206c31 0 57 25 57 56s-26 57 -57 57s-56 -26 -56 -57s25 -56 56 -56z" />
+ <glyph glyph-name="ion-lock-combination" unicode="&#xf4d4;" horiz-adv-x="384"
+d="M320 271c39 -35 64 -86 64 -143c0 -106 -86 -192 -192 -192s-192 86 -192 192c0 57 25 108 64 143v49c0 71 57 128 128 128s128 -57 128 -128v-49zM96 320v-26c28 16 61 26 96 26s68 -10 96 -26v26c0 53 -43 96 -96 96s-96 -43 -96 -96zM192 -32c88 0 160 72 160 160
+s-72 160 -160 160s-160 -72 -160 -160s72 -160 160 -160zM192 272c80 0 144 -64 144 -144s-64 -144 -144 -144s-144 64 -144 144s64 144 144 144zM315 95c2 9 4 18 4 29h-7v7h8c0 11 -2 20 -5 30l-25 -7l-4 12l25 8c-4 10 -8 18 -14 26l-11 -8l-4 6l11 8c-6 8 -13 16 -21 22
+l-15 -21l-11 8l15 20c-8 6 -17 11 -27 14l-4 -13l-6 2l5 13c-9 3 -20 5 -29 5v-13v-6h-16v6v13c-11 -1 -19 -2 -29 -5l4 -12l-6 -2l-4 12c-10 -3 -19 -8 -27 -14l15 -20l-10 -8l-15 21c-8 -6 -16 -14 -22 -22l11 -8l-4 -5l-10 8c-6 -8 -10 -17 -14 -27l24 -8l-5 -12l-25 7
+c-3 -10 -3 -19 -3 -30h6v-7h-5c0 -11 2 -20 4 -29l24 7l4 -12l-24 -8c4 -10 8 -19 14 -27l9 7l4 -5l-9 -7c6 -8 13 -16 21 -22l15 21l10 -8l-15 -20c8 -5 17 -11 27 -14l3 11l7 -2l-4 -11c10 -3 18 -4 29 -5v13v6h16v-6v-13c9 1 19 2 29 5l-5 12l6 2l4 -12c10 3 19 8 27 14
+l-15 20l11 8l15 -21c8 6 15 14 21 22l-11 7l4 6l10 -8c6 8 11 17 15 27l-25 8l4 12zM111 128c0 54 27 81 81 81s81 -27 81 -81s-27 -81 -81 -81s-81 27 -81 81z" />
<glyph glyph-name="ion-locked" unicode="&#xf200;" horiz-adv-x="384"
d="M22 -32c-12 0 -22 10 -22 22v212c0 12 10 22 22 22h3h19v31c0 42 17 87 43 115s64 46 105 46v0v0c41 0 79 -18 105 -46s43 -73 43 -115v-31h22c12 0 22 -10 22 -22v-212c0 -12 -10 -22 -22 -22h-340zM97 255v-31h17h155h18v31c0 27 -10 61 -28 80v0v1
c-18 19 -42 29 -67 29v0v0c-25 0 -49 -10 -67 -29v-1v0c-18 -19 -28 -53 -28 -80z" />
- <glyph glyph-name="ion-log-in" unicode="&#xf29e;" horiz-adv-x="384"
-d="M160 160v48h-152c-4 0 -8 4 -8 8v16c0 4 4 8 8 8h152v48l64 -64zM376 384c4 0 8 -4 8 -8v-302c0 -8 0 -10 -9 -15l-119 -59v64h-152c-4 0 -8 4 -8 8v104h32v-80h128v224l48 32h-176v-80h-32v104c0 4 4 8 8 8h272z" />
- <glyph glyph-name="ion-log-out" unicode="&#xf29f;" horiz-adv-x="384"
-d="M320 288l64 -64l-64 -64v48h-152c-4 0 -8 4 -8 8v16c0 4 4 8 8 8h152v48zM288 272h-32v80h-176l48 -32v-224h128v80h32v-104c0 -4 -4 -8 -8 -8h-152v-64l-119 59c-9 5 -9 7 -9 15v302c0 4 4 8 8 8h272c4 0 8 -4 8 -8v-104z" />
- <glyph glyph-name="ion-loop" unicode="&#xf201;" horiz-adv-x="512"
-d="M273.4 147.5l-0.300781 -58c48.9004 8.2002 86.3008 51 86.3008 102.5c0 15.9004 -3.60059 31 -10 44.5c-2.80078 5.7998 -6 11.2998 -9.80078 16.5l47.1006 43.5c1.09961 -1.2998 2.09961 -2.7002 3.09961 -4c20.9004 -28 33.2002 -62.7998 33.2002 -100.5v-3.7002
-c-1.5 -71.5 -47.5996 -132 -111.4 -154.6c-12.2998 -4.2998 -25.1992 -7.2998 -38.5 -8.7002l-0.0996094 -57l-76.2002 67l-26.2002 23l44.4004 38.7002zM89 195.7c1.59961 72.0996 48.2998 133 112.9 155.2c11.6992 4 24 6.7998 36.7998 8.09961l0.0996094 57
-l76.1006 -66.9004l26.1992 -23.0996l-44.2998 -38.5996l-58.3994 -50.9004l0.199219 57.9004c-48.7998 -8.30078 -86 -51.1006 -86 -102.4c0 -16 3.60059 -31.0996 10.1006 -44.7002c2.7002 -5.7998 6 -11.2002 9.7002 -16.2998l-47 -43.5996
-c-1.30078 1.59961 -2.60059 3.2998 -3.80078 5c-20.5 27.8994 -32.5996 62.2998 -32.5996 99.5996v3.7002z" />
+ <glyph glyph-name="ion-log-in" unicode="&#xf29e;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224c-96 0 -177 60 -209 144h34c9 -20 23 -40 39 -56c36 -36 85 -56 136 -56s100 20 136 56s56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56c-16 -16 -30 -36 -39 -56h-34c32 84 113 144 209 144z
+M175 124l52 52h-227v32h227l-52 52l22 23l91 -91l-91 -91z" />
+ <glyph glyph-name="ion-log-out" unicode="&#xf29f;"
+d="M335 124l52 52h-227v32h227l-52 52l22 23l91 -91l-91 -91zM359 56c3 3 6 5 8 8h41c-40 -58 -108 -96 -184 -96c-124 0 -224 100 -224 224s100 224 224 224c76 0 144 -38 184 -96h-41c-2 3 -5 5 -8 8c-36 36 -84 56 -135 56s-100 -20 -136 -56s-56 -85 -56 -136
+s20 -100 56 -136s85 -56 136 -56s99 20 135 56z" />
+ <glyph glyph-name="ion-loop" unicode="&#xf201;" horiz-adv-x="334"
+d="M184 148v-58c49 8 86 50 86 102c0 16 -4 30 -10 44c-3 6 -5 12 -9 17l47 43c1 -1 2 -3 3 -4c21 -28 33 -62 33 -100v-4c-2 -72 -47 -131 -111 -154c-12 -4 -26 -8 -39 -9v-57l-76 67l-26 23l44 39zM0 196c2 72 48 133 113 155c12 4 24 7 37 8v57l76 -67l26 -23l-44 -39
+l-59 -51l1 58c-49 -8 -86 -51 -86 -102c0 -16 4 -31 10 -45c3 -6 5 -11 9 -16l-47 -44c-1 2 -2 3 -3 5c-20 28 -33 63 -33 100v4z" />
<glyph glyph-name="ion-magnet" unicode="&#xf2a0;" horiz-adv-x="384"
d="M192 416c115 0 192 -78 192 -200c0 -49 -3 -77 -15 -128c-16 -66 -39 -113 -39 -113v-1c-2 -3 -6 -6 -10 -6c-1 0 -3 1 -4 1l-2 1l-50 20l-2 1c-3 2 -5 5 -5 9c0 1 0 3 1 4v1c7 16 27 59 37 101s13 63 13 108c0 71 -52 122 -116 122s-116 -51 -116 -122
c0 -45 3 -66 13 -108s30 -85 37 -101v-1c1 -1 1 -3 1 -4c0 -4 -2 -7 -5 -9l-2 -1l-50 -20l-2 -1c-1 0 -3 -1 -4 -1c-4 0 -8 3 -10 6v1s-24 47 -40 113c-12 51 -14 79 -14 128c0 122 77 200 192 200zM109 4c-9 19 -27 59 -36 98l-42 -12c13 -53 30 -92 35 -104l43 17v1z
@@ -1376,10 +1589,10 @@ s56 -38 90 -38s66 14 90 38z" />
d="M84 341c-21 0 -37 17 -37 38s16 37 37 37s37 -16 37 -37s-16 -38 -37 -38zM121 333c28 0 47 -24 47 -48v-114c0 -22 -32 -22 -32 0v105h-5v-286c0 -28 -41 -31 -43 0v165h-1h-7v-165c-1 -29 -43 -30 -43 0v286h-6v-105c0 -22 -31 -22 -31 0v114c0 24 19 48 47 48h37h37z
" />
<glyph glyph-name="ion-map" unicode="&#xf203;"
-d="M441 311c4 -3 7 -8 7 -14v-281c0 -6 -3 -11 -8 -14c-2 -1 -5 -2 -7 -2c-3 0 -5 0 -7 2l-97 66l-97 -66c-5 -3 -11 -3 -16 0l-97 66l-97 -66c-4 -3 -10 -3 -15 0s-7 8 -7 14v281c0 6 3 11 7 14l105 71c5 3 10 3 15 0l97 -66l97 66c5 3 10 3 15 0zM103 95v241l-71 -49v-242
-zM135 95l73 -49v131l-4 -13c-7 2 -14 6 -21 10l9 13c6 -4 10 -6 16 -8v109l-73 49v-101c4 -2 8 -4 12 -7l-9 -13c-1 1 -2 1 -3 2v-123zM240 46l73 49v109l-2 -2c-2 -2 -3 -4 -5 -6l-12 11c2 2 3 4 5 6c3 3 6 7 9 10l5 -5v119l-73 -49v-112h6l3 -15c-3 0 -6 -1 -9 -1v0v-114z
-M416 46v0v242l-71 49v-88c3 1 5 2 8 2l3 -15c-4 -1 -7 -2 -11 -4v-137zM67 192v-1l-16 5l1 1c2 7 4 13 9 20l13 -9c-4 -5 -5 -10 -7 -16zM97 227c-3 -1 -11 -5 -14 -7l-11 12c4 3 7 6 11 8c3 2 7 3 10 4l5 -15c-2 -1 1 -1 -1 -2zM264 182c5 2 11 5 16 10l10 -12
-c-6 -6 -12 -9 -19 -12zM166 210c4 -4 6 -7 10 -11l-11 -12c-4 4 -7 9 -11 13l-3 3l12 11c1 -1 2 -3 3 -4zM376 218l-12 12l11 10l-11 10l12 12l10 -11l10 11l12 -12l-11 -10l11 -10l-12 -12l-10 11z" />
+d="M441 311c4 -3 7 -8 7 -14v-281c0 -6 -2 -11 -7 -14c-2 -1 -5 -2 -7 -2c-3 0 -6 0 -8 2l-97 66l-97 -66c-5 -3 -10 -3 -15 0l-97 66l-97 -66c-5 -3 -10 -3 -15 0s-8 8 -8 14v281c0 6 3 11 7 14l105 71c5 3 10 3 15 0l97 -66l98 66c5 3 10 3 15 0zM103 95v242l-71 -50v-242
+zM135 95l73 -49v129l-4 -11c-7 2 -13 6 -20 10l8 13c5 -3 11 -6 16 -8v109l-73 49v-101c4 -2 9 -4 13 -7l-10 -13c-1 1 -2 1 -3 2v-123zM240 46l73 49v109c0 -1 -1 -1 -1 -2l-6 -6l-12 11l6 6c3 3 5 7 8 10l5 -5v119l-73 -49v-112h7l3 -15c-3 0 -6 -1 -9 -1h-1v-114zM416 46
+v242l-71 49v-88c3 1 5 1 8 2l4 -16c-4 -1 -8 -1 -12 -3v-137zM97 227c-3 -1 -11 -5 -14 -7l-11 12c4 3 8 6 12 8c3 2 6 3 9 4l5 -15c-2 -1 1 -1 -1 -2zM265 182c5 3 10 5 15 10l11 -12c-6 -6 -12 -10 -19 -13zM67 192v-1l-15 5v1c2 7 4 13 9 20l13 -9c-4 -5 -5 -10 -7 -16z
+M166 210c3 -4 7 -8 11 -11l-11 -12c-4 4 -8 9 -12 13l-3 3l12 11c1 -1 2 -3 3 -4zM376 218l-11 12l10 10l-10 10l11 12l10 -11l11 11l11 -12l-10 -10l10 -10l-11 -12l-11 11z" />
<glyph glyph-name="ion-medkit" unicode="&#xf2a2;"
d="M440 304c4 0 8 -4 8 -8v-288c0 -4 -4 -8 -8 -8h-432c-4 0 -8 4 -8 8v288c0 4 4 8 8 8h120v31c1 28 22 49 51 49h45h45c30 0 50 -21 51 -49v-31h120zM160 331v-27h128v27v1v1c0 10 -9 19 -19 19h-45h-45c-10 0 -19 -9 -19 -19v-1v-1zM320 128v64h-64v64h-64v-64h-64v-64
h64v-64h64v64h64z" />
@@ -1443,6 +1656,11 @@ c-12 0 -23 -3 -33 -9l-80 138c35 20 73 31 113 31s78 -10 113 -30l-81 -139c-10 6 -2
<glyph glyph-name="ion-outlet" unicode="&#xf342;"
d="M338 416c61 0 110 -51 110 -113v-222c0 -62 -49 -113 -110 -113h-228c-61 0 -110 51 -110 113v222c0 62 49 113 110 113h228zM143 197v102c0 11 -9 21 -20 21h-23c-11 0 -19 -9 -20 -20v-2v-101v-1c0 -11 9 -20 20 -20h23c11 0 20 9 20 20v1zM265 52v29
c0 23 -18 42 -41 42s-41 -19 -41 -42v-29v0c0 -11 9 -20 20 -20h21h21c11 0 20 7 20 18v2zM368 197v102c0 11 -9 21 -20 21h-24c-11 0 -19 -9 -20 -20v-2v-101v-1c0 -11 9 -20 20 -20h24c11 0 20 9 20 20v1z" />
+ <glyph glyph-name="ion-paintbrush" unicode="&#xf4d5;"
+d="M118 165c52 0 102 -41 90 -102c-11 -52 -54 -71 -90 -77c-30 -5 -100 0 -118 35c24 9 34 26 34 49c0 49 32 95 84 95zM436 388c13 -13 17 -30 5 -45l-154 -175c2 -9 1 -17 -3 -23l-50 -58v0v0c-2 -2 -4 -2 -6 0c-1 1 -1 2 -1 3v1c2 53 -41 87 -89 90v0h-2s-2 0 -2 1
+c-2 2 -2 4 0 6l59 49c6 4 14 4 23 2l175 154c15 12 32 8 45 -5zM134 188v0v0v0z" />
+ <glyph glyph-name="ion-paintbucket" unicode="&#xf4d6;" horiz-adv-x="480"
+d="M112 384l32 32l275 -276l-58 -12l-163 -160l-198 192l152 152zM309 160l-110 110l-110 -110h220zM419 140c0 0 61 -66 61 -99s-27 -60 -61 -60s-60 27 -60 60s60 99 60 99z" />
<glyph glyph-name="ion-paper-airplane" unicode="&#xf2c3;"
d="M0 176l448 240l-112 -448l-112 112l-80 -112l-16 160zM319 31l80 323l-322 -173l83 -31l192 154l-128 -176z" />
<glyph glyph-name="ion-paperclip" unicode="&#xf20f;" horiz-adv-x="160"
@@ -1469,11 +1687,9 @@ c0 -8 -5 -14 -12 -17c-1 0 -1 -1 -2 -1v0c-6 -3 -10 -6 -10 -13v-5l18 -118c2 -8 7 -
d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c32 32 51 75 55 120l-63 8v16l63 8c-4 45 -23 88 -55 120s-75 51 -120 55l-8 -63h-16l-8 63c-45 -4 -88 -23 -120 -55s-51 -75 -55 -120l63 -8v-16l-63 -8
c4 -45 23 -88 55 -120s75 -51 120 -55l8 63h16l8 -63c45 4 88 23 120 55z" />
<glyph glyph-name="ion-pizza" unicode="&#xf2a8;" horiz-adv-x="352"
-d="M317 317c5 -2 8 -7 8 -13c0 -2 0 -4 -1 -6v0l-148 -330l-148 330v0c-1 2 -1 4 -1 6c0 6 3 11 8 13v0c1 0 1 0 2 1v0c42 18 90 28 139 28s97 -10 139 -28v0s0 -1 1 -1h1zM167 330c-4 -2 -5 -7 -3 -11c0 -1 5 -9 14 -15c12 -8 27 -8 41 0c4 2 5 7 3 11s-7 5 -11 3
-c-9 -5 -16 -5 -23 0c-6 4 -10 9 -10 9c-2 4 -7 5 -11 3zM80 288c0 -18 14 -32 32 -32s32 14 32 32s-14 32 -32 32s-32 -14 -32 -32zM134 187c1 10 5 16 13 19c6 3 13 3 13 3c4 0 8 3 8 7s-3 9 -7 9c-1 0 -10 0 -20 -4c-14 -6 -22 -17 -23 -33c0 -4 3 -9 7 -9s9 4 9 8z
-M188 53c13 7 20 20 20 36c0 4 -5 7 -9 7s-7 -4 -7 -8c0 -10 -4 -17 -11 -21c-6 -3 -13 -3 -13 -3c-4 0 -8 -5 -8 -9s5 -7 9 -7c1 0 10 0 19 5zM176 109c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM240 224c18 0 32 14 32 32s-14 32 -32 32
-s-32 -14 -32 -32s14 -32 32 -32zM344 382c5 -2 8 -7 8 -13c0 -2 0 -3 -1 -5v-1l-7 -16l-1 -3c-2 -5 -7 -8 -13 -8c-2 0 -4 1 -6 2h-1c-45 19 -95 30 -147 30s-102 -11 -147 -30v0c-2 -1 -4 -2 -6 -2c-6 0 -12 4 -14 9l-1 2l-7 16v1c-1 2 -1 3 -1 5c0 6 3 11 8 13v0
-c1 0 1 1 2 1v0c51 21 107 33 166 33s115 -12 166 -33v0c1 0 1 -1 2 -1z" />
+d="M315 318c10 -4 12 -13 9 -20l-148 -330s-143 320 -148 331s2 16 9 19c39 18 90 28 139 28s96 -9 139 -28zM112 256c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM176 109c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM240 224
+c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM342 382c6 -3 10 -6 10 -13c0 -1 0 -3 -1 -5l-8 -19c-3 -5 -8 -9 -14 -9c-1 0 -3 1 -6 2c-41 18 -95 30 -147 30s-102 -11 -147 -30c-3 -1 -4 -2 -6 -2c-6 0 -11 4 -14 9l-8 19s-1 2 -1 5c0 8 6 12 10 14
+c49 21 107 33 166 33s118 -13 166 -34z" />
<glyph glyph-name="ion-plane" unicode="&#xf214;"
d="M250 136c0 -7 1 -69 -6 -102c-1 -4 3 -4 5 -7l51 -33c2 -2 3 -8 3 -8l1 -18l-68 16l-12 -32l-12 32l-68 -16l1 18s0 6 2 8l52 33c2 3 6 3 5 7c-7 33 -6 95 -6 102s-8 5 -8 5l-62 -13l-128 -49c0 23 2 26 9 31l183 131s5 63 5 113c0 24 12 78 27 78s27 -54 27 -78
c0 -53 5 -113 5 -113l183 -131c6 -4 9 -7 9 -31l-128 49l-62 13s-8 2 -8 -5z" />
@@ -1521,21 +1737,16 @@ d="M48 324v-68h-48v68c0 33 28 60 61 60h67v-48h-68c-7 0 -12 -5 -12 -12zM356 384c3
c0 -7 5 -12 12 -12z" />
<glyph glyph-name="ion-quote" unicode="&#xf347;" horiz-adv-x="384"
d="M128 384c-41 0 -73 -11 -95 -33s-33 -54 -33 -95v-256h160v256h-96c0 23 5 39 15 49s26 15 49 15zM352 384c-41 0 -73 -11 -95 -33s-33 -54 -33 -95v-256h160v256h-96c0 23 5 39 15 49s26 15 49 15z" />
- <glyph glyph-name="ion-radio-waves" unicode="&#xf2ac;" horiz-adv-x="384"
-d="M128 192c0 43 21 64 64 64s64 -21 64 -64s-21 -64 -64 -64s-64 21 -64 64zM96 192c0 -9 1 -17 3 -25s6 -16 10 -23s8 -13 14 -19s12 -11 19 -15l-23 -23c-6 4 -12 10 -17 15c-25 25 -38 55 -38 90s13 65 38 90c6 6 11 11 17 15l23 -23c-14 -9 -25 -20 -33 -35
-s-13 -30 -13 -47zM288 192c0 11 -2 22 -6 33s-9 20 -16 28s-15 15 -24 21l23 23c6 -4 12 -10 17 -15c25 -25 38 -55 38 -90s-13 -65 -38 -90c-6 -6 -11 -11 -17 -15l-23 23c14 9 25 20 33 35s13 30 13 47zM32 192c0 -26 6 -50 17 -72s27 -41 47 -56l-23 -23
-c-6 5 -11 9 -17 15c-18 18 -31 38 -41 61c-10 24 -15 49 -15 75s5 51 15 75c10 23 23 43 41 61c6 6 11 10 17 15l23 -23c-13 -10 -24 -21 -34 -34s-17 -28 -22 -44s-8 -33 -8 -50zM352 192c0 26 -6 50 -17 72s-27 41 -47 56l22 23c6 -5 12 -9 18 -15c18 -18 31 -38 41 -61
-c10 -24 15 -49 15 -75s-5 -51 -15 -75c-10 -23 -23 -43 -41 -61c-6 -6 -12 -10 -18 -15l-22 23c20 15 36 34 47 56s17 46 17 72z" />
+ <glyph glyph-name="ion-radio-waves" unicode="&#xf2ac;"
+d="M160 192c0 43 21 64 64 64s64 -21 64 -64s-21 -64 -64 -64s-64 21 -64 64zM112 192c0 -18 5 -35 13 -50s19 -28 33 -37l-23 -25c-6 5 -13 10 -18 16c-25 26 -37 59 -37 96s12 70 37 96c5 6 12 11 18 16l23 -25c-14 -9 -25 -22 -33 -37s-13 -32 -13 -50zM336 192
+c0 18 -5 35 -13 50s-19 28 -33 37l23 25c6 -5 13 -10 18 -16c25 -26 37 -59 37 -96s-12 -70 -37 -96c-5 -6 -12 -11 -18 -16l-23 25c14 9 25 22 33 37s13 32 13 50zM32 192c0 -27 6 -53 17 -77s27 -43 47 -59l-23 -24c-6 5 -12 10 -17 16c-18 19 -31 41 -41 65
+c-10 25 -15 51 -15 79s5 54 15 79c10 24 23 46 41 65c5 6 11 11 17 16l23 -24c-10 -8 -18 -17 -26 -27s-14 -21 -20 -32s-10 -24 -13 -37s-5 -26 -5 -40zM416 192c0 27 -6 53 -17 77s-27 43 -47 59l23 24c6 -5 12 -10 17 -16c18 -19 31 -41 41 -65c10 -25 15 -51 15 -79
+s-5 -54 -15 -79c-10 -24 -23 -46 -41 -65c-4 -5 -10 -10 -17 -16l-23 24c20 16 36 35 47 59s17 50 17 77z" />
<glyph glyph-name="ion-record" unicode="&#xf21b;" horiz-adv-x="416"
d="M208 -16c-115 0 -208 93 -208 208s93 208 208 208s208 -93 208 -208s-93 -208 -208 -208z" />
- <glyph glyph-name="ion-refresh" unicode="&#xf21c;" horiz-adv-x="512"
-d="M416 96l-104 112h73.5c-6.7002 65.4004 -63.0996 112 -129.5 112c-70.5996 0 -128 -57 -128 -128s57.4004 -128 128 -128c27.5 0 52.9004 7.90039 75 24.2002l6.2002 4.59961l43.2002 -46.2002l-7.5 -5.89941c-33.8008 -26.5 -74 -40.6006 -116.9 -40.7002
-c-91 0.200195 -167.4 63.5996 -187.1 148.6v0.100586c-0.200195 1 -0.5 2.09961 -0.700195 3.2002c-0.100586 0.399414 -0.200195 0.899414 -0.299805 1.39941c-0.100586 0.700195 -0.300781 1.40039 -0.400391 2.10059c-0.200195 0.799805 -0.299805 1.69922 -0.5 2.59961
-c-0.0996094 0.400391 -0.0996094 0.700195 -0.200195 1.09961c-0.200195 1.2002 -0.399414 2.40039 -0.599609 3.60059v0.200195c-0.900391 6.19922 -1.60059 12.5996 -1.90039 19.0996v0.900391c-0.0996094 1.39941 -0.200195 2.69922 -0.200195 4.09961
-c-0.0996094 1.7002 -0.0996094 3.2998 -0.0996094 5s0.0996094 3.40039 0.0996094 5c0.100586 1.40039 0.100586 2.7002 0.200195 4.09961v0.800781c0.299805 6.39941 0.900391 12.7998 1.90039 19.0996v0.200195c0.200195 1.2002 0.399414 2.39941 0.599609 3.59961
-c0.100586 0.400391 0.100586 0.700195 0.200195 1.10059c0.200195 0.899414 0.299805 1.69922 0.5 2.59961c0.0996094 0.700195 0.299805 1.40039 0.400391 2.09961c0.0996094 0.5 0.199219 0.900391 0.299805 1.40039c0.200195 1.09961 0.399414 2.2002 0.700195 3.2998
-v0.100586c19.6992 85 95.7998 148.399 186.699 148.6v0h0.400391c10.5996 0 21.0996 -0.900391 31.2002 -2.59961c0.5 0 0.899414 -0.100586 1.39941 -0.200195c0.700195 -0.100586 1.5 -0.299805 2.2002 -0.400391c57.2002 -10.5 105.601 -46.3994 133 -95.5996
-c13 -23.2998 21.2002 -49.4004 23.5 -77.2998h64.7002z" />
+ <glyph glyph-name="ion-refresh" unicode="&#xf21c;"
+d="M352 96l-104 112h74c-7 65 -64 112 -130 112c-71 0 -128 -57 -128 -128s57 -128 128 -128c28 0 53 8 75 24l6 5l43 -46l-7 -6c-34 -26 -74 -41 -117 -41c-91 0 -167 64 -187 149v0c0 1 -1 2 -1 3v1v2s-1 2 -1 3v1c0 1 -1 3 -1 4v0c-1 6 -2 13 -2 19v1v4v5v5v4v1
+c0 6 1 13 2 19v0c0 1 1 3 1 4v1c0 1 1 1 1 2v3v1c0 1 1 2 1 3v0c20 85 96 149 187 149v0v0c11 0 21 -1 31 -3h2h2c57 -10 106 -47 133 -96c13 -23 21 -49 23 -77h65z" />
<glyph glyph-name="ion-reply-all" unicode="&#xf21d;" horiz-adv-x="416"
d="M257 256c153 0 159 -208 159 -208c-51 93 -91 102 -159 102v-92l-152 134l152 144v-80zM0 192l144 136v-57l-82 -79l82 -68v-58z" />
<glyph glyph-name="ion-reply" unicode="&#xf21e;" horiz-adv-x="384"
@@ -1546,11 +1757,15 @@ s-43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96zM176 184c49 0 88 -39 88 -88s-39 -88
<glyph glyph-name="ion-ribbon-b" unicode="&#xf349;" horiz-adv-x="384"
d="M192 376c49 0 88 -39 88 -88s-39 -88 -88 -88s-88 39 -88 88s39 88 88 88zM192 416c71 0 128 -57 128 -128s-57 -128 -128 -128s-128 57 -128 128s57 128 128 128zM192 192c53 0 96 43 96 96s-43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96zM83 194c26 -30 65 -50 109 -50
c12 0 23 1 34 4l-34 -74l-48 -106l-48 80h-96zM301 194l83 -146h-96l-48 -80l-40 88l45 98c22 9 41 23 56 40z" />
- <glyph glyph-name="ion-sad" unicode="&#xf34a;"
+ <glyph glyph-name="ion-sad-outline" unicode="&#xf4d7;"
d="M367 164c3 -9 -2 -17 -11 -19c-3 -1 -7 0 -10 1c-5 2 -9 5 -11 10s-4 12 -13 15s-14 0 -19 -3c-4 -3 -10 -3 -15 -1c-3 1 -7 3 -9 6c-6 8 -3 17 5 22c15 9 29 13 49 6s29 -21 34 -37zM165 195c8 -5 10 -14 4 -22c-2 -3 -6 -5 -9 -6c-5 -2 -11 -2 -15 1c-5 3 -10 6 -19 3
s-11 -10 -13 -15s-6 -8 -11 -10c-3 -1 -7 -2 -10 -1c-9 2 -14 10 -11 19c5 16 14 30 34 37s35 3 50 -6zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56
s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56s100 20 136 56zM317 89c5 -7 3 -17 -4 -22c-3 -2 -6 -3 -9 -3c-5 0 -10 3 -13 7c0 0 -19 25 -67 25s-67 -25 -67 -25c-3 -4 -8 -7 -13 -7c-3 0 -6 1 -9 3c-7 5 -9 15 -4 22c1 2 28 39 93 39
s92 -37 93 -39z" />
+ <glyph glyph-name="ion-sad" unicode="&#xf34a;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM113 156c2 5 4 12 13 15s14 0 19 -3c4 -3 10 -3 15 -1c3 1 7 3 9 6c6 8 4 17 -4 22c-15 9 -30 13 -50 6s-29 -21 -34 -37c-3 -9 2 -17 11 -19c3 -1 7 0 10 1c5 2 9 5 11 10z
+M313 67c7 5 9 15 4 22c-1 2 -28 39 -93 39s-92 -37 -93 -39c-5 -7 -3 -17 4 -22c3 -2 6 -3 9 -3c5 0 10 3 13 7c0 0 19 25 67 25s67 -25 67 -25c3 -4 8 -7 13 -7c3 0 6 1 9 3zM356 145c9 2 14 10 11 19c-5 16 -14 30 -34 37s-34 3 -49 -6c-8 -5 -11 -14 -5 -22
+c2 -3 6 -5 9 -6c5 -2 11 -2 15 1c5 3 10 6 19 3s11 -10 13 -15s6 -8 11 -10c3 -1 7 -2 10 -1z" />
<glyph glyph-name="ion-scissors" unicode="&#xf34b;" horiz-adv-x="384"
d="M341 332c-13 -33 -117 -172 -117 -172l-32 -32s-31 -13 -50 -43s-33 -71 -33 -71v0c-7 -26 -28 -46 -53 -46c-31 0 -56 29 -56 64s25 64 56 64c13 0 25 -5 34 -13c2 -1 3 -3 4 -4v0l2 -2c4 -4 7 -2 14 11c8 15 17 35 27 54s38 59 38 59l17 23l144 192
c23 -20 18 -51 5 -84zM56 0c15 0 28 14 28 32s-13 32 -28 32s-28 -14 -28 -32s13 -32 28 -32zM192 160c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM143 183c-30 41 -90 125 -100 149c-13 33 -18 64 5 84l134 -178l-3 -4v0v0l-17 -23v-1v0
@@ -1584,6 +1799,10 @@ c7 0 13 -7 13 -14s-5 -13 -13 -13zM225 309c-7 0 -13 6 -13 13s5 14 13 14c7 0 13 -7
d="M64 180v76h224v-76v-90c0 -7 -4 -14 -11 -14h-28v-52c0 -13 -11 -24 -24 -24v0h-1c-6 0 -10 2 -14 5c-5 4 -9 11 -9 19v52h-49v-52c0 -13 -11 -24 -24 -24s-24 11 -24 24v52h-29c-7 0 -11 7 -11 14v90zM328 272c13 0 24 -11 24 -24v-96c0 -13 -11 -24 -24 -24
s-24 11 -24 24v96c0 13 11 24 24 24zM24 272c13 0 24 -11 24 -24v-96c0 -13 -11 -24 -24 -24s-24 11 -24 24v96c0 13 11 24 24 24zM231 359c48 -21 56 -72 57 -87h-224c1 15 8 66 56 87l-18 22c0 1 0 1 1 2s3 1 3 1l19 -23c14 5 31 9 51 9s36 -4 50 -9l20 23c0 1 1 0 2 -1
l2 -2zM127 309c8 0 13 6 13 13s-6 14 -13 14c-8 0 -14 -7 -14 -14s7 -13 14 -13zM225 309c7 0 14 6 14 13s-7 14 -14 14c-8 0 -13 -7 -13 -14s6 -13 13 -13z" />
+ <glyph glyph-name="ion-social-angular-outline" unicode="&#xf4d8;"
+d="M224 384l-188 -69l39 -230l149 -80l149 80l39 230zM224 416v0l224 -80l-46 -272l-178 -96l-178 96l-46 272zM312 96l-27 56h-122l-27 -56h-40l128 280l128 -280h-40zM182 192h84l-42 89z" />
+ <glyph glyph-name="ion-social-angular" unicode="&#xf4d9;"
+d="M182 192l42 89l42 -89h-84zM224 416l224 -80l-46 -272l-178 -96l-178 96l-46 272zM312 96h40l-128 280l-128 -280h40l27 56h122z" />
<glyph glyph-name="ion-social-apple-outline" unicode="&#xf226;" horiz-adv-x="320"
d="M238 278c-15 0 -26 -4 -37 -8c-10 -4 -21 -8 -35 -8s-25 4 -37 8c-11 4 -22 8 -34 8c-11 0 -23 -3 -34 -10c-12 -7 -23 -18 -31 -31c-12 -18 -16 -47 -13 -77c3 -34 16 -69 35 -99c13 -21 30 -45 50 -45h1c8 0 13 3 20 6c10 5 23 10 44 10v0c21 0 34 -5 44 -10
c7 -3 12 -6 19 -6v0c22 0 44 35 52 48c8 12 12 20 17 31c-12 7 -22 16 -30 28c-10 15 -17 33 -18 52c-1 18 2 37 10 53c6 12 14 22 24 30c-14 13 -31 20 -47 20zM238 294v0c25 0 52 -14 71 -39c-63 -36 -53 -128 11 -153c-9 -20 -13 -28 -24 -46c-16 -25 -37 -56 -65 -56h-1
@@ -1611,6 +1830,27 @@ l-123 -60c-6 -3 -15 -4 -23 -4s-17 1 -23 4l-123 60l-19 -9l156 -75c2 -1 5 -2 9 -2s
d="M7 284c-9 4 -9 11 0 15l169 82c4 2 10 3 16 3s12 -1 16 -3l169 -82c9 -4 9 -11 0 -15l-169 -82c-4 -2 -10 -3 -16 -3s-12 1 -16 3zM377 200c9 -4 9 -12 0 -16l-169 -81c-4 -2 -10 -4 -16 -4s-12 2 -16 4l-169 81c-9 4 -9 12 0 16c0 0 27 13 33 16c5 3 7 3 13 0
s123 -60 123 -60c4 -2 10 -3 16 -3s12 1 16 3c0 0 121 59 125 61s5 2 9 0s35 -17 35 -17zM377 100c9 -4 9 -11 0 -15l-169 -82c-4 -2 -10 -3 -16 -3s-12 1 -16 3l-169 82c-9 4 -9 11 0 15c0 0 27 14 33 17c5 3 7 2 13 -1s123 -59 123 -59c4 -2 10 -3 16 -3s12 1 16 3
c0 0 121 58 125 60s5 2 9 0s35 -17 35 -17z" />
+ <glyph glyph-name="ion-social-chrome-outline" unicode="&#xf4da;"
+d="M224 416c123 0 224 -101 224 -224s-101 -224 -224 -224s-224 101 -224 224s101 224 224 224zM224 371c-57 0 -109 -27 -141 -68l54 -93c8 40 43 72 87 72h155c-30 54 -89 89 -155 89zM291 192c0 37 -30 67 -67 67s-67 -30 -67 -67s30 -67 67 -67s67 30 67 67zM45 192
+c0 -91 67 -166 154 -177l54 93c-9 -3 -19 -6 -29 -6c-34 0 -61 18 -77 45v0l-78 135c-16 -27 -24 -58 -24 -90zM224 13c99 0 179 80 179 179c0 24 -4 46 -13 67h-108c19 -17 32 -40 32 -67c0 -17 -5 -32 -13 -45v0z" />
+ <glyph glyph-name="ion-social-chrome" unicode="&#xf4db;"
+d="M157 192c0 37 30 67 67 67s67 -30 67 -67s-30 -67 -67 -67s-67 30 -67 67zM445 230c2 -12 3 -25 3 -38c0 -106 -74 -195 -174 -218c-10 -2 -20 -4 -30 -5c-7 -1 -13 -1 -20 -1c-8 0 -17 0 -25 1v0v0v0v1l102 177c8 13 13 28 13 45c0 27 -13 50 -32 67h156
+c3 -9 5 -19 7 -29v0c-2 10 -4 20 -7 29v0c3 -9 5 -19 7 -29v0zM224 103c10 0 20 2 29 5l-78 -135v0c-42 9 -79 30 -108 59c-42 41 -67 97 -67 160c0 31 6 61 18 88c7 16 16 31 26 45v0l103 -178c16 -27 43 -44 77 -44zM59 343v0v1c24 26 55 47 90 59c23 8 49 13 75 13
+c73 0 138 -36 179 -90h1c10 -14 18 -29 25 -44v0c-7 15 -15 30 -25 44h-1c10 -14 19 -29 26 -44h-205c-44 0 -79 -32 -87 -72z" />
+ <glyph glyph-name="ion-social-codepen-outline" unicode="&#xf4dc;"
+d="M356 244c5 -3 7 -6 7 -12v-81c0 -6 -3 -10 -8 -13c-41 -27 -82 -55 -123 -82c-6 -4 -11 -4 -17 0c-41 27 -81 55 -122 82c-5 3 -8 7 -8 13v80c0 6 3 11 8 14c41 27 81 54 122 81c6 4 11 4 17 0c41 -27 83 -55 124 -82zM236 296v-54c0 -1 1 -2 2 -3c16 -11 31 -21 47 -32
+c1 -1 3 -1 4 0l40 26zM212 295c0 0 -62 -41 -93 -62c14 -9 27 -17 40 -26c1 -1 3 -1 4 0c15 10 31 21 46 31c1 1 3 4 3 6v51zM109 211v-40l30 20zM212 87v53c0 1 -2 3 -3 4c-15 10 -31 21 -46 31c-2 1 -3 1 -5 0l-39 -26c31 -21 93 -62 93 -62zM227 165l39 26s-34 23 -40 27
+c-1 1 -4 0 -5 -1c-5 -3 -9 -6 -14 -9c-8 -6 -25 -17 -25 -17l39 -26c2 -1 4 -1 6 0zM236 87l93 62l-38 26c-2 2 -5 2 -7 0c-15 -10 -30 -21 -45 -31c-2 -2 -3 -3 -3 -6v-51zM338 171v40l-30 -20zM224 384c-51 0 -100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136
+s85 -56 136 -56s100 20 136 56s56 85 56 136s-20 100 -56 136s-85 56 -136 56zM224 416v0c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224z" />
+ <glyph glyph-name="ion-social-codepen" unicode="&#xf4dd;"
+d="M209 144c1 -1 3 -3 3 -4v-53s-62 41 -93 62l39 26c2 1 3 1 5 0c15 -10 31 -21 46 -31zM163 207c-1 -1 -3 -1 -4 0c-13 9 -26 17 -40 26c31 21 93 62 93 62v-51c0 -2 -2 -5 -3 -6c-15 -10 -31 -21 -46 -31zM238 239c-1 1 -2 2 -2 3v54l93 -63l-40 -26c-1 -1 -3 -1 -4 0
+c-16 11 -31 21 -47 32zM226 218c6 -4 40 -27 40 -27l-39 -26c-2 -1 -4 -1 -6 0l-39 26s17 11 25 17c5 3 9 6 14 9c1 1 4 2 5 1zM109 211l30 -20l-30 -20v40zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM363 151v81
+c0 6 -2 9 -7 12c-41 27 -83 55 -124 82c-6 4 -11 4 -17 0c-41 -27 -81 -54 -122 -81c-5 -3 -8 -8 -8 -14v-80c0 -6 3 -10 8 -13c41 -27 81 -55 122 -82c6 -4 11 -4 17 0c41 27 82 55 123 82c5 3 8 7 8 13zM284 175c2 2 5 2 7 0l38 -26l-93 -62v51c0 3 1 4 3 6
+c15 10 30 21 45 31zM338 171l-30 20l30 20v-40z" />
+ <glyph glyph-name="ion-social-css3-outline" unicode="&#xf4de;" horiz-adv-x="384"
+d="M291 81l-99 -28l-98 28l-7 78h48l4 -40l53 -15v0v0l54 15l5 64h-112l-4 50h121l4 51h-184l-4 49h241zM0 416h384l-35 -403l-157 -45l-157 45zM319 37l30 347h-314l30 -347l127 -36z" />
+ <glyph glyph-name="ion-social-css3" unicode="&#xf4df;" horiz-adv-x="384"
+d="M192 109v0zM0 416h384l-35 -403l-157 -45l-157 45zM291 81l22 252h-241l4 -49h184l-4 -51h-121l4 -50h112l-5 -64l-54 -15v0v0l-53 15l-4 40h-48l7 -78l98 -28z" />
<glyph glyph-name="ion-social-designernews-outline" unicode="&#xf22a;"
d="M259 302v-53l-65 103zM0 188zM297 352l151 -119v-201h-248l-200 156h63c46 0 77 33 77 82c0 20 -5 37 -15 51l-3 3l37 -29v-107h41l-2 98l63 -98h36v84v80zM432 48v178l-119 92v1v-47v-83v-17h-15h-37h-9l-4 8l-33 50l1 -42v-16h-16h-41h-16v16v29c-3 -6 -7 -12 -12 -17
c-8 -9 -18 -16 -30 -21s-24 -7 -38 -7h-16l159 -124h226zM59 298h-1h-3v-57h4c8 0 13 2 17 6c5 6 6 15 6 22c0 26 -12 29 -23 29zM59 314v0c25 0 39 -16 39 -45c0 -28 -14 -44 -40 -44h-19v89h20z" />
@@ -1629,19 +1869,25 @@ d="M113 371l79 -66l-114 -71l-78 63zM27 295l52 -42l86 53l-53 46zM306 235l78 -63l-
l-78 -63l-114 71l79 66zM219 305l86 -52l52 42l-85 56z" />
<glyph glyph-name="ion-social-dropbox" unicode="&#xf22f;" horiz-adv-x="384"
d="M113 371l79 -66l-114 -71l-78 63zM0 172l78 62l114 -70l-79 -66zM192 164l114 70l78 -62l-113 -74zM384 297l-78 -63l-114 71l79 66zM192 150l80 -66l34 22v-25l-114 -68l-114 68v25l34 -22z" />
+ <glyph glyph-name="ion-social-euro-outline" unicode="&#xf4e0;" horiz-adv-x="320"
+d="M214 384c-53 0 -91 -9 -115 -27c-22 -16 -33 -40 -33 -74v-11v-17h-16h-34v-16h34h16v-15v-48v-17h-16h-34v-16h34h16v-15v-27c0 -34 11 -58 33 -74c24 -18 62 -27 115 -27c31 0 59 2 88 8l-5 35c-30 -4 -55 -7 -80 -7c-36 0 -59 6 -74 19c-19 16 -21 40 -21 60v13v15h16
+h103l3 16h-106h-16v17v48v15h16h118l2 16h-120h-16v17v2c0 16 2 39 21 55c16 13 39 19 74 19c24 0 51 -3 80 -7l5 35c-29 6 -57 8 -88 8zM214 400v0c35 0 68 -3 106 -12l-9 -65c-37 6 -68 9 -94 9c-64 0 -79 -22 -79 -58v-3h139l-8 -48h-131v-48h124l-7 -48h-117v-12
+c0 -44 15 -63 79 -63c26 0 57 3 94 9l9 -65c-38 -9 -71 -12 -106 -12c-115 0 -164 41 -164 117v26h-50v48h50v48h-50v48h50v12c0 76 49 117 164 117z" />
+ <glyph glyph-name="ion-social-euro" unicode="&#xf4e1;" horiz-adv-x="320"
+d="M138 176h124l-7 -48h-117v-13c0 -44 15 -63 79 -63c26 0 56 3 93 9l10 -65c-38 -9 -71 -12 -106 -12c-115 0 -164 41 -164 117v27h-50v48h50v48h-50v48h50v11c0 76 49 117 164 117c35 0 68 -3 106 -12l-10 -65c-37 6 -67 9 -93 9c-64 0 -79 -22 -79 -58v-2h138l-7 -48
+h-131v-48z" />
<glyph glyph-name="ion-social-facebook-outline" unicode="&#xf230;" horiz-adv-x="192"
d="M128 256h64l-8 -64h-56v-192h-83v192h-45v64h45v43c0 54 23 85 91 85h56v-64h-34c-27 0 -30 -9 -30 -26v-38zM170 208l4 32h-45h-17v17v37c0 10 1 21 9 30c10 11 25 12 37 12h18v32h-40c-28 0 -49 -6 -60 -18c-10 -11 -15 -27 -15 -51v-43v-16h-15h-30v-32h30h15v-16
v-176h51v176v16h17h41z" />
<glyph glyph-name="ion-social-facebook" unicode="&#xf231;" horiz-adv-x="192"
d="M128 256h64l-8 -64h-56v-192h-83v192h-45v64h45v43c0 54 23 85 91 85h56v-64h-34c-27 0 -30 -9 -30 -26v-38z" />
- <glyph glyph-name="ion-social-foursquare-outline" unicode="&#xf34c;"
-d="M439 298c12 -12 12 -32 0 -44l-196 -197c-6 -6 -14 -9 -22 -9h-5v0c-6 1 -13 4 -17 9l-118 119c-12 12 -12 31 0 43l35 35c6 6 13 9 21 9s16 -3 22 -9l62 -62l140 141c6 6 13 9 21 9v0c8 0 16 -3 22 -9zM221 80l194 196l-33 33l-161 -162l-84 84l-33 -33zM338 323l-77 78
-zM259 402c-10 9 -23 14 -36 14s-25 -5 -35 -14c20 18 51 18 71 0zM431 229c11 -11 17 -23 17 -37c0 -13 -6 -26 -17 -37l-170 -172c-10 -10 -25 -15 -38 -15s-27 5 -37 15l-171 172c-20 20 -20 54 0 74l171 172c1 1 1 0 2 1c10 9 22 14 35 14s26 -5 36 -14c1 -1 1 0 2 -1
-l77 -78l-23 -22l-77 77c-4 4 -9 6 -15 6s-10 -2 -14 -6l-171 -171c-8 -8 -8 -22 0 -30l171 -171c4 -4 8 -6 14 -6s11 2 15 6l171 171c8 8 8 22 0 30h-1l23 23v-1z" />
- <glyph glyph-name="ion-social-foursquare" unicode="&#xf34d;"
-d="M444 302c3 -3 4 -6 4 -10s-1 -8 -4 -11l-213 -213c-3 -3 -6 -4 -10 -4v0v0h-2c-3 0 -7 2 -9 4l-118 119c-6 6 -6 15 0 21l35 35c3 3 6 4 10 4s8 -1 11 -4l73 -73l167 167c3 3 6 5 10 5s8 -2 11 -5zM431 230v-1c11 -11 17 -23 17 -37s-6 -25 -17 -37l-170 -172
-c-20 -20 -55 -20 -75 0l-171 172c-10 10 -15 24 -15 37s5 27 15 37l171 172c10 10 24 15 38 15s27 -5 37 -15l77 -78l-116 -116l-55 55c-8 8 -18 12 -29 12s-21 -4 -29 -12l-35 -35c-8 -8 -12 -18 -12 -29s4 -21 12 -29l119 -119c5 -5 12 -10 19 -12h2h8c11 0 21 4 29 12z
-" />
+ <glyph glyph-name="ion-social-foursquare-outline" unicode="&#xf34c;" horiz-adv-x="320"
+d="M302 284c-12 -60 -25 -131 -27 -138zM281 416c35 0 45 -20 37 -57c-3 -16 -10 -44 -16 -75l-27 -137c-3 -13 -8 -35 -39 -35h-72c-3 0 -3 0 -6 -3c-2 -2 -115 -133 -115 -133c-9 -10 -23 -8 -28 -6s-15 8 -15 26v380s10 40 43 40h238zM280 352c6 31 6 32 -24 32h-195
+c-29 0 -29 -3 -29 -28v-297c0 -38 1 -38 3 -38s10 8 29 31c0 0 78 89 79 90c2 2 3 2 6 2h62c26 0 28 6 33 31c4 21 36 177 36 177zM302 284c6 31 13 59 16 75zM233 352c5 0 9 -5 8 -11l-8 -44c-1 -4 -6 -9 -11 -9h-75c-8 0 -8 -5 -8 -13v-6c0 -8 0 -13 8 -13h64
+s11 -6 10 -12s-11 -51 -12 -54s-4 -9 -11 -9h-62c-9 0 -11 -1 -17 -8l-54 -63c-1 -1 -1 -1 -1 0v231c0 5 5 11 11 11h158z" />
+ <glyph glyph-name="ion-social-foursquare" unicode="&#xf34d;" horiz-adv-x="320"
+d="M281 416c35 0 45 -20 37 -57c-10 -49 -40 -202 -43 -213c-3 -13 -8 -34 -39 -34h-72c-3 0 -3 0 -6 -3c-2 -2 -115 -133 -115 -133c-9 -10 -23 -8 -28 -6s-15 8 -15 26v380s10 40 43 40h238zM275 146c3 11 33 164 43 213zM267 351c2 9 -5 16 -12 16h-191
+c-9 0 -15 -8 -15 -15v-296c0 -1 1 -1 2 0c0 0 70 84 78 94s11 11 23 11h64c9 0 14 8 15 12s8 43 10 51s-6 16 -13 16h-82c-10 0 -18 8 -18 18v13c0 10 8 17 18 17h96s14 6 15 12z" />
<glyph glyph-name="ion-social-freebsd-devil" unicode="&#xf2c4;" horiz-adv-x="512"
d="M503 333c19 -37 8 -81 -20 -108s-60 -33 -60 -33c2 -32 16 -59 -41 -102c-43 -32 2 -90 2 -90c10 -14 23 -19 32 -32h-272s15 14 -7 32c0 0 -20 17 -18 29s6 13 9 15s0 7 0 7l-19 19s-13 -13 -44 -13c-38 0 -65 39 -65 39h46s-6 -8 -7 -13c-1 -4 1 -5 1 -5s11 -6 22 -6
c17 0 33 12 33 12l-24 22l-15 -4l-16 37l39 -10l-1 -15l28 -18s9 9 7 27s-9 26 -9 26s-4 0 -9 -4s-6 -6 -6 -6l-10 44s43 -19 50 -63c3 -20 -6 -35 -6 -35l17 -10s6 5 17 7s23 2 29 -8s5 -12 4 -19s0 -9 6 -11s6 -6 11 -8s15 -6 21 -2s8 11 8 18v16s-9 8 -32 20
@@ -1678,6 +1924,10 @@ M206 80c0 20 -13 31 -50 56c-3 0 -4 1 -8 1c-6 0 -31 -2 -50 -8c-16 -6 -38 -16 -38
d="M352 352h-320v-320h320v320zM384 384v0v-384h-384v384h384zM233 289h45l-64 -120v-72h-40v72l-66 120h47l40 -84z" />
<glyph glyph-name="ion-social-hackernews" unicode="&#xf237;" horiz-adv-x="384"
d="M0 384h384v-384h-384v384zM214 169l64 120h-45l-38 -84l-40 84h-47l66 -120v-72h40v72z" />
+ <glyph glyph-name="ion-social-html5-outline" unicode="&#xf4e2;" horiz-adv-x="384"
+d="M0 416h384l-35 -403l-157 -45l-157 45zM319 37l30 347h-314l30 -347l127 -36zM84 184l-13 150h241l-4 -50h-184l4 -51h176l-14 -151l-98 -28l-99 28l-6 77h48l3 -39l54 -15l53 15l6 64h-167z" />
+ <glyph glyph-name="ion-social-html5" unicode="&#xf4e3;" horiz-adv-x="384"
+d="M0 416h384l-35 -403l-157 -45l-157 45zM308 284l4 50h-241l13 -150h167l-6 -64l-53 -15l-54 15l-3 39h-48l6 -78l99 -27l98 28l14 151h-176l-4 51h184z" />
<glyph glyph-name="ion-social-instagram-outline" unicode="&#xf350;" horiz-adv-x="384"
d="M384 336v-289c0 -26 -22 -47 -48 -47h-288c-26 0 -48 21 -48 47v289c0 26 22 48 48 48h288c26 0 48 -22 48 -48zM192 272c-44 0 -80 -36 -80 -80s36 -80 80 -80s80 36 80 80s-36 80 -80 80zM352 288v48c0 9 -7 16 -16 16h-48c-9 0 -16 -7 -16 -16v-48c0 -9 7 -16 16 -16
h48c9 0 16 7 16 16zM337 32c9 0 15 7 15 16v176h-52c3 -10 4 -21 4 -32c0 -30 -11 -58 -32 -79s-50 -33 -80 -33s-58 12 -79 33s-33 49 -33 79c0 11 2 22 5 32h-53v-176c0 -9 8 -16 17 -16h288z" />
@@ -1685,12 +1935,32 @@ h48c9 0 16 7 16 16zM337 32c9 0 15 7 15 16v176h-52c3 -10 4 -21 4 -32c0 -30 -11 -5
d="M112 192c0 53 27 80 80 80s80 -27 80 -80s-27 -80 -80 -80s-80 27 -80 80zM113 271c-14 -14 -23 -29 -28 -47h-85v112c0 13 4 25 14 34s22 14 35 14h288c13 0 24 -5 33 -14s14 -21 14 -34v-112h-84c-5 18 -14 33 -28 47c-22 22 -49 33 -80 33s-57 -11 -79 -33zM352 300
v39c0 4 -2 7 -4 9s-5 4 -9 4h-38c-4 0 -7 -2 -9 -4s-4 -5 -4 -9v-39c0 -4 2 -7 4 -9s5 -3 9 -3h38c4 0 7 1 9 3s4 5 4 9zM272 113c22 22 32 48 32 79h80v-144c0 -13 -5 -24 -14 -34s-20 -14 -33 -14h-288c-13 0 -24 4 -34 14s-15 21 -15 34v144h81c0 -31 10 -57 32 -79
s48 -33 79 -33s58 11 80 33z" />
+ <glyph glyph-name="ion-social-javascript-outline" unicode="&#xf4e4;"
+d="M160 344h-48v-196c0 -30 -6 -50 -17 -64c-11 -13 -26 -20 -48 -20c-9 0 -18 1 -25 2l-4 -30c11 -2 25 -4 37 -4c34 0 59 8 76 25c19 18 29 48 29 90v197zM176 360v0v-213c0 -97 -49 -131 -121 -131c-18 0 -40 3 -55 8l8 62c10 -4 24 -6 39 -6c31 0 49 15 49 68v212h80z
+M350 352c-34 0 -62 -9 -82 -26c-19 -15 -28 -36 -28 -60c0 -20 7 -36 21 -51c14 -14 34 -26 61 -36c23 -8 38 -15 48 -24c12 -11 18 -23 18 -38c0 -16 -7 -31 -20 -40c-12 -9 -28 -14 -48 -14c-28 0 -52 8 -70 15l-7 -32c18 -8 44 -14 72 -14c38 0 70 9 90 27
+c18 16 27 38 27 63c0 21 -5 36 -17 50s-31 27 -58 37v0v0c-38 15 -72 28 -72 63c0 14 7 27 19 36c11 9 26 13 45 13c24 0 43 -5 57 -11l10 32c-19 6 -42 10 -66 10zM350 368v0c38 0 65 -7 85 -16l-19 -64c-13 7 -35 17 -67 17s-48 -16 -48 -33c0 -22 19 -31 62 -48
+c58 -22 85 -53 85 -102c0 -57 -42 -106 -133 -106c-38 0 -72 10 -91 21l15 63v0c20 -11 49 -21 81 -21c34 0 52 15 52 38c0 21 -15 33 -55 47c-55 20 -93 52 -93 102c0 58 49 102 126 102z" />
+ <glyph glyph-name="ion-social-javascript" unicode="&#xf4e5;"
+d="M176 360v0v-213c0 -97 -49 -131 -121 -131c-18 0 -40 3 -55 8l8 62c10 -4 24 -6 39 -6c31 0 49 15 49 68v212h80zM350 368v0c38 0 65 -7 85 -16l-19 -64c-13 7 -35 17 -67 17s-48 -16 -48 -33c0 -22 19 -31 62 -48c58 -22 85 -53 85 -102c0 -57 -42 -106 -133 -106
+c-38 0 -72 10 -91 21l15 63v0c20 -11 49 -21 81 -21c34 0 52 15 52 38c0 21 -15 33 -55 47c-55 20 -93 52 -93 102c0 58 49 102 126 102z" />
<glyph glyph-name="ion-social-linkedin-outline" unicode="&#xf238;" horiz-adv-x="384"
d="M119 64v0h-55v171h55v-171zM93 261v0v0c-18 0 -29 13 -29 29c0 17 12 30 30 30s29 -13 29 -30c0 -16 -12 -29 -30 -29zM257 239c36 0 63 -24 63 -75v-100h-55v94c0 22 -8 37 -28 37c-15 0 -24 -10 -28 -20c-2 -4 -2 -9 -2 -14v-97h-55v171h55v-24c8 11 21 28 50 28z
M353 384c18 0 31 -13 31 -30v-321c0 -17 -13 -33 -31 -33h-320c-18 0 -33 16 -33 33v321c0 17 15 30 33 30h320zM350 32c1 0 2 1 2 2v316c0 1 -1 2 -2 2h-316s-2 -1 -2 -2v-315s1 -3 3 -3h315z" />
<glyph glyph-name="ion-social-linkedin" unicode="&#xf239;" horiz-adv-x="384"
d="M353 384c18 0 31 -13 31 -30v-321c0 -17 -13 -33 -31 -33h-320c-18 0 -33 16 -33 33v321c0 17 15 30 33 30h320zM119 64v171h-55v-171h55zM93 261c18 0 30 13 30 29c0 17 -11 30 -29 30s-30 -13 -30 -30c0 -16 11 -29 29 -29v0zM320 64v100c0 51 -27 75 -63 75
c-29 0 -42 -17 -50 -28v24h-55v-171h55v97c0 5 0 10 2 14c4 10 13 20 28 20c20 0 28 -15 28 -37v-94h55z" />
+ <glyph glyph-name="ion-social-markdown" unicode="&#xf4e6;"
+d="M416 352c18 0 32 -14 32 -32v-256c0 -18 -14 -32 -32 -32h-384c-18 0 -32 14 -32 32v256c0 18 14 32 32 32h384zM252 96v0v192h-56l-42 -68l-42 68h-56v-192h56v96l42 -54l42 54v-96h56zM336 96v0l70 96h-42v96h-56v-96h-42z" />
+ <glyph glyph-name="ion-social-nodejs" unicode="&#xf4e7;" horiz-adv-x="384"
+d="M192 -32c-6 0 -12 2 -17 5l-53 32c-8 5 -4 6 -1 7c11 4 14 5 25 12c1 1 3 1 4 0l39 -23c1 -1 4 -1 5 0l156 92c1 1 2 2 2 4v187c0 2 0 4 -2 5l-156 94c-1 1 -3 1 -4 0l-155 -94c-2 -1 -3 -3 -3 -5v-187c0 -2 0 -3 2 -4l40 -24c24 -12 38 1 38 15v183c0 3 2 5 5 5h22
+c3 0 5 -2 5 -5v-183c0 -33 -19 -52 -49 -52c-9 0 -17 1 -37 11l-41 24c-10 6 -17 18 -17 30v190c0 12 7 24 17 30l158 95c10 6 24 6 34 0l158 -95c10 -6 17 -18 17 -30v-190c0 -12 -7 -24 -17 -30l-158 -94c-5 -3 -11 -5 -17 -5v0zM241 96c-65 0 -84 31 -84 59c0 3 1 5 4 5
+h21c2 0 5 -2 5 -4c3 -22 16 -31 54 -31c33 0 47 11 47 29c0 11 -3 18 -55 23c-43 4 -71 15 -71 51c0 33 28 52 73 52c46 0 76 -14 79 -51c0 -1 -1 -2 -2 -3s-2 -2 -3 -2h-20c-2 0 -5 2 -5 4c-4 17 -16 23 -49 23c-36 0 -41 -12 -41 -22c0 -12 5 -16 54 -23s72 -16 72 -51
+c0 -36 -29 -59 -79 -59v0v0z" />
+ <glyph glyph-name="ion-social-octocat" unicode="&#xf4e8;"
+d="M146 161c9 0 16 -4 22 -13s10 -20 10 -32s-4 -22 -10 -31s-14 -13 -22 -13c-9 0 -17 4 -23 13s-9 19 -9 31s3 24 9 32c6 9 14 13 23 13zM303 161c9 0 16 -4 22 -13s9 -20 9 -32s-3 -22 -9 -31s-13 -13 -22 -13s-18 4 -24 13s-9 19 -9 31s3 24 9 32c6 9 15 13 24 13z
+M414 276c24 -27 34 -66 34 -96c0 -24 -1 -46 -6 -65c-6 -19 -13 -35 -21 -47c-9 -12 -19 -23 -32 -32s-24 -17 -34 -21s-22 -8 -36 -10c-13 -2 -24 -4 -31 -4c0 0 -28 -1 -64 -1s-64 1 -64 1c-7 0 -18 2 -31 4c-14 2 -26 6 -36 10s-22 12 -34 21c-13 9 -23 20 -32 32
+c-8 12 -15 28 -21 47c-5 19 -6 41 -6 65c0 31 10 70 34 96c0 0 -2 14 0 39s7 48 16 69c30 -3 67 -20 112 -51c15 4 36 6 62 6c28 0 48 -2 62 -6c20 14 39 24 58 33c19 8 33 13 41 15s13 3 13 3c9 -21 14 -44 16 -69s0 -39 0 -39v0zM348 42c28 13 42 40 42 81
+c0 24 -8 43 -26 59c-9 9 -20 13 -32 15s-31 1 -56 -1s-40 -4 -52 -4s-25 2 -42 3s-30 3 -39 3c-10 0 -20 1 -31 -2s-21 -7 -28 -14c-17 -15 -25 -35 -25 -59c0 -41 13 -68 41 -81c27 -13 69 -18 123 -18h2c54 0 95 5 123 18z" />
<glyph glyph-name="ion-social-pinterest-outline" unicode="&#xf2b0;"
d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136c14 -14 31 -25 48 -34c1 6 2 10 3 16c4 18 29 122 29 122
s-8 15 -8 36c0 33 20 58 44 58c20 0 30 -16 30 -34c0 -20 -13 -51 -20 -79c-6 -24 12 -43 35 -43c42 0 71 54 71 119c0 49 -33 85 -93 85c-68 0 -110 -50 -110 -107c0 -20 6 -33 15 -44c4 -5 5 -6 3 -12c-1 -4 -4 -14 -5 -18c-2 -6 -6 -8 -11 -6c-31 13 -46 48 -46 86
@@ -1699,6 +1969,10 @@ c0 64 54 140 160 140c86 0 142 -63 142 -129c0 -88 -49 -153 -121 -153c-24 0 -47 13
d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224c-22 0 -44 3 -64 9c8 14 18 31 23 48c3 10 16 62 16 62c8 -15 30 -28 54 -28c72 0 121 65 121 153c0 66 -56 129 -142 129c-106 0 -160 -76 -160 -140c0 -39 15 -73 46 -86c5 -2 10 0 12 6c1 4 3 14 4 18
c2 6 1 7 -3 12c-9 11 -15 24 -15 44c0 57 42 107 110 107c60 0 94 -36 94 -85c0 -65 -29 -119 -71 -119c-24 0 -42 19 -36 43c7 28 20 59 20 79c0 18 -10 34 -30 34c-24 0 -43 -25 -43 -58c0 -21 7 -36 7 -36s-25 -104 -29 -122c-4 -17 -5 -35 -4 -51
c-79 35 -134 113 -134 205c0 124 100 224 224 224z" />
+ <glyph glyph-name="ion-social-python" unicode="&#xf4e9;" horiz-adv-x="384"
+d="M129 199c-29 -5 -49 -30 -49 -57v-43v-3h-15c-29 0 -54 29 -62 69c-2 9 -3 17 -3 27v1c0 53 29 95 65 95h127v16h-96v29c0 26 7 40 46 47c13 2 29 4 45 4s39 -1 55 -4c25 -4 46 -22 46 -47v-57v-31c0 -21 -14 -38 -33 -43c-4 -1 -8 -2 -13 -2h-104h3c-4 0 -8 0 -12 -1z
+M140 321c10 0 17 7 17 17s-7 18 -17 18s-18 -8 -18 -18s8 -17 18 -17zM380 225c3 -10 4 -21 4 -33c0 -16 -3 -30 -7 -43c-11 -31 -33 -53 -58 -53h-127v-16h96v-26c0 -26 -23 -40 -46 -47c-35 -10 -68 -9 -97 0c-25 7 -49 22 -49 47v54v33c0 21 14 36 33 41c4 1 8 2 13 2
+h104c3 0 6 1 9 1c27 4 49 28 49 62v38v3h15c28 0 52 -26 61 -63zM244 65c-10 0 -18 -7 -18 -17s8 -18 18 -18s17 8 17 18s-7 17 -17 17z" />
<glyph glyph-name="ion-social-reddit-outline" unicode="&#xf23a;" horiz-adv-x="449"
d="M259 160c0 21 11 31 32 31s32 -10 32 -31s-11 -32 -32 -32s-32 11 -32 32zM127 160c0 21 11 31 32 31s32 -10 32 -31s-11 -32 -32 -32s-32 11 -32 32zM449 197c0 -20 -9 -36 -27 -45c1 -5 1 -9 1 -14c0 -38 -19 -71 -58 -98s-85 -40 -140 -40s-102 13 -141 40
s-58 59 -58 97c0 5 0 10 1 15c-18 9 -27 24 -27 45c0 14 5 25 15 35s21 15 35 15c13 0 24 -4 33 -13c36 25 79 39 129 41h7l29 98l86 -17c8 19 21 28 41 28c12 0 22 -4 31 -13s13 -20 13 -32s-4 -23 -13 -32s-19 -13 -31 -13s-23 4 -32 13s-13 19 -13 31l-69 14l-24 -77
@@ -1716,6 +1990,14 @@ d="M56 112c31 0 56 -25 56 -56s-25 -56 -56 -56s-56 25 -56 56s25 56 56 56zM56 16c2
c-12 28 -30 54 -52 76s-48 40 -76 52c-25 10 -51 16 -77 18v-47c50 -3 92 -22 123 -53s50 -73 53 -123h48zM0 384c212 0 384 -172 384 -384h-80c0 171 -133 304 -304 304v80zM227 228c56 -56 89 -131 93 -212h48c-8 190 -162 344 -352 352v-48c81 -4 155 -36 211 -92z" />
<glyph glyph-name="ion-social-rss" unicode="&#xf23d;" horiz-adv-x="384"
d="M56 112c31 0 56 -25 56 -56s-25 -56 -56 -56s-56 25 -56 56s25 56 56 56zM0 256c140 0 256 -116 256 -256h-80c0 48 -14 94 -48 128s-80 48 -128 48v80zM0 384c212 0 384 -172 384 -384h-80c0 171 -133 304 -304 304v80z" />
+ <glyph glyph-name="ion-social-sass" unicode="&#xf4ea;" horiz-adv-x="512"
+d="M512 119v-8c-1 -9 -7 -17 -15 -22s-12 -4 -13 -3s1 3 4 5c13 8 17 20 10 33c-5 10 -15 16 -26 20c-24 8 -48 7 -72 0c4 -12 7 -23 -2 -34c-10 -12 -23 -19 -39 -22c-7 -2 -14 2 -15 9c-3 19 17 36 30 47c-7 11 -11 24 -14 37c-15 -17 -31 -40 -26 -61
+c3 -14 -1 -27 -14 -36s-30 -14 -46 -11c-4 1 -6 5 -5 8c2 14 25 32 35 43c2 2 3 4 1 7c-6 12 -10 23 -14 36c-13 -29 -30 -80 -57 -98c-9 -6 -17 -4 -21 5c-3 8 -2 20 -1 29c-6 -13 -11 -27 -20 -38c-7 -8 -24 -7 -30 1c-16 21 -13 50 -5 73l-29 -15c7 -16 8 -32 4 -49
+c-5 -19 -17 -35 -35 -46c-19 -12 -64 -24 -77 4c-7 16 -4 30 6 44c17 24 48 37 74 50c-32 23 -80 42 -96 80c-15 35 17 68 43 89c59 48 166 95 244 59c15 -7 36 -24 31 -52c-4 -24 -13 -39 -28 -54c-32 -32 -152 -77 -176 -15c-1 1 -1 4 1 4c2 -1 20 -15 43 -16
+c17 -1 36 3 52 8c33 11 71 33 80 67c4 13 -2 28 -15 34c-49 24 -116 -4 -159 -26c-33 -17 -84 -45 -82 -87c1 -37 56 -60 81 -82c15 7 42 15 52 27c11 13 26 25 44 26c8 0 14 -3 16 -10c2 -6 1 -11 0 -19c5 4 11 4 15 -1c12 -14 -22 -50 -10 -66c14 14 21 42 30 59
+c4 8 17 51 26 53c7 2 18 4 25 0c2 -1 3 -3 2 -5c-7 -19 -7 -33 3 -52c14 20 29 43 34 67c1 2 3 3 5 4c7 2 18 3 25 0c3 -1 3 -2 2 -5c-7 -22 -6 -38 6 -58c31 11 69 15 97 -5c-3 2 -7 5 0 0c5 -4 3 -2 0 0c12 -8 19 -18 21 -32zM113 94v0c1 7 -1 13 -3 20
+c-24 -8 -66 -35 -64 -62c1 -10 8 -13 17 -12s19 7 27 13c14 11 22 24 23 41zM216 166c1 3 -2 5 -5 4c-29 -8 -43 -57 -33 -81c1 -3 4 -3 6 -1c17 16 28 56 32 78zM286 84c8 -3 27 17 26 27c-8 -9 -18 -18 -26 -27zM367 102c11 6 16 19 12 30c-8 -6 -21 -19 -20 -31
+c0 -2 6 0 8 1z" />
<glyph glyph-name="ion-social-skype-outline" unicode="&#xf23e;" horiz-adv-x="384"
d="M106 352c-41 0 -74 -33 -74 -73c0 -13 4 -25 10 -36l6 -11l-2 -12c-2 -10 -3 -20 -3 -30c0 -40 16 -77 44 -105s67 -44 107 -44c9 0 19 1 28 3l11 2l9 -5c11 -6 24 -9 36 -9c41 0 74 33 74 73c0 11 -3 22 -8 32l-5 10l3 11c2 10 3 21 3 32c0 40 -16 77 -44 105
s-67 43 -107 43c-9 0 -18 0 -26 -2l-12 -2l-10 7c-12 7 -26 11 -40 11zM106 384v0c21 0 40 -6 56 -16c10 2 21 2 32 2c101 0 183 -80 183 -180c0 -13 -1 -27 -4 -39c7 -14 11 -29 11 -46c0 -58 -47 -105 -106 -105c-18 0 -35 4 -50 12c-11 -2 -22 -3 -34 -3
@@ -1728,6 +2010,21 @@ d="M373 151c7 -14 11 -29 11 -46c0 -58 -47 -105 -106 -105c-18 0 -35 4 -50 12c-11
M288 104c9 12 12 25 12 40c0 12 -2 23 -7 32s-12 16 -21 22s-19 10 -31 14s-26 7 -41 10c-12 3 -20 5 -25 6s-10 4 -15 6s-7 5 -10 8c-2 3 -4 6 -4 10c0 7 3 13 11 18s19 7 32 7c14 0 25 -2 31 -7s11 -12 16 -20c4 -7 8 -11 11 -14c4 -3 9 -5 16 -5c8 0 13 3 18 8s8 11 8 17
c0 7 -2 14 -6 21s-10 14 -18 20s-18 11 -30 15s-27 5 -43 5c-20 0 -38 -2 -53 -8c-16 -6 -28 -15 -36 -25c-8 -11 -12 -22 -12 -36s3 -26 11 -36s19 -17 32 -23c13 -5 29 -10 48 -14c14 -3 26 -5 34 -8c8 -2 14 -6 19 -11c5 -4 7 -10 7 -17c0 -9 -4 -17 -13 -23
s-22 -9 -37 -9c-11 0 -20 2 -27 5s-11 6 -15 11s-8 12 -11 19s-6 11 -10 15s-10 6 -16 6c-8 0 -14 -2 -19 -7s-8 -10 -8 -17c0 -11 4 -22 12 -33s18 -19 30 -26c17 -9 39 -14 65 -14c22 0 42 3 58 10s29 16 37 28z" />
+ <glyph glyph-name="ion-social-snapchat-outline" unicode="&#xf4eb;" horiz-adv-x="480"
+d="M240 400v0v0c-71 0 -128 -54 -118 -128c2 -15 3 -32 4 -45c0 0 -2 -5 -12 -5c-6 0 -15 2 -28 7c-2 1 -4 1 -6 1c-8 0 -13 -6 -14 -12c0 -5 4 -11 8 -13c14 -7 47 -10 47 -33s-23 -47 -41 -64s-64 -21 -64 -21s0 -21 32 -29s32 -5 33 -13c2 -15 1 -22 11 -22c2 0 4 1 6 1
+c8 1 20 3 32 3c11 0 23 -2 34 -9c23 -15 41 -34 76 -34s53 19 76 34c11 7 24 9 35 9c12 0 23 -2 31 -3c2 0 4 -1 6 -1c10 0 9 7 11 22c1 8 1 5 33 13s32 29 32 29s-46 4 -64 21s-41 41 -41 64s33 26 47 33c4 2 9 8 9 13c-1 6 -6 12 -14 12c-2 0 -5 0 -7 -1
+c-13 -5 -21 -6 -27 -6c-10 0 -13 4 -13 4c1 13 2 30 4 45c10 74 -47 128 -118 128zM240 416v0c41 0 80 -16 105 -45c24 -28 34 -63 29 -101c-1 -11 -2 -22 -3 -31c4 1 10 2 18 5c4 1 8 2 12 2c16 0 29 -12 30 -27c1 -13 -9 -25 -18 -29c-4 -2 -9 -3 -14 -5
+c-7 -2 -14 -5 -19 -8c-4 -3 -5 -4 -5 -5c0 -16 20 -37 36 -52c11 -10 39 -16 54 -17l15 -1v-14c0 -2 0 -11 -6 -21c-5 -8 -16 -19 -38 -24c-6 -1 -11 -3 -15 -4c-2 -1 -5 -1 -7 -1v-1c-1 -7 -1 -13 -4 -18c-2 -5 -9 -12 -22 -12c-2 0 -6 0 -9 1c-2 0 -3 1 -5 1
+c-7 1 -15 2 -23 2c-10 0 -19 -2 -26 -6c-4 -3 -9 -7 -14 -10c-18 -13 -38 -27 -71 -27s-53 14 -71 27c-5 3 -9 7 -14 10c-7 4 -15 6 -25 6c-8 0 -17 -1 -24 -2c-2 0 -3 -1 -5 -1c-3 -1 -7 -1 -9 -1c-13 0 -20 7 -22 12c-3 5 -3 11 -4 18v1c-2 0 -4 0 -6 1c-4 1 -10 3 -16 4
+c-22 5 -33 16 -38 24c-6 10 -6 18 -6 20v15l15 1c16 1 44 7 54 17c29 27 36 43 36 52c0 1 0 2 -4 5c-5 3 -13 6 -20 8c-5 2 -10 3 -14 5c-9 4 -18 16 -17 29c1 15 14 27 30 27c4 0 8 0 12 -2c8 -3 13 -4 17 -5c-1 9 -2 19 -3 30c-5 38 5 74 29 102c25 29 64 45 105 45v0z
+M240 219c-21 0 -41 8 -56 23c-3 3 -3 9 0 12s9 3 12 0c12 -12 27 -19 44 -19c16 0 32 7 44 19c3 3 9 3 12 0s3 -9 0 -12c-15 -15 -35 -23 -56 -23zM176 296c0 16 5 24 16 24s16 -8 16 -24s-5 -24 -16 -24s-16 8 -16 24zM272 296c0 16 5 24 16 24s16 -8 16 -24
+s-5 -24 -16 -24s-16 8 -16 24z" />
+ <glyph glyph-name="ion-social-snapchat" unicode="&#xf4ec;" horiz-adv-x="480"
+d="M480 88c0 -2 0 -11 -6 -21c-5 -8 -16 -19 -38 -24c-6 -1 -11 -3 -15 -4c-2 -1 -5 -1 -7 -1v-1c-1 -7 -1 -13 -4 -18c-2 -5 -9 -12 -22 -12c-2 0 -6 0 -9 1c-2 0 -3 1 -5 1c-7 1 -15 2 -23 2c-10 0 -19 -2 -26 -6c-4 -3 -9 -7 -14 -10c-18 -13 -38 -27 -71 -27
+s-53 14 -71 27c-5 3 -9 7 -14 10c-7 4 -15 6 -25 6c-8 0 -17 -1 -24 -2c-2 0 -3 -1 -5 -1c-3 -1 -7 -1 -9 -1c-13 0 -20 7 -22 12c-3 5 -3 11 -4 18v1c-2 0 -4 0 -6 1c-4 1 -10 3 -16 4c-22 5 -33 16 -38 24c-6 10 -6 18 -6 20v15l15 1c16 1 44 7 54 17c29 27 36 43 36 52
+c0 1 0 2 -4 5c-5 3 -13 6 -20 8c-5 2 -10 3 -14 5c-9 4 -18 16 -17 29c1 15 14 27 30 27c4 0 8 0 12 -2c8 -3 13 -4 17 -5c-1 9 -2 19 -3 30c-5 38 5 74 29 102c25 29 64 45 105 45v0c41 0 80 -16 105 -45c24 -28 34 -63 29 -101c-1 -11 -2 -22 -3 -31c4 1 10 2 18 5
+c4 1 8 2 12 2c16 0 29 -12 30 -27c1 -13 -9 -25 -18 -29c-4 -2 -9 -3 -14 -5c-7 -2 -14 -5 -19 -8c-4 -3 -5 -4 -5 -5c0 -16 20 -37 36 -52c11 -10 39 -16 54 -17l15 -1v-14zM192 320c-9 0 -16 -11 -16 -24s7 -24 16 -24s16 11 16 24s-7 24 -16 24zM296 242c3 3 3 9 0 12
+s-9 3 -12 0c-12 -12 -28 -19 -44 -19c-17 0 -32 7 -44 19c-3 3 -9 3 -12 0s-3 -9 0 -12c15 -15 35 -23 56 -23s41 8 56 23zM288 272c9 0 16 11 16 24s-7 24 -16 24s-16 -11 -16 -24s7 -24 16 -24z" />
<glyph glyph-name="ion-social-tumblr-outline" unicode="&#xf240;" horiz-adv-x="256"
d="M193 52c21 0 42 6 63 20v-65c-18 -8 -34 -15 -48 -18s-28 -5 -45 -5c-19 0 -35 2 -50 7c-14 5 -28 12 -38 21s-17 18 -21 28s-6 25 -6 44v140h-48v58c16 5 30 14 42 24s19 21 26 35s11 37 14 59h62v-112h96v-64h-96v-101c0 -24 1 -40 4 -47c2 -7 7 -12 14 -16
c9 -6 19 -8 31 -8zM240 17v29c-15 -6 -31 -10 -47 -10c-15 0 -28 3 -40 10c-10 6 -17 15 -21 25c-2 6 -4 17 -4 52v117h96v32h-96v112h-32c-2 -16 -7 -36 -14 -50c-8 -16 -17 -29 -30 -40c-11 -9 -23 -17 -36 -23v-31h48v-156c0 -21 2 -32 4 -38c3 -8 10 -15 18 -22
@@ -1735,17 +2032,21 @@ c9 -8 19 -14 31 -18c13 -4 29 -6 46 -6c16 0 28 2 41 5c11 2 23 6 36 12z" />
<glyph glyph-name="ion-social-tumblr" unicode="&#xf241;" horiz-adv-x="256"
d="M193 52c21 0 42 6 63 20v-65c-18 -8 -34 -15 -48 -18s-28 -5 -45 -5c-19 0 -35 2 -50 7c-14 5 -28 12 -38 21s-17 18 -21 28s-6 25 -6 44v140h-48v58c16 5 30 14 42 24s19 21 26 35s11 37 14 59h62v-112h96v-64h-96v-101c0 -24 1 -40 4 -47c2 -7 7 -12 14 -16
c9 -6 19 -8 31 -8z" />
- <glyph glyph-name="ion-social-tux" unicode="&#xf2c5;" horiz-adv-x="384"
-d="M191 347c2 2 3 4 5 5c-3 -2 -5 -4 -7 -8c0 1 1 2 2 3zM362 52c7 -4 22 -10 22 -20s-16 -16 -42 -30s-33 -34 -61 -34s-26 17 -37 20s-35 3 -48 3s-33 -1 -42 -4s-23 -19 -38 -19s-26 9 -56 16s-60 7 -60 23s11 17 7 31s-7 25 -4 30s10 4 19 5s19 2 22 11c1 5 -2 17 5 25
-c-4 16 -2 27 10 44c17 23 14 38 23 53s32 36 37 45c9 16 9 22 8 55s-2 50 -2 50c0 33 20 60 58 60h14c38 0 64 -32 65 -69c0 -19 -6 -38 4 -67c0 0 12 -20 22 -33s37 -43 45 -68s13 -56 12 -66c-1 -6 -1 -9 -3 -11c3 -1 6 -2 8 -5c3 -4 2 -11 0 -26c-1 -8 5 -15 12 -19z
-M138 -3c1 13 -4 21 -17 43s-32 58 -46 65c0 0 -4 2 -8 2s-12 3 -15 -7c-2 -7 0 -19 -2 -22c-2 -4 -9 -9 -14 -10s-22 -1 -25 -5s1 -12 5 -24s-6 -18 -7 -23s-2 -12 7 -15s33 -7 46 -9c15 -3 38 -14 51 -15c12 -1 24 7 25 20zM254 62c-2 10 -5 28 1 35c4 5 10 6 17 5
-c0 4 1 9 3 12c1 2 3 3 7 5s7 3 12 3c20 -1 24 -12 20 -6c-3 4 -9 9 -14 10c0 0 4 12 2 34c-4 40 -33 62 -33 62c27 -30 28 -58 28 -72c0 -6 -2 -18 -5 -24c-4 -1 -7 -2 -11 -4c-10 -5 -8 2 -8 10c0 10 2 20 -5 49c-5 22 -17 28 -18 33s-1 14 -9 30s-18 18 -15 34s5 22 -8 25
-s-23 8 -24 13v10c0 2 1 5 2 7l3 3c2 2 5 4 9 4c8 0 14 -6 14 -14c0 -3 -1 -7 -3 -10s-2 -3 -3 -4c-2 -2 3 -4 7 -4c3 0 5 1 7 10c1 3 1 8 1 13v0c0 14 -11 25 -23 25c-4 0 -8 -2 -12 -4c-2 -1 -4 -4 -6 -6c-1 -1 -1 -2 -1 -3h-1c-2 -4 -2 -8 -2 -12c0 -5 -1 -9 0 -13
-c0 -2 1 -3 0 -3c-2 0 -6 5 -10 5c-6 0 -10 -2 -10 -2s1 15 -3 23c-4 9 -18 16 -24 4s-2 -25 1 -31l3 -6c2 1 5 4 5 4s-6 3 -7 11c-1 9 3 14 7 15s10 -2 12 -8s1 -13 1 -13s-9 -8 -13 -11s-12 -8 -12 -11s0 -5 2 -7c3 -4 9 -8 13 -10s7 -4 15 -4s14 3 29 8c22 7 19 12 23 12
-s6 -3 4 -6s-6 -2 -22 -9s-22 -9 -28 -10s-12 -5 -27 9c-1 1 10 -17 17 -20s20 2 30 7s15 10 21 11s9 -2 5 -5s-16 -8 -23 -13s-19 -15 -27 -16s-21 16 -25 22c-5 8 -7 11 -5 -12c0 0 -6 -8 -10 -15s-6 -13 -7 -19c-1 -5 -1 -10 -1 -12s-12 -14 -18 -41s2 -58 -8 -55
-c-6 2 -16 14 -16 27s1 17 2 20c1 4 -4 -8 -4 -21s2 -17 7 -23c3 -4 45 -32 56 -42s10 -20 7 -27s-10 -11 -10 -11s5 -10 9 -19s2 -22 2 -22s4 1 4 9s-4 16 -5 19c0 0 17 -12 38 -10c25 2 41 12 54 22c18 13 13 23 15 4c2 -17 -12 -27 -10 -34c4 8 11 12 13 24s0 26 -2 36z
-M157 323c0 -1 -1 -2 -1 -3v0c2 0 3 5 2 8c-1 4 -3 6 -4 6h-2c3 -2 5 -6 5 -11zM211 335c3 -2 6 -5 6 -10v-3v0c2 0 3 4 2 7s-3 6 -5 6h-3zM348 15c24 11 36 17 21 26c-17 10 -27 13 -27 29c0 5 4 16 2 22c-1 4 -6 5 -9 5l-1 -1c-7 -6 -13 -24 -33 -24s-27 19 -28 24
-c-4 2 -9 1 -12 -4c-4 -7 -3 -12 1 -36c6 -31 -5 -54 1 -64s18 -18 33 -10s28 23 52 33z" />
+ <glyph glyph-name="ion-social-tux" unicode="&#xf2c5;" horiz-adv-x="383"
+d="M189 347c2 2 -1 -1 0 0c2 2 4 4 6 5c-3 -2 -5 -4 -7 -8c0 1 0 2 1 3zM361 52c7 -4 23 -11 21 -22c-2 -10 -17 -15 -24 -19c-15 -8 -28 -14 -41 -25c-9 -8 -17 -15 -29 -17c-11 -2 -25 -1 -33 8c-5 5 -7 11 -15 12c-25 5 -54 4 -79 0c-13 -2 -21 -11 -32 -17
+c-10 -5 -20 -5 -30 -1c-13 5 -27 10 -41 13s-29 5 -43 9c-31 8 -5 30 -11 50c-3 12 -10 29 8 30c9 1 27 -1 31 11c2 7 -2 15 2 22s-1 17 1 25c4 18 19 32 25 49c5 14 8 25 18 37c9 11 22 22 29 34c10 18 9 35 8 55c-1 17 -1 33 -2 50c0 33 20 60 58 60h14
+c38 0 63 -32 64 -69c0 -19 -5 -38 5 -67c15 -27 36 -48 52 -73c10 -16 16 -31 20 -49c3 -14 9 -31 7 -45c-1 -6 -2 -9 -4 -11c3 -1 7 -2 9 -5c3 -4 2 -11 0 -26c-1 -8 5 -15 12 -19zM137 -3c2 20 -15 39 -25 56c-10 16 -21 43 -39 52c-8 4 -19 5 -23 -5c-2 -7 0 -19 -2 -22
+c-4 -9 -14 -10 -23 -11c-6 0 -17 0 -17 -8c1 -10 10 -20 7 -30c-2 -7 -8 -12 -8 -19c0 -14 38 -15 47 -17c19 -4 37 -14 57 -16c12 -1 25 7 26 20zM253 62c-2 10 2 -10 0 0s-5 28 1 35c4 5 10 6 17 5c0 4 1 9 3 12c8 13 29 8 39 0l-1 2c-3 4 -8 9 -13 10c0 0 4 12 2 34
+c-4 40 -33 62 -33 62c27 -30 27 -58 27 -72c0 -6 -1 -18 -4 -24c-4 -1 -7 -2 -11 -4c-10 -5 -8 2 -8 10c0 18 -2 36 -7 54c-3 9 -7 17 -13 24c-4 5 -4 9 -5 15c-3 12 -9 22 -16 32c-7 9 -7 17 -5 28c1 7 2 14 -6 17c-6 2 -26 5 -27 14c-1 6 -1 16 5 20c16 14 30 -11 17 -24
+c-3 -3 7 -4 8 -4c4 1 4 7 5 10c1 4 1 9 1 13c0 17 -18 32 -34 21c-6 -4 -9 -11 -10 -17c0 -2 -1 -20 0 -20c-4 0 -7 5 -11 5c-3 0 -7 0 -10 -1c0 0 2 14 -2 22c-4 9 -18 16 -24 4s-3 -25 0 -31s4 -6 4 -6c2 1 5 4 5 4s-6 3 -7 11c-1 9 3 14 7 15s10 -2 12 -8s0 -13 0 -13
+c-7 -6 -30 -18 -22 -28c14 -18 33 -15 52 -9c8 3 18 5 24 12c3 3 11 2 8 -4c-2 -5 -18 -7 -22 -9c-9 -4 -18 -8 -28 -10c-6 -1 -13 -5 -28 9c7 -6 8 -16 17 -20c13 -6 33 9 44 15c1 1 16 5 14 0c-1 -4 -11 -7 -15 -9c-11 -6 -23 -21 -36 -22c-8 -1 -21 16 -25 22
+c-1 1 -5 9 -6 4c-1 -8 2 -14 -3 -21c-6 -9 -11 -18 -13 -29c-1 -6 0 -11 -3 -16c-11 -15 -17 -33 -19 -51c0 -4 3 -43 -5 -41c-18 5 -17 33 -14 47c-3 -12 -8 -30 2 -44c12 -15 99 -55 53 -80c7 -14 14 -25 12 -41c8 7 2 20 -1 28c0 0 17 -12 38 -10c17 2 32 7 46 16
+c6 4 11 9 16 14c1 2 4 6 6 7l1 -11c2 -17 -12 -27 -10 -34c4 8 11 14 13 24c3 12 0 24 -2 36zM155 323v0v-3c2 0 2 5 1 8c-1 4 -3 6 -4 6h-2c3 -2 5 -6 5 -11zM210 335c3 -2 0 0 0 0c3 -2 5 -5 5 -10v-3c2 0 3 4 2 7s-3 6 -5 6h-2zM347 15c24 11 -24 -10 0 0
+c24 11 35 17 20 26c-17 10 -26 13 -26 29c0 5 4 16 2 22c-1 4 -6 5 -9 5c-10 -10 -17 -25 -34 -25c-14 0 -25 11 -28 24c-4 2 -10 1 -13 -4c-6 -12 1 -29 3 -41c2 -18 -4 -35 -2 -53c2 -21 26 -22 40 -13c16 10 29 22 47 30z" />
+ <glyph glyph-name="ion-social-twitch-outline" unicode="&#xf4ed;" horiz-adv-x="416"
+d="M32 416h384v-272l-112 -112h-80l-64 -64h-64v64h-96v304zM368 160v208h-304v-272h80v-64l64 64h96zM272 176v129h48v-129h-48zM160 176v129h48v-129h-48z" />
+ <glyph glyph-name="ion-social-twitch" unicode="&#xf4ee;" horiz-adv-x="416"
+d="M32 416h384v-272l-112 -112h-80l-64 -64h-64v64h-96v304zM208 176v129h-48v-129h48zM320 176v129h-48v-129h48z" />
<glyph glyph-name="ion-social-twitter-outline" unicode="&#xf242;" horiz-adv-x="472"
d="M472 338c-13 -20 -29 -36 -48 -50v-12c0 -128 -98 -276 -276 -276c-55 0 -105 16 -148 44c8 -1 15 -2 23 -2c45 0 87 16 120 42c-42 1 -78 29 -90 67c6 -1 12 -2 18 -2c9 0 18 2 26 4c-44 9 -78 48 -78 95v1c13 -7 28 -12 44 -12c-26 17 -43 47 -43 81c0 18 5 34 13 48
c48 -59 119 -97 199 -101c-2 7 -2 14 -2 22c0 54 43 97 97 97c28 0 52 -12 70 -31c22 4 43 13 62 24c-7 -23 -23 -42 -43 -54c20 2 39 7 56 15zM414 301c3 2 8 6 11 8c-2 0 -11 -2 -19 -1s-21 5 -21 5s14 13 18 17l11 11c-4 -1 -10 -2 -14 -3l-8 -2l-6 6
@@ -1778,6 +2079,13 @@ c6 3 12 5 18 5c7 0 13 -3 18 -7c8 -7 13 -12 16 -18c6 -11 12 -24 16 -37c13 -44 26
d="M445 334c7 -33 1 -66 -13 -97s-31 -59 -51 -87c-26 -36 -52 -71 -85 -101c-19 -18 -41 -35 -66 -44c-31 -11 -52 -5 -71 22c-14 19 -22 40 -28 63c-12 45 -25 90 -38 134c-4 12 -9 22 -15 33c-3 5 -8 10 -12 14c-5 4 -11 3 -17 0c-10 -6 -28 -18 -28 -18l-21 27
c26 24 82 71 82 71c11 9 33 25 48 27c21 3 38 -4 50 -22c11 -17 15 -37 18 -57c7 -41 11 -82 23 -122c3 -10 8 -20 13 -29c7 -11 15 -13 25 -5c4 3 7 6 10 10c20 24 37 52 48 81c3 9 3 17 3 27c0 13 -10 25 -25 26s-24 -1 -39 -7c6 24 24 62 54 84c29 21 71 24 94 16
s36 -23 41 -46z" />
+ <glyph glyph-name="ion-social-whatsapp-outline" unicode="&#xf4ef;"
+d="M178 294c4 -11 15 -39 16 -42s2 -6 0 -10s-3 -6 -6 -9s-6 -7 -9 -9c-3 -3 -6 -6 -3 -12s14 -24 30 -39c21 -20 38 -27 44 -30s9 -3 12 1s15 16 19 21s8 5 13 3s31 -17 37 -20s10 -5 11 -7s0 -13 -5 -26s-28 -24 -38 -25s-11 -8 -67 16s-90 84 -93 88s-22 31 -21 58
+s17 41 22 46s11 7 15 7h10s9 0 13 -11zM228 384c-50 0 -97 -20 -133 -55c-35 -35 -55 -81 -55 -131c0 -34 9 -67 27 -96l8 -13l-5 -14l-19 -57l61 19l13 4l12 -6c28 -15 59 -23 91 -23c50 0 97 19 133 54c35 35 55 82 55 132s-20 96 -55 131c-36 35 -83 55 -133 55zM228 416
+v0c121 0 220 -97 220 -218s-99 -218 -220 -218c-39 0 -74 10 -106 27l-122 -39l40 117c-20 33 -32 72 -32 113c0 121 99 218 220 218z" />
+ <glyph glyph-name="ion-social-whatsapp" unicode="&#xf4f0;"
+d="M228 416c121 0 220 -97 220 -218s-99 -218 -220 -218c-39 0 -74 10 -106 27l-122 -39l40 117c-20 33 -32 72 -32 113c0 121 99 218 220 218zM337 115c5 13 6 24 5 26s-5 4 -11 7s-32 18 -37 20s-9 2 -13 -3s-16 -17 -19 -21s-6 -4 -12 -1s-23 10 -44 30
+c-16 15 -27 33 -30 39s0 9 3 12c3 2 6 6 9 9s4 5 6 9s1 7 0 10s-12 31 -16 42s-10 11 -13 11h-10s-10 -2 -15 -7s-21 -19 -22 -46s18 -54 21 -58s37 -64 93 -88s57 -17 67 -16s33 12 38 25z" />
<glyph glyph-name="ion-social-windows-outline" unicode="&#xf246;"
d="M432 167h-216v-149l216 -32v181zM448 183v0v-215l-248 36v179h248zM168 167h-152v-120l152 -22v142zM184 183v0v-177l-184 27v150h184zM432 398v0l-216 -31v-152h216v183zM448 416v0v-217h-248v182zM168 360v0l-152 -22v-123h152v145zM184 378v0v-179h-184v153z" />
<glyph glyph-name="ion-social-windows" unicode="&#xf247;"
@@ -1796,6 +2104,11 @@ d="M289 380c11 0 21 1 31 4l-128 -213v-171c-10 4 -21 4 -32 4s-22 0 -32 -4v171l-12
v-5v-151c6 1 11 0 16 0s11 1 16 0v151v5z" />
<glyph glyph-name="ion-social-yahoo" unicode="&#xf24b;" horiz-adv-x="320"
d="M289 380c11 0 21 1 31 4l-128 -213v-171c-10 4 -21 4 -32 4s-22 0 -32 -4v171l-128 213c10 -4 21 -4 32 -4s22 0 32 4l96 -160l96 160c10 -4 22 -4 33 -4z" />
+ <glyph glyph-name="ion-social-yen-outline" unicode="&#xf4f1;" horiz-adv-x="384"
+d="M384 416l-112 -208h48v-48h-73l-15 -31v-17h88v-48h-88v-96h-80v96h-88v48h88v17l-14 31h-74v48h48l-112 208h80l112 -221l112 221h80zM304 192h-59l13 24l99 184v0h-43l-122 -240l-122 240h-43l99 -184l13 -24h-59v-16h68l20 -44v-36h-88v-16h88v-96h48v96h88v16h-88v37
+l21 43h67v16z" />
+ <glyph glyph-name="ion-social-yen" unicode="&#xf4f2;" horiz-adv-x="384"
+d="M384 416l-112 -208h48v-48h-73l-15 -31v-17h88v-48h-88v-96h-80v96h-88v48h88v17l-14 31h-74v48h48l-112 208h80l112 -221l112 221h80z" />
<glyph glyph-name="ion-social-youtube-outline" unicode="&#xf24c;" horiz-adv-x="512"
d="M265 352v0h-9h-9c-65 0 -118 -2 -168 -4h-1h-1c-23 0 -42 -22 -42 -49v-1v-1c-2 -34 -3 -70 -3 -105v0v0c0 -35 1 -70 3 -104v-2v-1c0 -14 5 -26 14 -36c8 -9 17 -13 28 -13h1h1c52 -2 108 -4 166 -4h11v0v0h11c58 0 113 2 166 4h1h1c11 0 20 4 28 13c9 10 14 22 14 36v1
v2c2 34 3 68 3 104v0v0c0 36 -1 71 -3 105v1v2c0 27 -19 49 -42 49h-1h-1c-49 2 -103 3 -168 3zM265 384v0c58 0 115 0 170 -3c41 0 74 -36 74 -81c2 -36 3 -72 3 -108s-1 -71 -3 -107c0 -45 -33 -81 -74 -81c-55 -3 -111 -4 -168 -4h-11h-11c-57 0 -113 1 -168 4
@@ -1803,6 +2116,16 @@ c-41 0 -74 36 -74 81c-2 36 -3 71 -3 107s2 71 4 107c0 45 32 82 73 82c55 2 112 3 1
<glyph glyph-name="ion-social-youtube" unicode="&#xf24d;" horiz-adv-x="512"
d="M509 299c2 -36 3 -71 3 -107s-1 -71 -3 -107c0 -45 -33 -81 -74 -81c-58 -3 -118 -4 -179 -4s-121 1 -179 4c-41 0 -74 36 -74 81c-2 36 -3 71 -3 107s2 71 4 107c0 45 32 81 73 81c55 3 112 4 170 4h9h9c58 0 115 -1 170 -4c41 0 74 -36 74 -81zM207 94l145 98l-145 99
v-197z" />
+ <glyph glyph-name="ion-soup-can-outline" unicode="&#xf4f3;" horiz-adv-x="320"
+d="M160 304c-88 0 -160 29 -160 64s72 64 160 64s160 -29 160 -64s-72 -64 -160 -64zM160 415c-70 0 -126 -19 -126 -43s56 -43 126 -43s126 19 126 43s-56 43 -126 43zM161 288c88 0 158 29 159 64c0 -5 0 -33 -8 -40v-240c0 -35 -64 -64 -152 -64s-152 29 -152 64v240
+c-8 6 -8 40 -8 40c0 -35 73 -64 161 -64zM280 72v80c-18 -10 -43 -17 -72 -21h-2c-6 -20 -24 -35 -46 -35s-40 15 -46 35h-2c-29 4 -54 11 -72 21v-80c1 -2 9 -10 30 -18c24 -9 55 -14 90 -14s67 5 91 14c21 8 29 16 29 18zM280 184v91c-33 -12 -75 -19 -119 -19
+c-45 0 -87 7 -121 19v-91c18 -10 43 -17 73 -21h3c7 17 24 29 44 29s37 -12 44 -29h3c30 4 55 11 73 21zM178 -16zM160 -16h1h-1v0zM312 32l8 -16c0 -7 -3 -14 -8 -20c-21 -26 -81 -44 -152 -44s-131 18 -152 44c-5 6 -8 13 -8 20l8 16v16c0 -35 63 -64 152 -64
+s152 28 152 64v-16z" />
+ <glyph glyph-name="ion-soup-can" unicode="&#xf4f4;" horiz-adv-x="320"
+d="M0 368c0 43 53 64 160 64s160 -21 160 -64s-53 -64 -160 -64s-160 21 -160 64zM160 8c-44 0 -80 6 -109 18s-43 28 -43 46v128c0 -9 4 -19 13 -27s21 -15 37 -21s33 -10 54 -13c1 -12 7 -23 16 -31s20 -12 32 -12s23 4 32 12s15 19 16 31c31 4 56 12 75 23s29 24 29 38
+v-128c0 -18 -14 -34 -43 -46s-65 -18 -109 -18zM160 288c44 0 82 6 113 18s47 28 47 46v-8c0 -5 -1 -11 -2 -18s-3 -11 -6 -14v-96c0 -14 -10 -27 -29 -38s-44 -19 -76 -23c-2 11 -8 19 -17 26s-19 11 -30 11s-21 -4 -30 -11s-15 -15 -17 -26c-32 4 -57 12 -76 23
+s-29 24 -29 38v96c-5 5 -8 18 -8 40c0 -18 16 -34 47 -46s69 -18 113 -18zM312 56v-24l8 -16c0 -7 -3 -14 -8 -20c-11 -13 -30 -24 -58 -32s-59 -12 -94 -12s-66 4 -94 12s-47 19 -58 32c-5 6 -8 13 -8 20l8 16v24c0 -18 14 -34 43 -46s65 -18 109 -18s80 6 109 18
+s43 28 43 46z" />
<glyph glyph-name="ion-speakerphone" unicode="&#xf2b2;"
d="M39 266c0 -37 20 -69 50 -86c-1 0 -2 1 -3 1s-4 1 -5 1v0c-35 3 -62 33 -69 69c-6 0 -12 7 -12 16c0 8 5 15 11 16c6 42 40 75 81 75h8c-36 -15 -61 -51 -61 -92zM433 357c10 -25 15 -56 15 -88s-5 -63 -15 -88l-3 -9c-6 -14 -15 -26 -24 -34c-10 -10 -22 -19 -34 -20h-3
c-7 0 -15 2 -22 5c-3 2 -10 5 -10 5c-22 10 -84 28 -115 29c-4 -8 -10 -20 -12 -30c-2 -9 -6 -27 -7 -61c-1 -32 1 -59 3 -82c0 -2 1 -5 1 -7c0 -6 -2 -9 -9 -9h-77c-6 0 -9 3 -9 6v7c2 72 25 140 26 145c2 9 5 17 7 30c2 12 -27 13 -40 24c-29 17 -47 49 -47 86
@@ -1813,8 +2136,8 @@ d="M312 192l8 -8l-64 -84v-4c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32h4zM2
l16 27c-25 13 -52 21 -81 22v-32h-16v32c-29 -1 -56 -9 -81 -22l16 -27l-14 -8l-16 27c-12 -8 -23 -16 -33 -26s-19 -21 -26 -33l28 -16l-8 -13l-28 15c-13 -25 -21 -52 -22 -81h32v-16h-32c1 -31 11 -61 26 -88h-36c-14 29 -22 62 -22 96c0 124 100 224 224 224z" />
<glyph glyph-name="ion-spoon" unicode="&#xf2b4;" horiz-adv-x="128"
d="M128 288c0 64 -26 128 -64 128s-64 -64 -64 -128v0c1 -25 16 -54 37 -64l1 -1v0c3 -2 10 -6 10 -10c0 0 -16 -199 -16 -210s4 -20 10 -26s14 -9 22 -9v0v0c8 0 16 3 22 9s10 13 10 26s-16 210 -16 210c0 4 7 8 10 10l1 1c22 10 37 38 37 64z" />
- <glyph glyph-name="ion-star" unicode="&#xf24e;" horiz-adv-x="384"
-d="M384 240l-119 -89l47 -151l-120 96l-120 -96l47 151l-119 89h147l45 144l45 -144h147z" />
+ <glyph glyph-name="ion-star" unicode="&#xf24e;"
+d="M448 248l-139 -104l55 -176l-140 112l-140 -112l55 176l-139 104h172l52 168l53 -168h171z" />
<glyph glyph-name="ion-stats-bars" unicode="&#xf2b5;" horiz-adv-x="352"
d="M96 32v320h64v-320h-64zM0 32v96h64v-96h-64zM192 32v160h64v-160h-64zM288 32v224h64v-224h-64z" />
<glyph glyph-name="ion-steam" unicode="&#xf30b;" horiz-adv-x="512"
@@ -1836,6 +2159,9 @@ d="M320 240c26 0 48 -22 48 -48s-22 -48 -48 -48s-48 22 -48 48s22 48 48 48zM320 32
<glyph glyph-name="ion-toggle" unicode="&#xf355;"
d="M320 288h-192c-53 0 -96 -43 -96 -96s43 -96 96 -96h192c53 0 96 43 96 96s-43 96 -96 96zM320 320v0c71 0 128 -57 128 -128s-57 -128 -128 -128h-192c-71 0 -128 57 -128 128s57 128 128 128h192zM128 240c-26 0 -48 -22 -48 -48s22 -48 48 -48s48 22 48 48
s-22 48 -48 48zM128 272v0c44 0 80 -36 80 -80s-36 -80 -80 -80s-80 36 -80 80s36 80 80 80z" />
+ <glyph glyph-name="ion-transgender" unicode="&#xf4f5;" horiz-adv-x="512"
+d="M368 448h144v-144h-40v76l-101 -100c8 -17 13 -36 13 -56c0 -63 -46 -115 -104 -126v-52h72v-46h-72v-64h-48v64h-72v46h72v52c-59 11 -104 63 -104 126c0 20 5 39 13 56l-22 22l-36 -36l-33 33l36 36l-46 45v-76h-40v144h144v-40h-70l43 -42l36 36l33 -33l-36 -36
+l17 -17c23 22 54 36 89 36c27 0 53 -8 74 -23c0 0 6 -5 15 -13l93 92h-70v40zM256 144c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80z" />
<glyph glyph-name="ion-trash-a" unicode="&#xf252;" horiz-adv-x="352"
d="M261 320v0h91v-32h-9s-5 -1 -8 -4s-4 -9 -4 -9l-19 -241c-2 -29 -2 -34 -36 -34h-200c-34 0 -34 5 -36 34l-19 242s-1 6 -4 9s-8 3 -8 3h-9v32h91v29c0 19 14 35 34 35h101c20 0 35 -16 35 -35v-29zM112 349v-29h128v29c0 10 -9 15 -19 15h-91c-10 0 -18 -5 -18 -15z
M104 64h20l-10 192h-21zM187 64v192h-22v-192h22zM249 64l10 192h-20l-11 -192h21z" />
@@ -1845,11 +2171,16 @@ h-208c-15 0 -15 3 -17 15l-19 242c-1 12 0 15 17 15h246z" />
<glyph glyph-name="ion-trophy" unicode="&#xf356;"
d="M448 345c0 -25 2 -73 -22 -122c-15 -30 -36 -55 -63 -75c-23 -16 -49 -28 -77 -35c-16 -17 -32 -27 -46 -31v-33s0 -49 99 -49h13v-32h-256v32h13c85 0 97 35 99 46v36c-14 4 -30 14 -46 31c-28 7 -55 19 -77 35c-27 20 -48 45 -63 75c-17 36 -21 71 -22 97v0v11v0v21v0
h80c-2 35 0 64 0 64h143h1h1h142s2 -29 0 -64h81v-7zM51 237c17 -34 43 -61 77 -78c-22 40 -33 84 -42 135c-1 8 -2 17 -3 26h-51c1 -23 5 -53 19 -83zM397 237c14 30 18 60 19 83h-51c-1 -9 -3 -18 -4 -26c-9 -51 -20 -95 -42 -135c34 17 61 43 78 78z" />
+ <glyph glyph-name="ion-tshirt-outline" unicode="&#xf4f6;"
+d="M146 362l-104 -31l11 -32l39 4l38 5l-2 -38l-14 -255h220l-14 255l-2 38l38 -5l39 -4l11 32l-104 31c-6 -8 -13 -14 -21 -19c-15 -10 -34 -15 -57 -15v0v0c-34 1 -59 11 -78 34zM288 400v0l160 -48l-32 -88l-64 8l16 -289h-288l16 289l-64 -8l-32 88l160 48
+c14 -27 31 -39 64 -40c33 0 50 13 64 40z" />
+ <glyph glyph-name="ion-tshirt" unicode="&#xf4f7;"
+d="M448 352l-32 -88l-64 8l16 -288h-288l16 288l-64 -8l-32 88l160 48c14 -27 31 -39 64 -40c33 0 50 13 64 40z" />
<glyph glyph-name="ion-umbrella" unicode="&#xf2b7;"
d="M344 160v0v0v0zM104 160v0v0v0zM240 399c116 -8 208 -109 208 -227v-12c-4 25 -26 52 -52 52c-29 0 -52 -23 -52 -52v0c0 29 -23 52 -52 52s-49 -12 -52 -45v-135c0 -17 -6 -33 -18 -45s-29 -19 -46 -19c-35 0 -63 29 -63 64c0 9 7 16 16 16s16 -7 16 -16
c0 -18 14 -32 31 -32c18 0 32 14 32 32v134c-1 24 -26 46 -52 46c-29 0 -52 -23 -52 -52v0c0 29 -23 52 -52 52c-27 0 -49 -26 -52 -52v18c0 118 92 213 208 221v1c0 9 7 16 16 16s16 -7 16 -16v-1z" />
<glyph glyph-name="ion-university" unicode="&#xf357;"
-d="M224 384l224 -111l-92 -60l-132 -85l-160 102v-198l-32 16v203l-32 21zM358 192l10 -82l-6 -3c-1 -1 -93 -54 -131 -99l-7 -8l-7 8c-38 45 -130 98 -131 99l-6 3l9 82l135 -88z" />
+d="M224 384l224 -111l-92 -60l-132 -85l-160 102v-198l-32 16v203l-32 21zM358 192l10 -82c-16 -12 -112 -78 -144 -110c-32 32 -128 98 -144 110l9 82l135 -88z" />
<glyph glyph-name="ion-unlocked" unicode="&#xf254;" horiz-adv-x="384"
d="M22 -32c-12 0 -22 10 -22 22v212c0 12 10 22 22 22h3h19v31c0 42 17 87 43 115s64 46 105 46v0v0c41 0 79 -18 105 -46c20 -21 33 -51 39 -82h-53c-5 18 -13 35 -24 47v0v1c-18 19 -42 29 -67 29v0v0c-25 0 -49 -10 -67 -29v-1v0c-18 -19 -28 -53 -28 -80v-31h265
c12 0 22 -10 22 -22v-212c0 -12 -10 -22 -22 -22h-340z" />
diff --git a/public/assets/fonts/ionicons.ttf b/public/assets/fonts/ionicons.ttf
index cc67b2f..c4e4632 100755
--- a/public/assets/fonts/ionicons.ttf
+++ b/public/assets/fonts/ionicons.ttf
Binary files differ
diff --git a/public/assets/fonts/ionicons.woff b/public/assets/fonts/ionicons.woff
index 1d7b977..5f3a14e 100755
--- a/public/assets/fonts/ionicons.woff
+++ b/public/assets/fonts/ionicons.woff
Binary files differ
diff --git a/public/assets/javascripts/app.js b/public/assets/javascripts/app.js
index a146325..3cafeca 100644
--- a/public/assets/javascripts/app.js
+++ b/public/assets/javascripts/app.js
@@ -21,44 +21,12 @@ app.init = function () {
app.launch = function () {
if ($.browser.msie || ! has3d()) { return app.fallback() }
- var movements
-
- app.devicePixelRatio = is_mobile ? devicePixelRatio : 1
-
- scene = new MX.Scene().addTo('#scene')
- scene.width = window.innerWidth
- scene.height = window.innerHeight
- scene.perspective = window.innerHeight
-
- window.onresize = function () {
- scene.width = window.innerWidth
- scene.height = window.innerHeight
- scene.perspective = window.innerHeight
- scene.update()
- }
-
- cam = scene.camera
- cam.y = viewHeight
-
- if (MX.Map) map = app.map = new MX.Map()
-
- if (is_mobile) {
- app.movements = new MX.MobileMovements(cam, viewHeight)
- }
- else {
- app.movements = new MX.Movements(cam, viewHeight)
- }
- app.movements.init()
-
var last_t = 0
function animate (t) {
var dt = t - last_t
last_t = t
requestAnimationFrame(animate)
- environment.update(t)
- window.path && path.update(t)
- app.movements.update(dt || 0)
- scene.update()
+ environment.update(t, dt)
}
var loader = new Loader(function(){
diff --git a/public/assets/javascripts/defaults.js b/public/assets/javascripts/defaults.js
index 12aed62..1e1ac5b 100644
--- a/public/assets/javascripts/defaults.js
+++ b/public/assets/javascripts/defaults.js
@@ -1,5 +1,7 @@
+app = window.app || {}
app.defaults = {
viewHeight: window.viewHeight = 186,
+ wallHeight: 397,
units: app.units = "ft",
footResolution: 36,
meterResolution: 100,
@@ -13,7 +15,7 @@ app.defaults = {
},
}
-marked.setOptions({
+window.marked && marked.setOptions({
sanitize: true,
smartypants: true,
})
diff --git a/public/assets/javascripts/mx/extensions/mx.movements.js b/public/assets/javascripts/mx/extensions/mx.movements.js
index 9af2c8d..3e34c1b 100644
--- a/public/assets/javascripts/mx/extensions/mx.movements.js
+++ b/public/assets/javascripts/mx/extensions/mx.movements.js
@@ -20,7 +20,7 @@ MX.Movements = function (cam) {
rotationX_max = PI/6
var v = 12,
- vr = Math.PI * 0.012,
+ vr = Math.PI * 0.018,
jumpV = 23,
vx = vy = vz = 0,
creepFactor = 0.3
@@ -39,7 +39,7 @@ MX.Movements = function (cam) {
})
function clampRotation( vr ) {
- if (Rooms.mover.noclip) {
+ if (window.Rooms && Rooms.mover.noclip) {
return clamp(vr, PI/-2, PI/2 )
}
else {
@@ -155,6 +155,9 @@ MX.Movements = function (cam) {
app.controller.presets.hide()
$(".inuse").removeClass("inuse")
}
+ else if (Rooms.shapesMode) {
+ // don't show map in editor for now..
+ }
else {
app.controller.toolbar.toggleMap()
}
@@ -162,10 +165,13 @@ MX.Movements = function (cam) {
case 8: // backspace
e.preventDefault()
- if (app.controller.mediaEditor.scenery) {
+ if (app.controller.sculptureEditor && app.controller.sculptureEditor.sculpture) {
+ app.controller.sculptureEditor.sculpture.remove()
+ }
+ else if (app.controller.mediaEditor && app.controller.mediaEditor.scenery) {
app.controller.mediaEditor.scenery.remove()
}
- else if (app.controller.textEditor.scenery) {
+ else if (app.controller.textEditor && app.controller.textEditor.scenery) {
app.controller.textEditor.scenery.remove()
}
}
@@ -221,15 +227,19 @@ MX.Movements = function (cam) {
/*
case 48: // 0
- cam.rotationX = 0
- cam.rotationY = 0
- cam.x = 0
- cam.y = viewHeight
- cam.z = 0
+ movements.center()
break
*/
}
},
+
+ center: function(){
+ cam.rotationX = 0
+ cam.rotationY = 0
+ cam.x = 0
+ cam.y = viewHeight
+ cam.z = 0
+ },
mousedown: function (e) {
if (locked) return;
@@ -341,7 +351,7 @@ MX.Movements = function (cam) {
jumping = false
}
- var ceiling = (Rooms.mover.room ? Rooms.mover.room.height : 5000)
+ var ceiling = ((window.Rooms && Rooms.mover.room) ? Rooms.mover.room.height : 5000)
if (pos.y >= ceiling-5) {
vy = 0
diff --git a/public/assets/javascripts/mx/extensions/mx.orbitCamera.js b/public/assets/javascripts/mx/extensions/mx.orbitCamera.js
new file mode 100644
index 0000000..a936cef
--- /dev/null
+++ b/public/assets/javascripts/mx/extensions/mx.orbitCamera.js
@@ -0,0 +1,97 @@
+MX.OrbitCamera = function(opt){
+ var exports = {}, bound = false
+ exports.opt = opt = defaults(opt, {
+ el: window, // object to bind events on
+ camera: scene.camera, // camera object we'll be moving
+ radius: 100,
+ radiusRange: [ 10, 1000 ],
+ rotationX: PI/2,
+ rotationY: 0,
+ center: { x: 0, y: 0, z: 0 },
+ sensitivity: 10, // moving 1 pixel is like moving N radians
+ wheelSensitivity: 10,
+ ease: 10,
+ })
+ var rx, ry, radius, px, py, epsilon = 1e-10, dragging = false
+ exports.init = function(){
+ ry = opt.rotationY
+ rx = opt.rotationX
+ radius = opt.radius
+ exports.wheel = new wheel({
+ el: opt.el,
+ update: function(e, delta){
+ opt.radius = clamp( opt.radius + delta * opt.wheelSensitivity, opt.radiusRange[0], opt.radiusRange[1] )
+ },
+ })
+ exports.bind()
+ }
+ exports.toggle = function(state){
+ if (state) exports.bind()
+ else exports.unbind()
+ }
+ exports.bind = function(){
+ if (bound) return;
+ bound = true
+ opt.el.addEventListener("mousedown", down)
+ window.addEventListener("mousemove", move)
+ window.addEventListener("mouseup", up)
+ exports.wheel.unlock()
+ }
+ exports.unbind = function(){
+ if (! bound) return;
+ bound = false
+ opt.el.removeEventListener("mousedown", down)
+ window.removeEventListener("mousemove", move)
+ window.removeEventListener("mouseup", up)
+ exports.wheel.lock()
+ }
+ function down (e) {
+ px = e.pageX
+ py = e.pageY
+ dragging = true
+ }
+ function move (e) {
+ if (! dragging) return
+ exports.delta(px- e.pageX, py - e.pageY)
+ px = e.pageX
+ py = e.pageY
+ }
+ function up (e) {
+ dragging = false
+ }
+ exports.delta = function(x,y){
+ opt.rotationY += x/window.innerWidth * opt.sensitivity
+ opt.rotationX = clamp( opt.rotationX + y/window.innerHeight * opt.sensitivity, 0, PI)
+ }
+ exports.move = function(y, x){
+ opt.rotationY = y
+ if (typeof x == "number") { opt.rotationX = x }
+ }
+ exports.update = function(){
+ if (! bound) return
+ if (abs(ry - opt.rotationY) > epsilon) {
+ ry = avg(ry, opt.rotationY, opt.ease)
+ }
+ else {
+ ry = opt.rotationY
+ }
+ if (abs(rx - opt.rotationX) > epsilon) {
+ rx = avg(rx, opt.rotationX, opt.ease)
+ }
+ else {
+ rx = opt.rotationX
+ }
+ if (abs(radius - opt.radius) > epsilon) {
+ radius = avg(radius, opt.radius, opt.ease)
+ }
+ else {
+ radius = opt.radius
+ }
+ opt.camera.x = opt.center.x + radius * sin(rx) * cos(ry)
+ opt.camera.y = opt.center.y + radius * cos(rx)
+ opt.camera.z = opt.center.z + radius * sin(rx) * sin(ry)
+ opt.camera.rotationX = PI/2 - rx
+ opt.camera.rotationY = ry + PI/2
+ }
+ return exports
+}
diff --git a/public/assets/javascripts/mx/mx.js b/public/assets/javascripts/mx/mx.js
index ab9a9a0..60651eb 100644
--- a/public/assets/javascripts/mx/mx.js
+++ b/public/assets/javascripts/mx/mx.js
@@ -25,7 +25,7 @@ var MX = MX || (function (undefined) {
var MX = {
version: '0.1.0',
prefix: undefined,
- rotationUnit: 'rad'
+ rotationUnit: 'rad',
}
var floatPrecision = 5
@@ -162,24 +162,24 @@ var MX = MX || (function (undefined) {
Object.defineProperty(this, 'width', {
get: function () {
return width
- || parseInt(self.el.style.width, 10) * app.devicePixelRatio
+ || parseInt(self.el.style.width, 10) * app_devicePixelRatio
|| 0
},
set: function (val) {
width = val
- this.el.style.width = (width/app.devicePixelRatio) + 'px'
+ this.el.style.width = (width/app_devicePixelRatio) + 'px'
}
})
Object.defineProperty(this, 'height', {
get: function () {
return height
- || parseInt(self.el.style.height, 10) * app.devicePixelRatio
+ || parseInt(self.el.style.height, 10) * app_devicePixelRatio
|| 0
},
set: function (val) {
height = val
- this.el.style.height = (height/app.devicePixelRatio) + 'px'
+ this.el.style.height = (height/app_devicePixelRatio) + 'px'
}
})
}
@@ -302,9 +302,9 @@ var MX = MX || (function (undefined) {
+ (-this.y).toFixed(floatPrecision) + 'px,'
+ (-this.z).toFixed(floatPrecision) + 'px) '
+ 'scale3d('
- + (app.devicePixelRatio * this.scaleX).toFixed(floatPrecision) + ','
- + (app.devicePixelRatio * this.scaleY).toFixed(floatPrecision) + ','
- + (app.devicePixelRatio * this.scaleZ).toFixed(floatPrecision) + ') '
+ + (app_devicePixelRatio * this.scaleX).toFixed(floatPrecision) + ','
+ + (app_devicePixelRatio * this.scaleY).toFixed(floatPrecision) + ','
+ + (app_devicePixelRatio * this.scaleZ).toFixed(floatPrecision) + ') '
if (rotationTranslation) {
transformString += rotationTranslation.before
diff --git a/public/assets/javascripts/mx/primitives/mx.grid.js b/public/assets/javascripts/mx/primitives/mx.grid.js
new file mode 100644
index 0000000..a765c89
--- /dev/null
+++ b/public/assets/javascripts/mx/primitives/mx.grid.js
@@ -0,0 +1,70 @@
+MX.Grid = MX.Object3D.extend({
+ init: function (ops) {
+
+ this.type = "Grid"
+
+ var ops = this.ops = defaults(ops, {
+ x: 0,
+ y: 0,
+ z: 0,
+ space: 20,
+ cells: 20,
+ })
+
+ ops.side = ops.space * ops.cells
+
+ var ctx, canvas = document.createElement("canvas")
+
+ this.el = canvas
+ this.width = this.height = canvas.width = canvas.height = ops.side + 4
+
+ ctx = canvas.getContext('2d')
+
+ this.x = ops.x || 0
+ this.y = ops.y || 0
+ this.z = ops.z || 0
+ this.rotationX = PI/2
+ this.scale = ops.scale || 1
+ this.backface = ops.backface || false
+
+ ops.className && this.el.classList.add(ops.className)
+ this.backface && this.el.classList.add("backface-visible")
+ this.el.classList.add("mx-grid")
+
+ this.draw(ctx)
+ },
+
+ draw: function(ctx, recenter){
+ ctx = ctx || this.ctx
+
+ if (recenter) {
+ ctx.save()
+ ctx.translate( -grid.width/2, -grid.height/2 )
+ }
+
+ var cells = this.ops.cells,
+ space = this.ops.space,
+ side = this.ops.side
+
+ ctx.strokeStyle = "#444"
+ ctx.lineWidth = 1
+ ctx.beginPath()
+ ctx.translate(1,1)
+ for (var i = 0; i <= cells; i++) {
+ ctx.moveTo(i*space, 0)
+ ctx.lineTo(i*space, side)
+ ctx.moveTo(0, i*space)
+ ctx.lineTo(side, i*space)
+ }
+ ctx.closePath()
+ ctx.stroke()
+
+ if (recenter) {
+ ctx.restore()
+ }
+
+ },
+
+})
+
+
diff --git a/public/assets/javascripts/mx/primitives/mx.image.js b/public/assets/javascripts/mx/primitives/mx.image.js
index b8557bf..ce99592 100644
--- a/public/assets/javascripts/mx/primitives/mx.image.js
+++ b/public/assets/javascripts/mx/primitives/mx.image.js
@@ -1,6 +1,7 @@
MX.Image = MX.Object3D.extend({
init: function (ops) {
-
+ ops = ops || {}
+
this.type = "Image"
this.media = ops.media
this.width = 0
@@ -18,7 +19,7 @@ MX.Image = MX.Object3D.extend({
this.el.style.backgroundRepeat = 'no-repeat'
- this.load(ops)
+ ops.src && this.load(ops)
},
load: function(ops){
@@ -41,8 +42,41 @@ MX.Image = MX.Object3D.extend({
layer.el.classList.add('image')
layer.dirty = true
layer.update()
+ layer.ops.onload
+
+ if (ops.keepImage) {
+ layer.image = image
+ }
+ }
+
+ if (ops.src) {
+ image.src = ops.src
+ }
+ else if (ops.media) {
+ image.src = ops.media.url
+ }
+ else if (ops.url) {
+ image.src = ops.url
+ }
+ },
+
+ draw: function(ctx, recenter){
+ if (! this.image) { return }
+
+ if (recenter) {
+ ctx.save()
+ ctx.scale(-1, 1)
+ ctx.translate( -this.width/2 * this.scale, -this.height/2 * this.scale )
+ }
+
+ ctx.drawImage(this.image,
+ 0, 0, this.image.naturalWidth, this.image.naturalHeight,
+ 0, 0, this.image.width * this.scale * devicePixelRatio, this.image.height * this.scale * devicePixelRatio
+ )
+
+ if (recenter) {
+ ctx.restore()
}
- image.src = ops.src;
},
})
diff --git a/public/assets/javascripts/mx/primitives/mx.point.js b/public/assets/javascripts/mx/primitives/mx.point.js
new file mode 100644
index 0000000..41a7732
--- /dev/null
+++ b/public/assets/javascripts/mx/primitives/mx.point.js
@@ -0,0 +1,17 @@
+MX.Point = MX.Object3D.extend({
+ init: function(p){
+ this.updateChildren = false
+ this.move({
+ x: p.a,
+ y: 11,
+ z: p.b,
+ width: 20,
+ height: 20,
+ rotationX: PI/2,
+ })
+ this.el.style.backgroundColor = 'rgb(' + [abs(floor(p.a*30)), 0, abs(floor(p.b*30))] + ')'
+ this.el.style.backfaceVisibility = "visible"
+ this.el.style.borderRadius = "50%"
+ scene.add(this)
+ }
+})
diff --git a/public/assets/javascripts/mx/primitives/mx.polyline.js b/public/assets/javascripts/mx/primitives/mx.polyline.js
new file mode 100644
index 0000000..e549150
--- /dev/null
+++ b/public/assets/javascripts/mx/primitives/mx.polyline.js
@@ -0,0 +1,57 @@
+MX.Polyline = MX.Object3D.extend({
+ init: function(polyline){
+ this.faces = []
+ this.points = polyline.points
+ for (var i = 1; i < this.points.length; i++) {
+ var mx = new MX.Object3D()
+ var head = this.points[i-1]
+ var tail = this.points[i]
+ this.move_face(mx, head, tail)
+ this.faces.push(mx)
+ scene.add(mx)
+ }
+ },
+
+ rebuild: function(){
+ for (var i = 1; i < this.points.length; i++) {
+ var mx = this.faces[i-1]
+ var head = this.points[i-1]
+ var tail = this.points[i]
+ this.move_face(mx, head, tail)
+ }
+ },
+
+ move_face: function (mx, head, tail){
+ var mid_x = (head.a + tail.a)
+ var mid_z = (head.b + tail.b)
+ var len = head.distanceTo( tail )
+ var angle = atan2( head.b - tail.b, head.a - tail.a )
+ mx.move({
+ x: mid_x / 2,
+ y: wallHeight/2 + 1,
+ z: mid_z / 2,
+ width: ceil(len),
+ height: wallHeight,
+ rotationY: angle
+ })
+ // var hue = abs(round( angle / PI * 90 + 300))
+ // mx.el.style.backgroundColor = 'hsl(' + [hue, "100%", "50%"] + ')'
+ var lum = abs(round( angle / PI * 20 + 70))
+ mx.el.style.backgroundColor = 'hsla(' + ["0", "0%", lum + "%", "0.99"] + ')'
+ },
+
+ set_height: function(height){
+ for (var i = 0; i < this.faces.length; i++) {
+ this.faces[i].height = height
+ this.faces[i].y = height / 2 + 1
+ }
+ },
+
+ destroy: function(){
+ this.faces.forEach(function(mx){
+ scene.remove(mx)
+ })
+ this.faces = null
+ this.points = null
+ },
+})
diff --git a/public/assets/javascripts/mx/primitives/mx.soundcloud.js b/public/assets/javascripts/mx/primitives/mx.soundcloud.js
index 75286d9..fecb2f4 100644
--- a/public/assets/javascripts/mx/primitives/mx.soundcloud.js
+++ b/public/assets/javascripts/mx/primitives/mx.soundcloud.js
@@ -102,6 +102,11 @@ MX.Soundcloud = MX.Object3D.extend({
setLoop: function(state){
this.media.loop = state
},
+
+ setVolume: function(n){
+ if (this.muted || ! this.player) return
+ this.player.setVolume(floor( n * 100 ))
+ },
didPlay: function(){
this.paused = false
diff --git a/public/assets/javascripts/mx/primitives/mx.video.js b/public/assets/javascripts/mx/primitives/mx.video.js
index c281f02..53ccf2e 100644
--- a/public/assets/javascripts/mx/primitives/mx.video.js
+++ b/public/assets/javascripts/mx/primitives/mx.video.js
@@ -21,6 +21,7 @@ MX.Video = MX.Object3D.extend({
this.el.classList.add("video")
this.el.classList.add("mx-scenery")
this.paused = !! this.media.autoplay
+ this.playing = false
this.muted = app.muted || !! this.media.mute
},
@@ -60,11 +61,13 @@ MX.Video = MX.Object3D.extend({
play: function(){
this.paused = false
+ this.playing = true
this.player.play()
},
pause: function(){
this.paused = true
+ this.playing = false
this.player.pause()
},
@@ -87,6 +90,11 @@ MX.Video = MX.Object3D.extend({
this.muted = false
},
+ setVolume: function(n){
+ if (this.muted || ! this.player) return
+ this.player.volume = n
+ },
+
setLoop: function(state){
this.media.loop = state
},
diff --git a/public/assets/javascripts/mx/primitives/mx.vimeo.js b/public/assets/javascripts/mx/primitives/mx.vimeo.js
index fe5ce86..af138ae 100644
--- a/public/assets/javascripts/mx/primitives/mx.vimeo.js
+++ b/public/assets/javascripts/mx/primitives/mx.vimeo.js
@@ -20,6 +20,7 @@ MX.Vimeo = MX.Object3D.extend({
this.backface && this.el.classList.add("backface-visible")
this.el.classList.add("video")
this.el.classList.add("mx-scenery")
+ this.playing = false
this.paused = !! this.media.autoplay
this.muted = app.muted || !! this.media.mute
this.started = false
@@ -99,7 +100,7 @@ MX.Vimeo = MX.Object3D.extend({
return
}
- if (! this.started || n === 0) {
+ if (! this.started) {
return
}
@@ -130,6 +131,11 @@ MX.Vimeo = MX.Object3D.extend({
this.player.api('setVolume', 0.8)
this.muted = false
},
+
+ setVolume: function(n){
+ if (this.muted || ! this.player) return
+ this.player.api('setVolume', n)
+ },
setLoop: function(state){
this.media.loop = state
@@ -140,19 +146,26 @@ MX.Vimeo = MX.Object3D.extend({
if (this.paused) {
this.pause()
}
+ else {
+ this.playing = true
+ }
},
onPause: function(){
if (! this.paused) {
this.play()
}
+ else {
+ this.playing = false
+ }
},
finished: function(){
-// if (this.media.loop) {
-// this.seek(0)
-// this.play()
-// }
+ console.log("vimeo finished")
+ if (this.media.loop) {
+ this.seek(0)
+ this.play()
+ }
// else if (this.bound) {
if (! this.media.loop && this.bound) {
$(".playButton").removeClass('playing')
diff --git a/public/assets/javascripts/mx/primitives/mx.youtube.js b/public/assets/javascripts/mx/primitives/mx.youtube.js
index 5c92378..8cd9f59 100644
--- a/public/assets/javascripts/mx/primitives/mx.youtube.js
+++ b/public/assets/javascripts/mx/primitives/mx.youtube.js
@@ -21,6 +21,7 @@ MX.Youtube = MX.Object3D.extend({
this.el.classList.add("video")
this.el.classList.add("mx-scenery")
this.paused = !! this.media.autoplay
+ this.playing = false
this.muted = app.muted || !! this.media.mute
},
@@ -143,11 +144,13 @@ MX.Youtube = MX.Object3D.extend({
play: function(){
this.paused = false
+ this.playing = true
this.player.playVideo()
},
pause: function(){
this.paused = true
+ this.playing = false
this.player.pauseVideo()
},
@@ -173,6 +176,11 @@ MX.Youtube = MX.Object3D.extend({
this.player.setVolume(80)
this.muted = false
},
+
+ setVolume: function(n){
+ if (this.muted || ! this.player || ! this.player.setVolume) return
+ this.player.setVolume( floor(n * 100) )
+ },
setLoop: function(state){
this.media.loop = state
diff --git a/public/assets/javascripts/rectangles/_env.js b/public/assets/javascripts/rectangles/_env.js
index 3221bac..b3c7d66 100644
--- a/public/assets/javascripts/rectangles/_env.js
+++ b/public/assets/javascripts/rectangles/_env.js
@@ -1,6 +1,22 @@
var environment = new function(){}
environment.init = function(){
+ scene = new MX.Scene().addTo('#scene')
+ scene.width = window.innerWidth
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ cam = scene.camera
+ cam.y = viewHeight
+
+ if (is_mobile) {
+ app.movements = new MX.MobileMovements(cam, viewHeight)
+ }
+ else {
+ app.movements = new MX.Movements(cam, viewHeight)
+ }
+ app.movements.init()
+
map = new Map ()
if (window.scene) {
@@ -16,10 +32,18 @@ environment.init = function(){
scene.camera.radius = 20
}
-
+
+ window.onresize = function () {
+ scene.width = window.innerWidth
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+ scene.update()
+ }
+
Rooms.init()
Walls.init()
Scenery.init()
+ Sculpture.init()
scene.update()
environment.update()
@@ -51,8 +75,13 @@ environment.init = function(){
}
})
}
-environment.update = function(t){
+environment.minimal = function(){
+ environment.update = function(t){}
+}
+environment.update = function(t, dt){
+ app.movements.update(dt || 0)
+ scene.update()
map.update()
- window.minimap && window.minimap.update && minimap.update()
+ window.minimap && minimap.update && minimap.update()
z = false
}
diff --git a/public/assets/javascripts/rectangles/engine/map/_map.js b/public/assets/javascripts/rectangles/engine/map/_map.js
index 202803a..6492db6 100644
--- a/public/assets/javascripts/rectangles/engine/map/_map.js
+++ b/public/assets/javascripts/rectangles/engine/map/_map.js
@@ -16,6 +16,7 @@ var Map = function(opt){
var base = this
base.el = opt.el
base.$el = $(base.el)
+ base.opt = opt
if (! base.el) return
@@ -33,7 +34,6 @@ var Map = function(opt){
scene.camera.x + sides.a, scene.camera.z + sides.b )
}
-
base.set_zoom = function (n) {
n = clamp(n, opt.zoom_min, opt.zoom_max)
base.zoom_exponent = n
@@ -44,12 +44,21 @@ var Map = function(opt){
var canvas = base.canvas = document.createElement("canvas")
canvas.width = base.dimensions.a
canvas.height = base.dimensions.b
-
+
base.el.appendChild(canvas)
switch (opt.type) {
+ case "ortho":
+ base.draw = new Map.Draw (base, { ortho: true })
+ base.draw.grid_size = MAP_GRID_SIZE
+ base.ui = new Map.UI.Ortho (base)
+ base.sides = base.sides_for_center
+ $(window).resize(base.resize)
+ break
+
case "editor":
base.draw = new Map.Draw (base)
+ base.draw.grid_size = MAP_GRID_SIZE
base.ui = new Map.UI.Editor (base)
base.sides = base.sides_for_center
$(window).resize(base.resize)
@@ -57,14 +66,16 @@ var Map = function(opt){
case "minimap":
base.draw = new Map.Draw (base, { center: scene.camera, minimap: true })
+ base.draw.grid_size = MAP_GRID_SIZE * 10
base.ui = new Map.UI.Minimap (base)
base.sides = base.sides_for_camera
break
}
- base.resize = function(){
- canvas.width = base.dimensions.a = window.innerWidth
- canvas.height = base.dimensions.b = window.innerHeight
+ base.resize = function(w, h){
+ canvas.width = base.dimensions.a = w || window.innerWidth
+ canvas.height = base.dimensions.b = h || window.innerHeight
+ // resize here - esp if 2d-hires
}
base.toggle = function(state){
diff --git a/public/assets/javascripts/rectangles/engine/map/draw.js b/public/assets/javascripts/rectangles/engine/map/draw.js
index eceda3c..4f4759f 100644
--- a/public/assets/javascripts/rectangles/engine/map/draw.js
+++ b/public/assets/javascripts/rectangles/engine/map/draw.js
@@ -5,24 +5,32 @@ Map.Draw = function(map, opt){
var draw = this
- var ctx = map.canvas.getContext("2d")
+ var ctx = draw.ctx = map.canvas.getContext("2d")
draw.animate = function(){
ctx.save()
draw.clear()
draw.fill("rgba(255,255,255,0.98)")
- if (opt.minimap) {
+ if (opt.ortho) {
+ }
+ else if (opt.minimap) {
ctx.translate( map.dimensions.a * 1/2, map.dimensions.b * 1/2)
ctx.scale( map.zoom, map.zoom )
+ if (map.opt.pivot) { ctx.rotate(scene.camera.rotationY + PI) }
ctx.translate( opt.center.x, - opt.center.z )
ctx.scale( -1, 1 )
draw.coords()
- draw.regions(Rooms.regions, [ "#fff" ], "#000")
+ if (Rooms.shapesMode) {
+ shapes.draw(draw.ctx, "#fff", null)
+ shapes.draw(draw.ctx, null, "#000")
+ }
+ else {
+ draw.regions(Rooms.regions, [ "#fff" ], "#000")
+ }
draw.camera(scene.camera)
}
-
else {
ctx.translate( map.dimensions.a * 1/2, map.dimensions.b * 1/2)
ctx.scale( map.zoom, map.zoom )
@@ -31,12 +39,19 @@ Map.Draw = function(map, opt){
draw.regions(Rooms.regions, [ "#f8f8f8" ], "#000")
draw.mouse(map.ui.mouse.cursor)
+ draw.mouse_dimensions(map.ui.mouse.cursor)
draw.coords()
scene && draw.camera(scene.camera)
}
ctx.restore()
}
+ draw.translate = function(){
+ ctx.translate( map.dimensions.a * 1/2, map.dimensions.b * 1/2)
+ ctx.scale( map.zoom, map.zoom )
+ ctx.translate( map.center.a, map.center.b )
+ ctx.scale( -1, 1 )
+ }
// changes the ctx temporarily
draw.render = function(){
@@ -56,9 +71,9 @@ Map.Draw = function(map, opt){
}
var canvas = document.createElement("canvas")
- ctx = canvas.getContext('2d')
canvas.width = thumbnail_width
canvas.height = thumbnail_height
+ ctx = canvas.getContext('2d')
draw.clear()
@@ -87,7 +102,7 @@ Map.Draw = function(map, opt){
ctx.putImageData(pixelData, 0, 0)
// reset the ctx
- ctx = map.canvas.getContext("2d")
+ ctx = draw.ctx
return canvas
}
@@ -123,7 +138,8 @@ Map.Draw = function(map, opt){
ctx.beginPath();
ctx.arc(mouse.x.b, mouse.y.b, radius, 0, 2*Math.PI, false);
ctx.fill();
-
+ }
+ draw.mouse_dimensions = function(mouse){
if (mouse.width() != 0 && mouse.height() != 0) {
if (map.ui.dragging) {
stroke_rect(mouse)
@@ -159,36 +175,39 @@ Map.Draw = function(map, opt){
}
draw.coords = function(){
- /*
- ctx.fillStyle = "#888";
- dot_at(0,0)
- ctx.fillStyle = "#bbb";
- dot_at(100,0)
- dot_at(0,100)
- ctx.fillStyle = "#ddd";
- dot_at(200,0)
- dot_at(0,200)
- ctx.fillStyle = "#eee";
- dot_at(300,0)
- dot_at(0,300)
- */
-
ctx.strokeStyle = "rgba(0,0,0,0.1)"
ctx.lineWidth = 1/map.zoom
var sides = map.sides()
- var quant = sides.clone().quantize(MAP_GRID_SIZE)
- for (var x = quant.x.a - MAP_GRID_SIZE; x <= quant.x.b; x += MAP_GRID_SIZE) {
- line(x, sides.y.a, x, sides.y.b)
- }
- for (var y = quant.y.a - MAP_GRID_SIZE; y <= quant.y.b; y += MAP_GRID_SIZE) {
- line(sides.x.a, y, sides.x.b, y)
+ var quant = sides.clone().quantize(draw.grid_size)
+ for (var x = quant.x.a - draw.grid_size; x <= quant.x.b; x += draw.grid_size) {
+ if (Math.round(x) % 360 == 0) {
+ ctx.strokeStyle = "rgba(0,0,0,0.3)"
+ ctx.lineWidth = 1/map.zoom
+ }
+ else {
+ ctx.strokeStyle = "rgba(0,0,0,0.05)"
+ ctx.lineWidth = 1/map.zoom
+ }
+ line(x, sides.y.a, x, sides.y.b)
}
+
+ for (var y = quant.y.a - draw.grid_size; y <= quant.y.b; y += draw.grid_size) {
+ if (Math.round(y) % 360 == 0) {
+ ctx.strokeStyle = "rgba(0,0,0,0.3)"
+ ctx.lineWidth = 1/map.zoom
+ }
+ else {
+ ctx.strokeStyle = "rgba(0,0,0,0.05)"
+ ctx.lineWidth = 1/map.zoom
+ }
+ line(sides.x.a, y, sides.x.b, y)
+ }
}
//
- function line (x,y,a,b,translation){
+ var line = draw.line = function (x,y,a,b,translation){
if (translation) {
x += translation.a
a += translation.a
@@ -219,11 +238,11 @@ Map.Draw = function(map, opt){
line(r.x.a, r.y.a, r.x.b, r.y.b, r.translation)
}
- function dot_at (x,z){
+ draw.dot_at = function dot_at (x, z, radius){
ctx.save()
ctx.translate(x,z)
- var radius = 2 / map.zoom
+ radius = (radius || 2) / map.zoom
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2*Math.PI, false);
@@ -231,4 +250,29 @@ Map.Draw = function(map, opt){
ctx.restore()
}
+
+ draw.x_at = function x_at (x, z, length){
+ ctx.save()
+ if (x && 'x' in x) {
+ length = z
+ ctx.translate(x.x,x.z)
+ }
+ else {
+ ctx.translate(x,z)
+ }
+
+ var len = (length/2 || 4) / map.zoom
+
+ ctx.lineCap = "square"
+ ctx.lineWidth = 2/map.zoom
+ ctx.beginPath()
+ ctx.moveTo( -len, -len);
+ ctx.lineTo( len, len);
+ ctx.moveTo( -len, len);
+ ctx.lineTo( len, -len);
+ ctx.stroke();
+
+ ctx.restore()
+ }
+
} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/_base.js b/public/assets/javascripts/rectangles/engine/map/tools/_base.js
new file mode 100644
index 0000000..17b247d
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/_base.js
@@ -0,0 +1,11 @@
+var MapTool = Fiber.extend(function(base){
+ var exports = {
+ recenterCursor: true,
+ down: function(e, cursor){},
+ move: function(e, cursor){},
+ drag: function(e, cursor){},
+ up: function(e, cursor, new_cursor){},
+ cancel: function(){},
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/arrow.js b/public/assets/javascripts/rectangles/engine/map/tools/arrow.js
new file mode 100644
index 0000000..0b0557e
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/arrow.js
@@ -0,0 +1,83 @@
+// Tool used to move corners of polylines
+
+var ArrowTool = MapTool.extend(function(base){
+ var exports = {}
+
+ var selected_point = null, selected_segment = null, original_point = null, selected_shape = null
+ var src_points, dest_points
+
+ exports.down = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var p = shapes.findClosestPoint(last_point)
+ if (p && p.shape.type() !== "ortho") {
+ selected_shape = p.shape
+ selected_point = p.point
+ original_point = selected_point.clone()
+ return
+ }
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ document.body.style.cursor = "pointer"
+
+ selected_segment = segment
+ console.log(segment.head, segment.tail)
+ selected_shape = segment.shape
+ src_points = segment.shape.cloneSegment( segment )
+ dest_points = segment.shape.getSegment( segment )
+
+ last_point.a = segment.x
+ last_point.b = segment.y
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ else {
+ map.ui.set_drag_tool("position")
+ }
+ }
+
+ exports.move = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var p = shapes.findClosestPoint(last_point)
+ if (p) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(p.point)
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ return
+ }
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ document.body.style.cursor = "pointer"
+ last_point.a = segment.x
+ last_point.b = segment.y
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+
+ exports.drag = function(e, cursor){
+ if (selected_point) {
+ selected_point.a = original_point.a + cursor.x.magnitude()
+ selected_point.b = original_point.b + cursor.y.magnitude()
+ selected_shape.rebuild()
+ }
+ else if (selected_segment) {
+ selected_shape.translateSegment(
+ src_points, dest_points,
+ cursor.x.magnitude(), cursor.y.magnitude()
+ )
+ selected_shape.rebuild()
+ }
+ }
+
+ exports.up = function(e, cursor){
+ selected_point = selected_shape = selected_segment = original_point = null
+ }
+
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/eraser.js b/public/assets/javascripts/rectangles/engine/map/tools/eraser.js
new file mode 100644
index 0000000..8fc3687
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/eraser.js
@@ -0,0 +1,29 @@
+// Tool used to delete lines
+
+var EraserTool = MapTool.extend(function(base){
+ var exports = {}
+ exports.down = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ shapes.removeSegment(segment)
+ }
+ }
+ exports.move = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ document.body.style.cursor = "pointer"
+ last_point.a = segment.x
+ last_point.b = segment.y
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+ return exports
+})
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/line.js b/public/assets/javascripts/rectangles/engine/map/tools/line.js
new file mode 100644
index 0000000..8175d66
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/line.js
@@ -0,0 +1,63 @@
+// Tool is used to define a very simple line between two points.
+// It is used by the BlueprintScaler to specify a sample distance to scale.
+
+var LineTool = MapTool.extend(function(base){
+ var exports = {}
+
+ var selected_point = null
+
+ var line = exports.line = []
+
+ var can_drag, dragging
+
+ exports.down = function(e, cursor){
+
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ cursor.quantize(1/map.zoom)
+ app.router.blueprintView.map.center.a = cursor.x.a
+ app.router.blueprintView.map.center.b = -cursor.y.a
+ cursor.x.b = cursor.x.a
+ cursor.y.b = cursor.y.a
+ return
+ }
+
+ this.cursor = cursor
+ switch (line.length) {
+ case 0:
+ line[0] = cursor.x_component()
+ can_drag = true
+ break
+ case 1:
+ line[1] = cursor.x_component()
+ can_drag = false
+ break
+ case 2:
+ line[0] = cursor.x_component()
+ line.pop()
+ can_drag = true
+ break
+ }
+ }
+
+ exports.move = function(e, cursor){
+ this.cursor = cursor
+ }
+
+ exports.drag = function(e, cursor){
+ if (dragging) {
+ line[1].a = cursor.x.b
+ line[1].b = cursor.y.b
+ }
+ else if (can_drag && cursor.magnitude() > 10/map.zoom) {
+ line[1] = cursor.y_component()
+ dragging = true
+ }
+ }
+
+ exports.up = function(e, cursor){
+ can_drag = dragging = false
+ }
+
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/ortho.js b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js
new file mode 100644
index 0000000..374c822
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js
@@ -0,0 +1,118 @@
+// Tool to make a polyline where all walls are orthogonal
+
+var OrthoPolylineTool = MapTool.extend(function (base) {
+
+ var prev_point, horizontal = false, first_edge_is_horizontal = false
+
+ var exports = {}
+ exports.down = function(e, cursor){
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ e.preventDefault()
+ e.stopPropagation()
+ if (map.ui.placing) {
+ // close polyline or cancel
+ map.ui.placing = false
+ if (shapes.workline.points.length > 2) {
+ shapes.workline.build()
+ shapes.add(shapes.workline)
+ }
+ else {
+ shapes.workline.reset()
+ }
+ return
+ }
+ else {
+ map.ui.tools.position.rightclick(e, cursor)
+ }
+ return
+ }
+
+ // compare to initial point
+ var p = last_point.clone()
+ if (map.ui.placing) {
+ if (shapes.workline.lastPoint().eq(p)) {
+ return
+ }
+ else if (shapes.workline.canCloseWith(p)) {
+ shapes.workline.close()
+ shapes.workline.build()
+ shapes.add(shapes.workline)
+ map.ui.placing = false
+ }
+ else {
+ shapes.workline.add(p)
+ prev_point = p
+ horizontal = ! horizontal
+ }
+ }
+ else {
+ map.ui.placing = true
+ shapes.workline = new OrthoPolyline ()
+ shapes.workline.add(p)
+ first_point = prev_point = p
+ horizontal = false
+ }
+ }
+ exports.move = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ if (map.ui.placing) {
+ if (shapes.workline.points.length == 1) {
+ var x = abs(prev_point.a - last_point.a)
+ var y = abs(prev_point.b - last_point.b)
+ if (x > y) {
+ last_point.b = prev_point.b
+ first_edge_is_horizontal = horizontal = true
+ }
+ else {
+ last_point.a = prev_point.a
+ first_edge_is_horizontal = horizontal = false
+ }
+ }
+ else {
+ if (horizontal) {
+ last_point.b = prev_point.b
+ }
+ else {
+ last_point.a = prev_point.a
+ }
+ if (horizontal == first_edge_is_horizontal) {
+ // check if this point is within N pixels of the normal
+ // and lock it into place if so
+ if (horizontal && abs( first_point.a - last_point.a ) < 10/map.zoom) {
+ last_point.a = first_point.a
+ }
+ else if (! horizontal && abs( first_point.b - last_point.b ) < 10/map.zoom) {
+ last_point.b = first_point.b
+ }
+ }
+ }
+
+ if (shapes.workline.canCloseWith(last_point)) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(first_point)
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ return
+ }
+ var end_point = shapes.findClosestEndPoint(last_point)
+ if (end_point) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(end_point.point)
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ return
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+ exports.cancel = function(){
+ if (map.ui.placing) { shapes.workline.reset() }
+ first_point = null
+ map.ui.placing = false
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/polyline.js b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js
new file mode 100644
index 0000000..445ae26
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js
@@ -0,0 +1,73 @@
+// Tool used to draw polylines with arbitrary angles
+
+var PolylineTool = MapTool.extend(function (base) {
+ var exports = {}
+ exports.down = function(e, cursor){
+
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ e.preventDefault()
+ e.stopPropagation()
+ if (map.ui.placing) {
+ // close polyline or cancel
+ map.ui.placing = false
+ if (shapes.workline.points.length > 2) {
+ shapes.workline.build()
+ shapes.add(shapes.workline)
+ }
+ else {
+ shapes.workline.reset()
+ }
+ return
+ }
+ map.ui.tools.position.rightclick(e, cursor)
+ return
+ }
+
+ // compare to initial point
+ var p = last_point.clone()
+ if (map.ui.placing) {
+ if (shapes.workline.canCloseWith(p)) {
+ shapes.workline.close()
+ shapes.workline.build()
+ shapes.add(shapes.workline)
+ map.ui.placing = false
+ }
+ else {
+ shapes.workline.add(p)
+ }
+ }
+ else {
+ map.ui.placing = true
+ shapes.workline = new Polyline ()
+ shapes.workline.add(p)
+ }
+ }
+ exports.move = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ if (map.ui.placing && shapes.workline.canCloseWith(last_point)) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(shapes.workline.points[0])
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ return
+ }
+ var end_point = shapes.findClosestEndPoint(last_point)
+ if (end_point) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(end_point.point)
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ return
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+ exports.cancel = function(){
+ if (map.ui.placing) { shapes.workline.reset() }
+ map.ui.placing = false
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/position.js b/public/assets/javascripts/rectangles/engine/map/tools/position.js
new file mode 100644
index 0000000..f8365bc
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/position.js
@@ -0,0 +1,19 @@
+// Tool used to set position on the map and let you change the view by dragging.
+
+var PositionTool = MapTool.extend(function(base){
+ var exports = {
+ recenterCursor: false,
+ drag: function(e, cursor){
+ map.center.a = -cursor.x.magnitude()
+ map.center.b = cursor.y.magnitude()
+ },
+ rightclick: function(e, cursor){
+ cursor.quantize(1/map.zoom)
+ map.center.a = cursor.x.a
+ map.center.b = -cursor.y.a
+ cursor.x.b = cursor.x.a
+ cursor.y.b = cursor.y.a
+ }
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/start.js b/public/assets/javascripts/rectangles/engine/map/tools/start.js
new file mode 100644
index 0000000..203a85f
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/start.js
@@ -0,0 +1,29 @@
+// Tool is used to set the start position on the map.
+
+var StartPositionTool = MapTool.extend(function(base){
+ var exports = {}
+
+ var selected_point = null
+
+ var line = exports.line = []
+
+ var can_drag, dragging
+
+ exports.down = function(e, cursor){
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ cursor.quantize(1/map.zoom)
+ app.router.blueprintView.map.center.a = cursor.x.a
+ app.router.blueprintView.map.center.b = -cursor.y.a
+ cursor.x.b = cursor.x.a
+ cursor.y.b = cursor.y.a
+ return
+ }
+
+ cam.x = app.controller.startPosition.x = cursor.x.a
+ cam.z = app.controller.startPosition.z = cursor.y.a
+ }
+
+ return exports
+
+})
diff --git a/public/assets/javascripts/rectangles/engine/map/ui_editor.js b/public/assets/javascripts/rectangles/engine/map/ui/editor.js
index 7308344..3e1d720 100644
--- a/public/assets/javascripts/rectangles/engine/map/ui_editor.js
+++ b/public/assets/javascripts/rectangles/engine/map/ui/editor.js
@@ -73,7 +73,7 @@ Map.UI.Editor = function(map){
app.tube("builder-destroy-room", room)
// TODO: watch individual scenery object here
- Minotaur.watch( app.router.editorView.settings )
+ Minotaur.watch( app.controller.settings )
return
}
else if (intersects.length) {
@@ -205,7 +205,7 @@ Map.UI.Editor = function(map){
Rooms.rebuild()
// TODO: watch individual scenery object here
- Minotaur.watch( app.router.editorView.settings )
+ Minotaur.watch( app.controller.settings )
}
var intersects = Rooms.filter(function(r){
@@ -247,7 +247,7 @@ Map.UI.Editor = function(map){
Rooms.rebuild()
// TODO: watch individual scenery object here
- Minotaur.watch( app.router.editorView.settings )
+ Minotaur.watch( app.controller.settings )
wheelState = null
}, 250)
@@ -268,7 +268,7 @@ Map.UI.Editor = function(map){
Rooms.rebuild()
// TODO: watch individual scenery object here
- Minotaur.watch( app.router.editorView.settings )
+ Minotaur.watch( app.controller.settings )
wheelState = null
}, 250)
diff --git a/public/assets/javascripts/rectangles/engine/map/ui_minimap.js b/public/assets/javascripts/rectangles/engine/map/ui/minimap.js
index 0fdd336..0fdd336 100644
--- a/public/assets/javascripts/rectangles/engine/map/ui_minimap.js
+++ b/public/assets/javascripts/rectangles/engine/map/ui/minimap.js
diff --git a/public/assets/javascripts/rectangles/engine/map/ui/ortho.js b/public/assets/javascripts/rectangles/engine/map/ui/ortho.js
new file mode 100644
index 0000000..5be7446
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/ui/ortho.js
@@ -0,0 +1,107 @@
+Map.UI = Map.UI || {}
+Map.UI.Ortho = function(map){
+
+ var base = this
+ var last_event = null
+
+ base.creating = base.dragging = base.resizing = false
+
+ base.mouse = new mouse({
+ el: map.el,
+ down: function(e, cursor){
+ last_event = e
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom)
+ if (tool.recenterCursor) {
+ cursor.x.add(map.center.a)
+ cursor.y.sub(map.center.b)
+ base.tools[currentTool].down(e, cursor)
+ }
+ else {
+ base.tools[currentTool].down(e, cursor)
+ cursor.x.add(map.center.a)
+ cursor.y.sub(map.center.b)
+ }
+ },
+ move: function(e, cursor){
+ last_event = e
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom)
+ if (tool.recenterCursor) {
+ cursor.x.add(map.center.a)
+ cursor.y.sub(map.center.b)
+ base.tools[currentTool].move(e, cursor)
+ }
+ else {
+ base.tools[currentTool].move(e, cursor)
+ cursor.x.add(map.center.a)
+ cursor.y.sub(map.center.b)
+ }
+ },
+ drag: function(e, cursor){
+ last_event = e
+ cursor.x.b = ((cursor.x.b/map.dimensions.a)+0.5) * map.dimensions.a / map.zoom
+ cursor.y.b = ((cursor.y.b/map.dimensions.b)-0.5) * map.dimensions.b / map.zoom
+ if (tool.recenterCursor) {
+ cursor.x.b += map.center.a
+ cursor.y.b -= map.center.b
+ base.tools[currentTool].drag(e, cursor)
+ }
+ else {
+ base.tools[currentTool].drag(e, cursor)
+ cursor.x.b += map.center.a
+ cursor.y.b -= map.center.b
+ }
+ },
+ up: function(e, cursor, new_cursor){
+ last_event = e
+ new_cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom)
+ new_cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom)
+ if (tool.recenterCursor) {
+ new_cursor.x.add(map.center.a)
+ new_cursor.y.sub(map.center.b)
+ base.tools[currentTool].up(e, cursor, new_cursor)
+ }
+ else {
+ base.tools[currentTool].up(e, cursor, new_cursor)
+ new_cursor.x.add(map.center.a)
+ new_cursor.y.sub(map.center.b)
+ }
+ if (nextTool) {
+ console.log('found nextTool')
+ base.set_tool(nextTool)
+ nextTool = null
+ }
+ }
+ })
+
+ var currentTool = "polyline", nextTool, tool
+ base.add_tool = function(name, tool){
+ base.tools[name] = tool
+ }
+ base.set_tool = function(s){
+ console.log("set tool to", s)
+ if (base.tools[currentTool]) {
+ base.tools[currentTool].cancel()
+ }
+ currentTool = s
+ tool = base.tools[currentTool]
+ }
+ base.set_drag_tool = function(s){
+ console.log('set drag tool to', s)
+ nextTool = currentTool
+ currentTool = s
+ tool = base.tools[currentTool]
+ base.tools[currentTool].down(last_event, base.mouse.cursor)
+ }
+ base.tools = {}
+
+ base.wheel = new wheel({
+ el: map.el,
+ update: mousewheel,
+ })
+
+ function mousewheel (e, deltaY, deltaX){
+ map.set_zoom(map.zoom_exponent - deltaY/20)
+ }
+}
diff --git a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js
index 46c1d7f..9aff33f 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js
@@ -37,6 +37,7 @@
base.list = {}
base.regions = []
+ base.shapesMode = false
base.uid = new UidGenerator(base.list)
@@ -95,6 +96,7 @@
}
base.rebuild = function(walls_data){
+ if (base.shapesMode) return
walls_data = walls_data || Walls.serialize()
Rooms.clipper.update()
Rooms.builder.rebuild()
@@ -124,6 +126,45 @@
})
Rooms.rebuild(walls_data)
}
+
+ base.deserializeFromShapes = function(data, walls_data) {
+ walls_data = walls_data || Walls.serialize()
+ base.shapesMode = true
+ window.viewHeight = data.viewHeight || app.defaults.viewHeight
+ window.wallHeight = data.wallHeight || app.defaults.wallHeight
+ $(".units").val( data.units )
+
+ Rooms.builder.clear()
+
+ shapes.deserialize( data.shapes )
+ // shapes.build()
+ var regions = RegionList.build()
+
+ regions.forEach(function(region){
+ var room = new Room({
+ rect: region,
+ regions: [region],
+ height: wallHeight,
+ })
+
+ room.sides = region.sides
+ region.id = Rooms.uid("room_")
+ Rooms.list[ region.id ] = room
+ var mx_walls = Rooms.builder.build_walls(region)
+ room.mx_floor = Rooms.builder.make_floor(room, region)
+ room.mx_ceiling = Rooms.builder.make_ceiling(room, region)
+
+ mx_walls.forEach(function(mx){ scene.add(mx) })
+ scene.add(room.mx_floor)
+ scene.add(room.mx_ceiling)
+ })
+
+ Rooms.grouper.build()
+
+ Walls.paint()
+ Walls.deserialize(walls_data)
+ app.tube("rooms-built")
+ }
base.report = function(){
var data = []
diff --git a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js
index d52fe21..6203c20 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js
@@ -11,6 +11,7 @@ var Scenery = new function(){
base.init = function(){
base.resize.init()
+ base.sound.init()
}
base.add = function(opt){
@@ -113,6 +114,35 @@ var Scenery = new function(){
return added
}
+ base.rewindAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") scenery.seek(0)
+ })
+ }
+ base.playAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") {
+ scenery.unmute()
+ scenery.play()
+ }
+ })
+ }
+ base.pauseAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") scenery.pause()
+ })
+ }
+ base.muteAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") scenery.mx.mute()
+ })
+ }
+ base.unmuteAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") scenery.mx.unmute()
+ })
+ }
+
return base
}
diff --git a/public/assets/javascripts/rectangles/engine/scenery/move.js b/public/assets/javascripts/rectangles/engine/scenery/move.js
index f57ddba..94c6281 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/move.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/move.js
@@ -28,7 +28,7 @@ Scenery.move = function(base){
base.remove()
return
}
-
+
// load the modal
app.controller.pick(base)
@@ -75,13 +75,14 @@ Scenery.move = function(base){
switch (base.wall.side) {
case FRONT:
case BACK:
- base.mx.x = position.a + delta.a * cos(wall_rotation[base.wall.side]) + dimension.a / 2
+ base.mx.x = position.a + delta.a * cos(base.wall.rotationY) + dimension.a / 2
break
case LEFT:
case RIGHT:
- base.mx.z = position.a + delta.a * sin(wall_rotation[base.wall.side]) + dimension.a / 2
+ base.mx.z = position.a + delta.a * sin(base.wall.rotationY) + dimension.a / 2
break
}
+
if (editor.permissions.resize) {
Scenery.resize.move_dots()
}
@@ -104,7 +105,6 @@ Scenery.move = function(base){
dragging = moved = false
oldState = null
document.body.classList.remove("dragging")
-
}
function switch_wall (e, target, cursor){
diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js
index 5af7f3f..252af74 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/resize.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js
@@ -8,6 +8,7 @@ Scenery.resize = new function(){
var dragging = false
var naturalDimension, naturalDimensionCopy, dimension, position, scale
var oldState
+ var rotationY
var dots = [], dot, selected_dot
@@ -49,7 +50,8 @@ Scenery.resize = new function(){
// rotate the dots as appropriate
base.rotate_dots = function(){
- rotationY = wall_rotation[obj.wall.side]
+ // console.trace()
+ rotationY = obj.wall.rotationY
dots.forEach(function(dot){
dot.rotationY = rotationY
})
@@ -93,6 +95,7 @@ Scenery.resize = new function(){
base.add_dots()
base.rotate_dots()
base.move_dots()
+ Sculpture.resize.hide()
}
// dismiss the dots on blur
diff --git a/public/assets/javascripts/rectangles/engine/scenery/sound.js b/public/assets/javascripts/rectangles/engine/scenery/sound.js
new file mode 100644
index 0000000..5a783d6
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/scenery/sound.js
@@ -0,0 +1,16 @@
+
+Scenery.sound = {}
+Scenery.sound.max_distance = 1500
+Scenery.sound.init = function(){
+ app.tube.on("move", Scenery.sound.move)
+}
+Scenery.sound.move = function(){
+ Scenery.forEach(function(scenery){
+ if ((scenery.type == "video" || scenery.type == "audio")) { // && ! scenery.muted()) {
+ var distance = dist(cam.x, cam.z,
+ scenery.mx.x, scenery.mx.z)
+ var volume = 1 - (clamp( distance, 0, Scenery.sound.max_distance ) / Scenery.sound.max_distance)
+ scenery.setVolume(volume)
+ }
+ })
+}
diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js
index cd3f981..e3b9b4d 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js
@@ -90,11 +90,11 @@ Scenery.types.base = Fiber.extend(function(base){
switch (this.wall.side) {
case FRONT:
case BACK:
- this.position.a += delta.a * cos(wall_rotation[this.wall.side])
+ this.position.a += delta.a * cos(this.wall.rotationY)
break
case LEFT:
case RIGHT:
- this.position.a += delta.a * sin(wall_rotation[this.wall.side])
+ this.position.a += delta.a * sin(this.wall.rotationY)
break
}
},
diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/audio.js b/public/assets/javascripts/rectangles/engine/scenery/types/audio.js
index 82f984e..fdd221d 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/types/audio.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/types/audio.js
@@ -39,6 +39,10 @@ Scenery.types.audio = Scenery.types.base.extend(function(base){
this.dimensions.deserialize(data.dimensions)
},
+ setVolume: function(n){
+ this.mx.setVolume(n)
+ },
+
play: function(){
this.mx.play()
},
diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/video.js b/public/assets/javascripts/rectangles/engine/scenery/types/video.js
index d1b1763..163e19e 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/types/video.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/types/video.js
@@ -38,7 +38,8 @@ Scenery.types.video = Scenery.types.base.extend(function(base){
backface: false,
})
scene.add(this.mx)
- this.mx.load()
+
+ this.mx.load()
},
play: function(){
@@ -90,6 +91,14 @@ Scenery.types.video = Scenery.types.base.extend(function(base){
}
},
+ unmute: function(){
+ this.mx.unmute()
+ },
+
+ setVolume: function(n){
+ this.mx.setVolume(n)
+ },
+
serialize: function(){
var data = base.serialize.call(this)
return data
diff --git a/public/assets/javascripts/rectangles/engine/scenery/undo.js b/public/assets/javascripts/rectangles/engine/scenery/undo.js
index 1232780..b976ea2 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/undo.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/undo.js
@@ -195,5 +195,70 @@
},
},
+ //
+ {
+ type: "create-sculpture",
+ undo: function(state){
+ Sculpture.remove(state.id)
+ Sculpture.resize.hide()
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ redo: function(state){
+ var scenery = Sculpture.deserialize([ state ])
+ Sculpture.resize.show( sculpture )
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+ {
+ type: "update-sculpture",
+ undo: function(state){
+ var sculpture = Sculpture.find(state.id)
+
+ sculpture.deserialize(state)
+
+ if (editor.permissions.resize) {
+ Sculpture.resize.show(sculpture)
+ }
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ redo: function(state){
+ var sculpture = Sculpture.find(state.id)
+
+ sculpture.deserialize(state)
+
+ if (editor.permissions.resize) {
+ Sculpture.resize.show(sculpture)
+ Sculpture.resize.move_dots()
+ Sculpture.resize.rotate_dots()
+ }
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+ {
+ type: "destroy-sculpture",
+ undo: function(state){
+ var sculpture = Sculpture.deserialize([ state ])
+ Sculpture.resize.show( sculpture )
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ redo: function(state){
+ Sculpture.resize.hide()
+ Sculpture.remove(state.id)
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+
])
})()
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js
new file mode 100644
index 0000000..888b925
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js
@@ -0,0 +1,105 @@
+
+var Sculpture = new function(){
+
+ var base = this;
+
+ base.list = {}
+
+ base.mouse = new mouse ({ use_offset: false, mousedownUsesCapture: true })
+
+ base.init = function(){
+ app.on("move", base.updateBillboards)
+ base.resize.init()
+ }
+
+ base.updateBillboards = function(){
+ base.forEach(function(sculpture){
+ if (sculpture.billboard) {
+ sculpture.mx.rotationY = cam.rotationY
+ }
+ })
+ if (Sculpture.resize.obj && Sculpture.resize.obj.billboard) {
+ Sculpture.resize.move_dots()
+ }
+ }
+
+ base.add = function(opt){
+ var sculpture
+ switch (opt.media.type) {
+ case 'image':
+ sculpture = new Sculpture.types.image (opt)
+ break
+ }
+ base.list[sculpture.id] = sculpture
+ return sculpture
+ }
+
+ base.addNext = function(opt){
+ opt.newMedia = true
+ opt.media = Scenery.nextMedia
+ var sculpture = base.add(opt)
+
+ // test if sculpture was placed here
+ if (! sculpture) {
+ return null
+ }
+ else {
+ Scenery.nextMedia = null
+ return sculpture
+ }
+ }
+
+ base.find = function(id){
+ return base.list[id] || null
+ }
+
+ base.remove = function(id){
+ var scene_media = base.list[id]
+ delete base.list[id]
+ scene_media && scene_media.destroy()
+ }
+
+ base.removeAll = function(){
+ base.forEach(function(scene_media){
+ base.remove(scene_media.id)
+ })
+ }
+
+ base.uid = new UidGenerator(base.list)
+
+ base.forEach = function(f){
+ return base.values().forEach(f)
+ }
+
+ base.map = function(f){
+ return base.values().map(f)
+ }
+
+ base.values = function(){
+ return _.values(base.list)
+ }
+
+ base.serialize = function(){
+ var sculptures = base.map(function(sculpture){
+ return sculpture.serialize()
+ })
+ return sculptures
+ }
+
+ base.deserialize = function(sculpture_data){
+ var added = []
+ sculpture_data.forEach(function(data){
+ var scene_media = base.add({
+ id: data.id,
+ data: data,
+ media: data.media,
+ })
+ added.push(scene_media)
+ })
+ return added
+ }
+
+ return base
+}
+
+Sculpture.types = {}
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/move.js b/public/assets/javascripts/rectangles/engine/sculpture/move.js
new file mode 100644
index 0000000..0cbeccd
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/move.js
@@ -0,0 +1,111 @@
+
+Sculpture.move = function(base){
+
+ var x, y, z, position, dimension, bounds
+ var rotationY
+ var dragging = false, altPressed = false, shiftPressed = false, moved = false
+ var oldState
+ var height, width
+
+ this.bind = function(){
+ Sculpture.mouse.bind_el(base.mx.el)
+ Sculpture.mouse.on("down", down)
+ Sculpture.mouse.on("drag", drag)
+ Sculpture.mouse.on("up", up)
+ }
+
+ this.unbind = function(){
+ base.focused = false
+ Sculpture.mouse.unbind_el(base.mx.el)
+ Sculpture.mouse.off("down", down)
+ Sculpture.mouse.off("drag", drag)
+ Sculpture.mouse.off("up", up)
+ }
+
+ function down (e, cursor){
+ if (e.target != base.mx.el && (e.target != base.mx.overlay)) return;
+ if (editor.permissions.destroy) {
+ base.remove()
+ return
+ }
+
+ // load the modal
+ app.controller.pick(base)
+
+ if (! base.focused) {
+ e.clickAccepted = false
+ base.focused = true
+ return
+ }
+ if (! (editor.permissions.move || editor.permissions.resize) ) {
+ e.clickAccepted = false
+ return
+ }
+ altPressed = (e.altKey && ! base.billboard)
+ shiftPressed = e.shiftKey
+ dragging = true
+ moved = false
+ x = base.mx.x
+ y = base.mx.y
+ z = base.mx.z
+ rotationY = base.mx.rotationY
+ height = base.mx.height * base.mx.scale
+
+ bounds = base.bounds
+ dimension = base.dimensions
+
+ oldState = base.serialize()
+ document.body.classList.add("dragging")
+ }
+
+ function drag (e, cursor){
+ if (! dragging) return
+
+ moved = true
+
+ var delta = cursor.delta()
+ delta.mul( cursor_amp ) // TODO: this should be proportional to your distance from the wall
+ delta.b *= -1
+
+ // here we need to move the element based on the XY coords, as
+ // base.mx.y = position.b + delta.b + dimension.b / 2
+ if (shiftPressed) {
+ base.mx.y = clamp( y + delta.b, height/2 + sculpture_distance_from_floor, Infinity )
+ }
+ else if (altPressed) {
+ base.mx.rotationY = mod( rotationY + delta.a / (window.innerWidth / 2) , TWO_PI )
+ Sculpture.resize.move_dots()
+ }
+ else {
+ base.mx.x = x + delta.a * cos(cam.rotationY) - delta.b * sin(cam.rotationY)
+ base.mx.z = z + delta.a * sin(cam.rotationY) + delta.b * cos(cam.rotationY)
+ }
+
+ if (editor.permissions.resize) {
+ Sculpture.resize.move_dots()
+ base.updateOutline()
+ }
+ }
+
+ function up (e, cursor){
+ if (! dragging || ! oldState) return
+
+ if (moved) {
+ UndoStack.push({
+ type: 'update-sculpture',
+ undo: oldState,
+ redo: base.serialize(),
+ })
+
+ // TODO: watch individual sculpture object here
+ Minotaur.watch( app.router.editorView.settings )
+ }
+
+ dragging = moved = false
+ oldState = null
+ document.body.classList.remove("dragging")
+ }
+
+ return this
+
+} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/resize.js b/public/assets/javascripts/rectangles/engine/sculpture/resize.js
new file mode 100644
index 0000000..5f21d66
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/resize.js
@@ -0,0 +1,208 @@
+Sculpture.resize = new function(){
+
+ var base = this
+
+ var obj
+ var x, y, z, bounds
+ var dragging = false
+ var naturalDimension, naturalDimensionCopy, dimension, position, scale
+ var oldState
+ var rotationY
+
+ var dots = [], dot, selected_dot
+
+ base.init = function(){
+ base.build()
+ base.bind()
+ }
+
+ // create 9 dots at the corners of the div
+ base.build = function(){
+ [ TOP,
+ TOP_RIGHT,
+ RIGHT,
+ BOTTOM_RIGHT,
+ BOTTOM,
+ BOTTOM_LEFT,
+ LEFT,
+ TOP_LEFT ].forEach(base.build_dot)
+ }
+
+ // generate a dot element
+ base.build_dot = function(side) {
+ var dot = new MX.Object3D('.dot')
+ dot.width = dot.height = dot_side * 2
+ dot.scale = 0.5
+ dot.side = side
+ $(dot.el).on({
+ mouseenter: function(){ base.hovering = true },
+ mouseleave: function(){ base.hovering = false },
+ })
+ dots.push(dot)
+ }
+
+ base.add_dots = function(){
+ dots.forEach(function(dot){
+ scene.add(dot)
+ })
+ }
+
+ // move all the dots to the object's current position
+ base.move_dots = function(){
+ rotationY = obj.mx.rotationY
+
+ var x = obj.mx.x + sin(rotationY) * dot_distance_from_picture
+ var y = obj.mx.y
+ var z = obj.mx.z - cos(rotationY) * dot_distance_from_picture
+
+ dots.forEach(function(dot){
+ base.move_dot(dot, { x: x, y: y, z: z, rotationY: rotationY })
+ })
+ }
+
+ // move a dot .. to the initial position of the image
+ base.move_dot = function(dot, pos){
+ if (dot.side & TOP) {
+ pos.y += obj.dimensions.b / 2
+ }
+ if (dot.side & BOTTOM) {
+ pos.y -= obj.dimensions.b / 2
+ }
+ if (dot.side & LEFT) {
+ pos.x -= cos(rotationY) * (obj.dimensions.a) / 2
+ pos.z -= sin(rotationY) * (obj.dimensions.a) / 2
+ }
+ if (dot.side & RIGHT) {
+ pos.x += cos(rotationY) * (obj.dimensions.a) / 2
+ pos.z += sin(rotationY) * (obj.dimensions.a) / 2
+ }
+ dot.move(pos)
+ }
+
+ // pick a new object to focus on and show the dots
+ base.show = function(new_object) {
+ // if (obj === new_object) return
+ if (! new_object) return
+ base.obj = obj = new_object
+ base.add_dots()
+ base.move_dots()
+ }
+
+ // dismiss the dots on blur
+ var dotsHideTimeout;
+ base.defer_hide = function(){
+ clearTimeout(dotsHideTimeout)
+
+ dotsHideTimeout = setTimeout(function(){
+ if (Scenery.hovering || Scenery.resize.hovering || Scenery.mouse.down) return
+ Scenery.resize.hide()
+ }, dot_hide_delay)
+ }
+
+ base.hide = function () {
+ if (! obj) return
+ base.obj = obj = null
+ dots.forEach(function(dot){
+ scene.remove(dot)
+ })
+ }
+
+ base.bind = function(){
+ dots.forEach(function(dot){
+ Sculpture.mouse.bind_el(dot.el)
+ })
+ Sculpture.mouse.on("down", down)
+ Sculpture.mouse.on("drag", drag)
+ Sculpture.mouse.on("up", up)
+ }
+
+ base.unbind = function(){
+ dots.forEach(function(dot){
+ Sculpture.mouse.unbind_el(dot.el)
+ })
+ Sculpture.mouse.off("down", down)
+ Sculpture.mouse.off("drag", drag)
+ Sculpture.mouse.off("up", up)
+ }
+
+ function down (e, cursor){
+ var selection = dots.filter(function(dot){return e.target == dot.el})
+ if (! selection.length) return
+
+ selected_dot = selection[0]
+ dragging = true
+
+ naturalDimension = obj.naturalDimensions
+ dimension = obj.dimensions
+ position = new vec3(obj.mx.x, obj.mx.y, obj.mx.z)
+ oldState = obj.serialize()
+
+ if (obj.type == "text") {
+ naturalDimensionCopy = naturalDimension.clone()
+ positionCopy = position.clone()
+ }
+
+ document.body.classList.add("dragging")
+ }
+
+ function drag (e, cursor){
+ if (! dragging) return
+
+ var x_sign = selected_dot.side & LEFT ? -1 : selected_dot.side & RIGHT ? 1 : 0
+ var y_sign = selected_dot.side & TOP ? -1 : selected_dot.side & BOTTOM ? 1 : 0
+ var width = cursor.x.magnitude()
+ var height = cursor.y.magnitude()
+ var mag = cursor.magnitude()
+
+ if (abs(width) > abs(height)) {
+ mag = x_sign * mag * sign(width)
+ }
+ else {
+ mag = y_sign * mag * sign(height)
+ }
+
+ if (obj.type == "text") {
+ obj.mx.width = obj.media.width = naturalDimension.a = naturalDimensionCopy.a + (mag * 2)
+ obj.mx.height = obj.media.height = naturalDimension.b = naturalDimensionCopy.b + (mag * 2)
+ dimension.a = naturalDimension.a * obj.scale
+ dimension.b = naturalDimension.b * obj.scale
+ }
+ else {
+ obj.set_scale( ( dimension.a + mag ) / naturalDimension.a )
+ }
+
+ if (selected_dot.side & LEFT_RIGHT) {
+ obj.mx.x = position.a + cos(rotationY) * mag/2 * (x_sign)
+ obj.mx.z = position.c + sin(rotationY) * mag/2 * (x_sign)
+ }
+ if (selected_dot.side & TOP_BOTTOM) {
+ obj.mx.y = position.b - mag/2 * y_sign
+ }
+
+ base.move_dots()
+ obj.updateOutline()
+
+ app.controller.sculptureEditor.setDimensions()
+ }
+
+ function up (e, cursor){
+ if (! dragging) return
+ dragging = false
+ if (! editor.permissions.resize) { return }
+
+ obj.scale = obj.mx.ops.scale = obj.mx.scale
+ obj.dimensions.assign(obj.naturalDimensions).mul(obj.scale)
+
+ UndoStack.push({
+ type: 'update-sculpture',
+ undo: oldState,
+ redo: obj.serialize(),
+ })
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+
+ document.body.classList.remove("dragging")
+ selected_dot = null
+ }
+} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js
new file mode 100644
index 0000000..2f593e8
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js
@@ -0,0 +1,176 @@
+Sculpture.types.base = Fiber.extend(function(base){
+
+ var exports = {
+
+ init: function(opt){
+ this.id = opt.id || Sculpture.uid("sculpture")
+ // this.move = new Sculpture.move (this)
+ this.media = opt.media
+ this.naturalDimensions = new vec3(this.media.width, this.media.height, this.media.width)
+ this.dimensions = new vec3(this.media.width, this.media.height, this.media.width)
+
+ this.move = new Sculpture.move (this)
+ this.billboard = true
+ this.backface = true
+
+ this.set_scale( opt.scale || this.media.scale || 1.0 )
+ this.position = new vec2(0,0)
+
+ this.isSculpture = true
+ },
+
+ set_scale: function(scale){
+ this.scale = scale || 1.0
+ if (this.mx) {
+ this.mx.scale = this.mx.ops.scale = this.scale
+ }
+ this.dimensions = this.naturalDimensions.clone().mul(this.scale)
+ },
+ set_depth: function(depth){
+ console.log(this.dimensions.c, this.naturalDimensions.c, depth)
+ this.dimensions.c = depth
+ this.naturalDimensions.c = depth / this.scale
+ },
+
+ place: function(opt){
+ if (opt.data) {
+ this.deserialize(opt.data)
+ }
+ else {
+ this.mx.move(opt.position)
+ }
+ },
+
+ bind: function(){
+ this.move.bind()
+ },
+
+ unbind: function(){
+ this.move.unbind()
+ },
+
+ setOutline: function(val){
+ this.outline = val
+ if (val && ! this.outlineEl) {
+ this.buildOutline()
+ }
+ this.outlineEl.el.style.display = val ? "block" : "none"
+ },
+ setOutlineColor: function(val){
+ this.outlineColor = val
+ if (this.outlineEl) {
+ this.outlineColor = this.outlineEl.el.style.borderColor = val
+ }
+ },
+ setBillboard: function(val){
+ this.billboard = val
+ if (this.billboard) {
+ this.mx.el.classList.add("backface-hidden")
+ this.mx.el.classList.remove("backface-visible")
+ this.mx.rotationY = cam.rotationY
+ }
+ else {
+ this.mx.el.classList.add("backface-visible")
+ this.mx.el.classList.remove("backface-hidden")
+ this.mx.rotationY = quantize(cam.rotationY, PI/2)
+ }
+ Sculpture.resize.move_dots()
+ },
+
+ buildOutline: function(){
+ this.outlineEl = new MX.Object3D(".mx-outline")
+ this.outlineEl.width = this.naturalDimensions.a
+ this.outlineEl.height = this.naturalDimensions.c
+ this.outlineEl.scale = this.mx.scale
+ this.outlineEl.rotationX = -PI/2
+ this.outlineEl.x = this.mx.x
+ this.outlineEl.y = sculpture_distance_from_floor
+ this.outlineEl.z = this.mx.z
+ this.outlineEl.el.style.borderColor = this.outlineColor || "#000000"
+ scene.add(this.outlineEl)
+ },
+ updateOutline: function(){
+ if (! this.outline) { return }
+ if (! this.outlineEl) {
+ this.buildOutline()
+ }
+ this.outlineEl.x = this.mx.x
+ this.outlineEl.y = sculpture_distance_from_floor
+ this.outlineEl.z = this.mx.z
+ this.outlineEl.width = this.naturalDimensions.a
+ this.outlineEl.height = this.naturalDimensions.c
+
+ this.outlineEl.scale = this.mx.scale
+ },
+
+ remove: function(){
+ if (this.removed) return
+ this.removed = true
+
+ UndoStack.push({
+ type: 'destroy-sculpture',
+ undo: this.serialize(),
+ redo: { id: this.id },
+ })
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+
+ Sculpture.remove(this.id)
+
+ Sculpture.resize.hide()
+ if (app.controller.sculptureEditor) {
+ app.controller.sculptureEditor.tainted = false
+ app.controller.sculptureEditor.hide()
+ }
+ },
+
+ destroy: function(){
+ this.unbind()
+ scene.remove(this.mx)
+ this.mx.media = null
+ this.mx.ops = null
+ this.mx = null
+ this.move = null
+ this.media = null
+ this.dimensions = null
+ this.naturalDimensions = null
+ this.wall = null
+ this.bounds = null
+ this.center = null
+ },
+
+ serialize: function(){
+ var data = {
+ id: this.id,
+ dimensions: this.dimensions.serialize(),
+ position: app.position(this.mx),
+ scale: this.scale,
+ media: this.media,
+ billboard: this.billboard,
+ outline: this.outline,
+ outlineColor: this.outlineColor || "#000000",
+ backface: this.backface,
+ }
+ return data
+ },
+
+ deserialize: function(data){
+ this.mx.move(data.position)
+ this.mx.ops.width = data.dimensions.a
+ this.mx.ops.height = data.dimensions.b
+ this.billboard = data.billboard
+ this.outline = data.outline
+ this.outlineColor = data.outlineColor || "#000000"
+ this.backface = data.backface
+ if (! this.backface) this.mx.el.classList.remove("backface-visible")
+ this.dimensions.deserialize(data.dimensions)
+ if (this.outline) {
+ this.buildOutline()
+ }
+ },
+ }
+
+ return exports
+
+})
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/image.js b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js
new file mode 100644
index 0000000..1a53f5b
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js
@@ -0,0 +1,38 @@
+
+Sculpture.types.image = Sculpture.types.base.extend(function(base){
+
+ var exports = {
+
+ type: 'image',
+
+ init: function(opt){
+
+ opt.scale = opt.scale || (opt.data && opt.data.scale) || DEFAULT_PICTURE_WIDTH / max(DEFAULT_PICTURE_WIDTH, opt.media.width)
+
+ base.init.call(this, opt)
+
+ this.build(opt)
+ this.bind()
+ this.place(opt)
+ },
+
+ build: function(opt){
+ this.mx = new MX.Image({
+ src: this.media.url,
+ scale: this.scale,
+ media: this.media,
+ backface: true,
+ })
+
+ if (opt.position) {
+ opt.position.y = opt.position.y || this.scale * this.media.height/2 + sculpture_distance_from_floor
+ opt.position.rotationY = opt.position.rotationY || scene.camera.rotationY
+ }
+
+ scene.add( this.mx )
+ },
+
+ }
+
+ return exports
+})
diff --git a/public/assets/javascripts/rectangles/engine/shapes/ortho.js b/public/assets/javascripts/rectangles/engine/shapes/ortho.js
new file mode 100644
index 0000000..163f646
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/ortho.js
@@ -0,0 +1,66 @@
+// An OrthoPolyline is a Polyline where all angles are 90 degrees.
+
+if (! ('window' in this) ) {
+ var Polyline = require("./polyline.js")
+}
+
+var OrthoPolyline = Polyline.extend(function(base){
+ var exports = {}
+ exports.type = function(){
+ return "ortho"
+ }
+ exports.instantiate = function(){
+ return new OrthoPolyline
+ }
+ exports.canCloseWith = function(p){
+ return (this.points.length > 2 && this.points[0].distanceTo( p ) < 10/map.zoom)
+ }
+ exports.draw = function(ctx, fillStyle, strokeStyle){
+ var points = this.points
+ if (! points.length) return
+ if (points.length == 1) {
+ ctx.fillStyle = "#f80"
+ map.draw.dot_at(this.points[0].a, points[0].b, 5)
+ }
+ if (points.length > 1) {
+ ctx.fillStyle = fillStyle
+ ctx.strokeStyle = strokeStyle
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[0].a, points[0].b)
+ points.forEach(function(point, i){
+ i && ctx.lineTo(point.a, point.b)
+ })
+ strokeStyle && ctx.stroke()
+ if (! map.ui.placing || this.closed) {
+ fillStyle && ctx.fill()
+ }
+ }
+ }
+ exports.translateSegment = function(src, dest, dx, dy) {
+ if (src[0].a == src[1].a) {
+ dest[0].a = src[0].a + dx
+ dest[1].a = src[1].a + dx
+ if (src.length == 3) {
+ dest[2].a = src[2].a + dx
+ }
+ }
+ else {
+ dest[0].b = src[0].b + dy
+ dest[1].b = src[1].b + dy
+ if (src.length == 3) {
+ dest[2].b = src[2].b + dy
+ }
+ }
+ }
+ exports.close = function(){
+ this.points[this.points.length] = this.points[0]
+ this.closed = true
+ }
+ return exports
+})
+
+
+if (! ('window' in this) ) {
+ module.exports = OrthoPolyline
+}
diff --git a/public/assets/javascripts/rectangles/engine/shapes/polyline.js b/public/assets/javascripts/rectangles/engine/shapes/polyline.js
new file mode 100644
index 0000000..b2cd92f
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/polyline.js
@@ -0,0 +1,212 @@
+// A Polyline is a set of points inputted by the user using the V2 editor to trace a blueprint.
+// Additionally, it manages a set of MX objects which correspond to the walls in 3D.
+// In this way, it attempts to bridge the 2D (canvas, imperative) and 3D (css, declarative) views.
+
+if (! ('window' in this) ) {
+ var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js")
+ var vec2 = require("../../models/vec2")
+}
+
+var Polyline = Fiber.extend(function(base){
+ var exports = {}
+ exports.init = function(){
+ this.points = []
+ this.mx_points = []
+ this.closed = false
+ }
+ exports.type = function(){
+ return "polyline"
+ }
+ exports.instantiate = function(){
+ return new Polyline
+ }
+ exports.add = function(p){
+ this.points.push( p )
+ this.mx_points.push( new MX.Point(p) )
+ }
+ exports.firstPoint = function(){
+ return this.points[0]
+ }
+ exports.lastPoint = function(){
+ return this.points[this.points.length-1]
+ }
+ exports.canCloseWith = function(p){
+ return (this.points.length > 2 && this.points[0].distanceTo( p ) < 10/map.zoom)
+ }
+ exports.getHeadAtIndex = function(index){
+ if (index == 0) { return null }
+ if (index == this.points.length-1) { return this.clone() }
+ var head = this.instantiate()
+ head.points = this.points.slice(0, index+1)
+ return head
+ }
+ exports.getTailAtIndex = function(index){
+ if (index == this.points.length-1) { return null }
+ if (index == 0) { return this.clone() }
+ var tail = this.instantiate()
+ tail.points = this.points.slice(index, this.points.length)
+ return tail
+ }
+ exports.clone = function(){
+ var clone = this.instantiate()
+ clone.points = this.points.concat()
+ }
+ exports.getSegment = function(segment){
+ var seg = [
+ this.points[segment.head],
+ this.points[segment.tail],
+ ]
+ if (segment.head == 0) {
+ seg.push( this.lastPoint() )
+ }
+ else if (segment.tail == this.points.length-1) {
+ seg.push( this.firstPoint() )
+ }
+ return seg
+ }
+ exports.cloneSegment = function(segment){
+ return this.getSegment(segment).map(function(point){ return point.clone() })
+ }
+ exports.translateSegment = function(src, dest, dx, dy){
+ dest[0].a = src[0].a + dx
+ dest[0].b = src[0].b + dy
+ dest[1].a = src[1].a + dx
+ dest[1].b = src[1].b + dy
+ if (src.length == 3) {
+ dest[2].a = src[2].a + dx
+ dest[2].b = src[2].b + dy
+ }
+ }
+ exports.hasPointNear = function(p){
+ var point
+ for (var i = 0; i < this.points.length; i++){
+ point = this.points[i]
+ if (point.distanceTo( p ) < 10/map.zoom) {
+ return point
+ }
+ }
+ return null
+ }
+ exports.hasEndPointNear = function(p){
+ if (this.closed || ! this.points.length) return null
+ if (this.firstPoint().distanceTo( p ) < 10/map.zoom) {
+ return this.firstPoint()
+ }
+ if (this.lastPoint().distanceTo( p ) < 10/map.zoom) {
+ return this.lastPoint()
+ }
+ return null
+ }
+ exports.hasSegmentNear = function(p, min_dist){
+ var p1, p2, d1, d2, sum, rat
+ var dx, dy, new_x, new_y, x, y, closest_distance = min_dist || Infinity
+ var closest_i = -1
+ var points = this.points
+ var p1, p2 = points[0]
+ for (var i = 1; i < points.length; i++) {
+ p1 = p2
+ p2 = points[i]
+ d1 = p2.a - p1.a
+ d2 = p2.b - p1.b
+ sum = d1*d1 + d2*d2
+ rat = ((p.a - p1.a) * d1 + (p.b - p1.b) * d2) / sum
+ rat = rat < 0 ? 0 : rat < 1 ? rat : 1
+ new_x = p1.a + rat * d1
+ new_y = p1.b + rat * d2
+ dx = new_x - p.a
+ dy = new_y - p.b
+ sum2 = sqrt(dx*dx+dy*dy)
+ if (sum2 < closest_distance) {
+ x = new_x
+ y = new_y
+ closest_distance = sum2
+ closest_i = i
+ }
+ }
+ if (closest_i == -1) return null
+ return {
+ x: x,
+ y: y,
+ distance: closest_distance,
+ head: closest_i-1,
+ tail: closest_i,
+ }
+ }
+ exports.draw = function(ctx, fillStyle, strokeStyle){
+ var points = this.points
+ if (! points.length) return
+ if (points.length == 1) {
+ ctx.fillStyle = "#f80"
+ map.draw.dot_at(this.points[0].a, points[0].b, 5)
+ }
+ if (points.length > 1) {
+ ctx.fillStyle = fillStyle
+ ctx.strokeStyle = strokeStyle
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[0].a, points[0].b)
+ points.forEach(function(point, i){
+ i && ctx.lineTo(point.a, point.b)
+ })
+ strokeStyle && ctx.stroke()
+ if (! map.ui.placing || this.closed) {
+ fillStyle && ctx.fill()
+ }
+ }
+ }
+ exports.draw_line = function (ctx, p){
+ var last = this.points[this.points.length-1]
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(last.a, last.b)
+ ctx.lineTo(p.a, p.b)
+ ctx.stroke()
+ }
+ exports.close = function(){
+ this.points[this.points.length] = this.points[0]
+ this.closed = true
+ }
+ exports.build = function(){
+ this.mx_points && this.mx_points.forEach(function(mx){ scene.remove(mx) })
+ this.mx = new MX.Polyline(this)
+ }
+ exports.rebuild = function(){
+ this.mx.rebuild()
+ }
+ exports.getSegments = function(){
+ if (this.points.length == 1) {
+ return []
+ }
+ var segments = []
+ for (var i = 1; i < this.points.length; i++) {
+ segments.push( [ this.points[i-1], this.points[i] ] )
+ }
+ return segments
+ }
+ exports.serialize = function(){
+ return {
+ type: this.type(),
+ closed: this.closed,
+ points: this.points.map(function(point){ return [point.a, point.b] }),
+ }
+ }
+ exports.deserialize = function(data){
+ this.closed = data.closed || false
+ this.points = (data.points || data).map(function(point){ return new vec2(point[0], point[1]) })
+ }
+ exports.reset = function(){
+ this.mx_points.forEach(function(mx){ scene.remove(mx) })
+ this.mx_points.length = 0
+ this.points.length = 0
+ }
+ exports.destroy = function(){
+ this.reset()
+ this.mx && this.mx.destroy()
+ }
+ return exports
+})
+
+if (! ('window' in this) ) {
+ module.exports = Polyline
+}
diff --git a/public/assets/javascripts/rectangles/engine/shapes/regionlist.js b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js
new file mode 100644
index 0000000..8c9e732
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js
@@ -0,0 +1,240 @@
+// This algorithm takes the polylines from ShapeList as input and produces
+// a set of Rooms which can be used by the existing V1 mover and editor.
+
+// The algorithm assumes that
+// 1) all angles are orthogonal
+// 2) all polylines are closed
+
+if (! ('window' in this) ) {
+ var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js")
+ var vec2 = require("../../models/vec2")
+ var Rect = require("../../models/rect")
+ var sort = require("../../util/sort")
+}
+
+var RegionList = (function(){
+
+ var RegionList = {}
+ var regions = RegionList.regions
+
+ // Build a list of regions from the existing shapes.
+ // Operates on all the shapes at once.
+ RegionList.build = function(){
+ var segments = RegionList.getSortedSegments()
+ return RegionList.buildRoomsFromSegments(segments)
+ }
+
+ // Build a list of regions from the individual shapes.
+ // Same, but operates on the shapes individually
+ RegionList.buildByShape = function(){
+ var shapes = RegionList.getSortedSegmentsByShape()
+ var region_lists = shapes.map(function(shape){
+ return RegionList.buildRoomsFromSegments(shape.segments)
+ })
+ var regions = []
+ return regions.concat.apply(regions, region_lists);
+ }
+
+ RegionList.buildRoomsFromSegments = function(segments){
+
+ var rooms = []
+ var seen_rooms = {}
+ var open_segments = []
+
+ var segment, open_segment, x_segment, y_segments, overlapped, seen_segments
+
+ // first pass: generate rooms from the vertical segments only
+ for (var i = 0; i < segments.length; i++) {
+ segment = segments[i]
+ if (! segment.isVertical()) {
+ continue
+ }
+
+ // check all the "open segments" we know about, i.e. rooms where we've only found
+ // the right wall.
+ overlapped = false
+ for (var j = 0; j < open_segments.length; j++) {
+ open_segment = open_segments[j]
+
+ // if these two segments overlap each other, then there is a room between them.
+ if (segment.y.overlaps(open_segment.y)) {
+ overlapped = true
+ open_segments.splice(j--, 1)
+
+ // the X part of the room will be the span between these two vertical segments'
+ // X components. the Y part of the room is the "split" or subdivision between
+ // the two horizontal vectors.
+
+ // the split function is non-commutative,
+ // so we need to call A split B and B split A,
+ // then dedupe the segments we got back..
+ x_segment = new vec2( open_segment.x.a, segment.x.b )
+ y_segments = open_segment.y.split(segment.y, 0, 0)
+
+ seen_segments = {}
+
+ // check each of the splits.. if the two segments overlap, then we definitely
+ // have a room here.
+ y_segments.forEach(function(seg){
+ seen_segments[ seg[0]+"" ] = true
+ var room = new Rect( x_segment, seg[0] )
+
+ if (seen_rooms[ room+"" ]) return
+ seen_rooms[ room+"" ] = true
+
+ room.sides = 0
+
+ rooms.push(room)
+ var new_seg = new Rect( segment.x, seg[0] )
+ open_segments.unshift(new_seg)
+ j++
+ })
+
+ // splitting the other way..
+ y_segments = segment.y.split(open_segment.y, 0, 0)
+ y_segments.forEach(function(seg){
+ if (seen_segments[ seg[0]+"" ]) return;
+ var new_seg = new Rect( segment.x, seg[0] )
+ open_segments.unshift(new_seg)
+ j++
+ })
+ }
+ }
+
+ // if we have overlap, then re-sort the open segments Y-wise
+ // and (again) dedupe..
+ if (overlapped) {
+ open_segments = open_segments.sort(function(a,b){
+ if (a.y.a < b.y.a) { return -1 }
+ if (a.y.a == b.y.a) { return 0 }
+ if (a.y.a > b.y.a) { return 1 }
+ })
+
+ if (open_segments.length < 2) { continue }
+
+ for (var k = 1; k < open_segments.length; k++) {
+ if (open_segments[k-1].y.containsVec(open_segments[k].y)) {
+ open_segments.splice(k--, 1)
+ }
+ else if (open_segments[k-1].y.overlaps(open_segments[k].y)) {
+ open_segments[k].y = open_segments[k].y.clone()
+ open_segments[k].y.a = open_segments[k-1].y.b
+ }
+ }
+ }
+ // if we don't have any overlap, then this is a new open segment.
+ else {
+ open_segments.push(segment)
+ }
+ }
+
+ var splits, splitter
+
+ // second pass: now that we have a bunch of rooms, assign sides to all of them.
+ // sides are used in the "mover" script to do bounds checking.
+ for (var i = 0; i < segments.length; i++) {
+ segment = segments[i]
+ var horizontal = segment.isHorizontal(), vertical = segment.isVertical()
+ for (var r = 0; r < rooms.length; r++){
+ room = rooms[r]
+
+ // vertical segments determine the left and right edges of the room, fairly simply.
+ if (vertical) {
+ if (segment.y.containsVec(room.y)) {
+ if (segment.x.a == room.x.a) {
+ room.sides |= LEFT
+ }
+ if (segment.x.a == room.x.b) {
+ room.sides |= RIGHT
+ }
+ }
+ }
+
+ // horizontal segments determine the front and back edges of the room.
+ if (horizontal) {
+ if (segment.x.containsVec(room.x)) {
+ if (segment.y.a == room.y.a) {
+ room.sides |= FRONT
+ }
+ if (segment.y.a == room.y.b) {
+ room.sides |= BACK
+ }
+ }
+
+ // however, since we did not split on horizontal segments, our rooms may
+ // only have partial overlap with these segments, in which case we need to
+ // split the rooms apart.
+ else if ((segment.y.a == room.y.a || segment.y.a == room.y.b) && room.x.overlaps(segment.x)) {
+
+ // split the room across the segment. preserve whether or not we know the
+ // room borders a segment on the left or right.
+ splits = room.x.split(segment.x, room.sides & LEFT, room.sides & RIGHT)
+ rooms.splice(r--, 1)
+ for (var k = 0; k < splits.length; k++) {
+ splitter = splits[k]
+ var new_room = new Rect( splitter[0], room.y )
+ new_room.sides = splitter[1] | ( room.sides & FRONT_BACK )
+ if (segment.x.overlaps( splitter[0] )) {
+ if (segment.y.a == new_room.y.a) {
+ new_room.sides |= FRONT
+ }
+ if (segment.y.a == new_room.y.b) {
+ new_room.sides |= BACK
+ }
+ }
+ rooms.unshift(new_room)
+ r++
+ }
+ }
+
+ }
+ }
+ }
+
+ return rooms
+ }
+
+ // Gets a list of polylines from the ShapeList and sorts the segments.
+ RegionList.getSortedSegments = function(){
+ // get a list of all segments from these polylines
+ var segments = shapes.getAllSegments()
+
+ segments = segments.map(RegionList.segmentsToRects)
+
+ return sort.rects_by_position(segments)
+ }
+
+ RegionList.getSortedSegmentsByShape = function(){
+ return shapes.getAllShapeSegments().map(function(shape){
+ var segments = shape.map(RegionList.segmentsToRects)
+ return {
+ shape: shape,
+ segments: sort.rects_by_position(segments)
+ }
+ })
+ }
+
+ // re-orient a segment so it's either facing up or right and make it into a rect
+ RegionList.segmentsToRects = function(segment){
+ // vertical
+ if (segment[0].a == segment[1].a) {
+ if (segment[0].b > segment[1].b) {
+ segment.push(segment.shift())
+ }
+ }
+ // horizontal
+ else if (segment[0].b == segment[1].b) {
+ if (segment[0].a > segment[1].a) {
+ segment.push(segment.shift())
+ }
+ }
+ return new Rect( segment[0].a, segment[0].b, segment[1].a, segment[1].b )
+ }
+
+ if (! ('window' in this) ) {
+ module.exports = RegionList
+ }
+
+ return RegionList
+
+})() \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js
new file mode 100644
index 0000000..21beb76
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js
@@ -0,0 +1,124 @@
+// The ShapeList manages the list of polylines which form a V2 layout.
+
+if (! ('window' in this) ) {
+ var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js")
+ var Polyline = require("./polyline.js")
+ var OrthoPolyline = require("./ortho.js")
+}
+
+var ShapeList = Fiber.extend(function(base){
+ var exports = {}
+ exports.init = function(){
+ this.shapes = []
+ this.workline = null
+ }
+ exports.add = function(shape){
+ this.shapes.push(shape)
+ }
+ exports.remove = function(shape){
+ var index = this.shapes.indexOf(shape)
+ if (index !== -1) {
+ this.shapes.splice(index, 1)
+ }
+ }
+ exports.destroy = function(){
+ this.shapes.forEach(function(shape){
+ shape.destroy()
+ })
+ this.shapes = []
+ }
+ exports.count = function(){
+ return this.shapes.length
+ }
+ exports.removeSegment = function (segment){
+ var shape = segment.shape
+ var head = shape.getHeadAtIndex(segment.head)
+ var tail = shape.getTailAtIndex(segment.tail)
+ this.remove(shape)
+ shape.destroy()
+ if (head) {
+ this.add(head)
+ head.build()
+ }
+ if (tail) {
+ this.add(tail)
+ tail.build()
+ }
+ }
+ exports.findClosestPoint = function (p){
+ var point
+ for (var i = 0; i < this.shapes.length; i++) {
+ point = this.shapes[i].hasPointNear(p)
+ if (point) return { point: point, shape: this.shapes[i] }
+ }
+ return null
+ }
+ exports.findClosestEndPoint = function (p){
+ var point
+ for (var i = 0; i < this.shapes.length; i++) {
+ point = this.shapes[i].hasEndPointNear(p)
+ if (point) return { point: point, shape: this.shapes[i] }
+ }
+ return null
+ }
+ exports.findClosestSegment = function (p){
+ var segment = null, closest_segment = null
+ for (var i = 0; i < this.shapes.length; i++) {
+ segment = this.shapes[i].hasSegmentNear(p, 10)
+ if (segment && (! closest_segment || segment.distance < closest_segment.distance)) {
+ closest_segment = segment
+ closest_segment.shape = this.shapes[i]
+ }
+ }
+ return closest_segment
+ }
+ exports.forEach = function(fn){
+ this.shapes.forEach(fn)
+ }
+ exports.getAllShapeSegments = function(){
+ return this.shapes.map(function(shape){ return shape.getSegments() })
+ }
+ exports.getAllSegments = function(){
+ var segments = []
+ this.shapes.forEach(function(shape){
+ segments = segments.concat( shape.getSegments() )
+ })
+ return segments
+ }
+ exports.draw = function(ctx, fillStyle, strokeStyle) {
+ this.shapes.forEach(function(shape){
+ shape.draw(ctx, fillStyle, strokeStyle)
+ })
+ }
+ exports.serialize = function(){
+ return this.shapes.map(function(shape){
+ return shape.serialize()
+ })
+ }
+ exports.deserialize = function(data){
+ data && data.forEach(function(shape_data){
+ var line
+ switch (shape_data.type) {
+ case 'ortho':
+ line = new OrthoPolyline()
+ break
+ default:
+ line = new Polyline()
+ break
+ }
+ line.deserialize(shape_data)
+ shapes.add(line)
+ }.bind(this))
+ }
+ exports.build = function(){
+ this.shapes.forEach(function(shape){
+ shape.build()
+ })
+ }
+ return exports
+})
+
+if (! ('window' in this) ) {
+ shapes = new ShapeList
+ module.exports = shapes
+}
diff --git a/public/assets/javascripts/rectangles/models/floor.js b/public/assets/javascripts/rectangles/models/floor.js
index 51537f3..63eebcc 100644
--- a/public/assets/javascripts/rectangles/models/floor.js
+++ b/public/assets/javascripts/rectangles/models/floor.js
@@ -68,8 +68,43 @@
}
return
}
+
- if (Scenery.nextWallpaper) {
+ var offset = offsetFromPoint(e, mx.el)
+ if (! offset) { return }
+
+ var x = mx.x + mx.width * (offset.left-0.5)
+ var z = mx.z + mx.height * (0.5-offset.top)
+
+ if (Scenery.nextMedia) {
+ e.preventDefault()
+
+ var sculpture = Sculpture.addNext({
+ position: { x: x, y: 0, z: z },
+ })
+
+ // scenery was not placed
+ if (! sculpture) {
+ e.stopPropagation()
+ return
+ }
+
+ app.controller.toolbar.resetPermissions()
+ Sculpture.resize.show(sculpture)
+ Sculpture.hovering = true
+
+ // app.controller.pick(sculpture)
+
+ UndoStack.push({
+ type: 'create-sculpture',
+ undo: { id: sculpture.id },
+ redo: sculpture.serialize(),
+ })
+
+ // TODO: watch individual sculpture object here
+ Minotaur.watch( app.router.editorView.settings )
+ }
+ else if (Scenery.nextWallpaper) {
var oldState = base.serialize()
base.wallpaper(Scenery.nextWallpaper)
// Scenery.nextWallpaper = null
@@ -98,7 +133,7 @@
this.mx.reverse()
}
}
-
+
Floor.prototype.color = function(color){
this.$els.css("background-color", color)
}
@@ -118,7 +153,7 @@
background.scale = background.scale || 1
this.background = background
- this.background.src = this.background.src.replace(/url\(\"?\'?/,"").replace(/\"?\'?\)/,"")
+ this.background.src = this.background.src.replace(/url\(\"?\'?/,"").replace(/\"?\'?\)/,"")
if (this.background.src == "none") {
this.wallpaperLoad(this.background.src)
diff --git a/public/assets/javascripts/rectangles/models/rect.js b/public/assets/javascripts/rectangles/models/rect.js
index c667cf5..a4756ed 100644
--- a/public/assets/javascripts/rectangles/models/rect.js
+++ b/public/assets/javascripts/rectangles/models/rect.js
@@ -39,6 +39,12 @@
Rect.prototype.clone = function(){
return new Rect( this.x.clone(), this.y.clone() )
}
+ Rect.prototype.x_component = function(){
+ return new vec2( this.x.a, this.y.a )
+ }
+ Rect.prototype.y_component = function(){
+ return new vec2( this.x.b, this.y.b )
+ }
Rect.prototype.assign = function(r) {
this.x.assign(r.x)
this.y.assign(r.y)
@@ -56,6 +62,12 @@
Rect.prototype.maxDimension = function(){
return abs(this.width) > abs(this.height) ? this.width : this.height
}
+ Rect.prototype.isVertical = function(){
+ return this.x.isPoint()
+ }
+ Rect.prototype.isHorizontal = function(){
+ return this.y.isPoint()
+ }
Rect.prototype.mul = function(n){
this.x.mul(n)
diff --git a/public/assets/javascripts/rectangles/models/room.js b/public/assets/javascripts/rectangles/models/room.js
index 26bf055..1abe2ba 100644
--- a/public/assets/javascripts/rectangles/models/room.js
+++ b/public/assets/javascripts/rectangles/models/room.js
@@ -31,10 +31,14 @@
var Room = function(opt){
this.id = opt.id || Rooms.uid("room_")
this.rect = opt.rect
- this.regions = []
+ this.regions = opt.regions || []
this.height = opt.height || 200
this.focused = false
+
+ this.mx_walls = []
+ this.mx_floor = []
+ this.mx_ceiling = []
}
Room.prototype.copy = function(){
@@ -125,6 +129,7 @@
Room.prototype.collidesDisc = function(src, dest, radius){
var x = dest.x, y = dest.z
var collision = 0, wall_collision, contains_x, contains_y
+
this.regions.forEach(function(r){
if (! r.sides) return
diff --git a/public/assets/javascripts/rectangles/models/vec2.js b/public/assets/javascripts/rectangles/models/vec2.js
index 14d0e6b..8942d92 100644
--- a/public/assets/javascripts/rectangles/models/vec2.js
+++ b/public/assets/javascripts/rectangles/models/vec2.js
@@ -43,6 +43,9 @@
vec2.prototype.eq = function(v){
return this.a == v.a && this.b == v.b
}
+ vec2.prototype.isPoint = function(){
+ return this.a == this.b
+ }
vec2.prototype.add = function(n){
this.a += n
this.b += n
@@ -80,6 +83,11 @@
this.a = Math.round(this.a)
this.b = Math.round(this.b)
}
+ vec2.prototype.distanceTo = function(v){
+ var va = (this.a - v.a)
+ var vb = (this.b - v.b)
+ return Math.sqrt( va*va + vb*vb )
+ }
vec2.prototype.setPosition = function(n){
var len = this.length()
this.a = n
@@ -103,6 +111,12 @@
vec2.prototype.containsDisc = function(n,r){
return this.a <= n-r && n+r <= this.b
}
+ vec2.prototype.containsVec = function(v){
+ return this.a <= v.a && v.b <= this.b
+ }
+ vec2.prototype.containsCenterVec = function(v){
+ return this.a < v.a && v.b < this.b
+ }
vec2.prototype.clamp = function(n){
return clamp(n, this.a, this.b)
}
@@ -200,13 +214,13 @@
}
vec2.prototype.toString = function(){
- return "[" + round(this.a) + " " + round(this.b) + "]"
+ return "[" + Math.round(this.a) + " " + Math.round(this.b) + "]"
}
vec2.prototype.exactString = function(){
return "[" + this.a + " " + this.b + "]"
}
vec2.prototype.serialize = function(){
- return [ round(this.a), round(this.b) ]
+ return [ Math.round(this.a), Math.round(this.b) ]
}
vec2.prototype.deserialize = function(data){
this.a = data[0]
diff --git a/public/assets/javascripts/rectangles/models/vec3.js b/public/assets/javascripts/rectangles/models/vec3.js
index c44dfe6..b3825a9 100644
--- a/public/assets/javascripts/rectangles/models/vec3.js
+++ b/public/assets/javascripts/rectangles/models/vec3.js
@@ -32,3 +32,28 @@ vec3.prototype.apply_projection = function (m) {
return this;
}
+
+vec3.prototype.serialize = function(){
+ return [ round(this.a), round(this.b), round(this.c) ]
+}
+vec3.prototype.deserialize = function(data){
+ this.a = data[0]
+ this.b = data[1]
+ this.c = data[2] || data[0]
+ return this
+}
+vec3.prototype.clone = function(){
+ return new vec3(this.a, this.b, this.c)
+}
+vec3.prototype.assign = function(v){
+ this.a = v.a
+ this.b = v.b
+ this.c = v.c
+ return this
+}
+vec3.prototype.mul = function(n) {
+ this.a *= n
+ this.b *= n
+ this.c *= n
+ return this
+} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/models/wall.js b/public/assets/javascripts/rectangles/models/wall.js
index fc1ccbe..cf3cea8 100644
--- a/public/assets/javascripts/rectangles/models/wall.js
+++ b/public/assets/javascripts/rectangles/models/wall.js
@@ -10,6 +10,11 @@
vec2 = require('./vec2')
Rect = require('./rect')
UidGenerator = require('../util/uid')
+ wall_rotation = {}
+ wall_rotation[FRONT] = PI
+ wall_rotation[BACK] = 0
+ wall_rotation[LEFT] = HALF_PI
+ wall_rotation[RIGHT] = -HALF_PI
}
var Wall = function(opt){
@@ -18,6 +23,7 @@
this.edge = opt.edge
this.side = opt.side
this.surface = opt.surface
+ this.rotationY = ('rotationY' in opt) ? opt.rotationY : wall_rotation[opt.side]
this.mx = opt.mx
this.background = { src: "none" }
}
@@ -89,7 +95,7 @@
mx_dot.move(mx_pos)
mx_dot.width = 5
mx_dot.height = 5
- mx_dot.rotationY = wall_rotation[base.side]
+ mx_dot.rotationY = base.rotationY
mx_dot.el.style.backgroundColor = "red"
scene.add(mx_dot)
}
@@ -192,7 +198,7 @@
}
Wall.prototype.serialize = function(){
- return {
+ return {
id: this.id,
background: this.background,
}
@@ -236,7 +242,7 @@
x: x,
y: position.b + dimension.b / 2,
z: z,
- rotationY: wall_rotation[ this.side ],
+ rotationY: this.rotationY,
}
}
Wall.prototype.mxToPosition = function(mx, dimension) {
@@ -288,7 +294,7 @@
background.scale = background.scale || 1
this.background = background
- this.background.src = this.background.src.replace(/url\(\"?\'?/,"").replace(/\"?\'?\)/,"")
+ this.background.src = this.background.src.replace(/url\(\"?\'?/,"").replace(/\"?\'?\)/,"")
if (this.background.src == "none") {
this.wallpaperLoad(this.background.src)
diff --git a/public/assets/javascripts/rectangles/util/constants.js b/public/assets/javascripts/rectangles/util/constants.js
index 3bc314c..522689b 100644
--- a/public/assets/javascripts/rectangles/util/constants.js
+++ b/public/assets/javascripts/rectangles/util/constants.js
@@ -22,10 +22,11 @@ var height_min = 200,
resize_margin = 8,
cursor_amp = 1.5,
DEFAULT_PICTURE_WIDTH = 350,
- MAP_GRID_SIZE = 360 // 10 feet
+ MAP_GRID_SIZE = 36 // 10 feet
var painting_distance_from_wall = 10,
- dot_distance_from_picture = 3
+ dot_distance_from_picture = 3,
+ sculpture_distance_from_floor = 3
var dot_hide_delay = 50, // ms
dot_side = 20
diff --git a/public/assets/javascripts/rectangles/util/coords.js b/public/assets/javascripts/rectangles/util/coords.js
index 74b7fda..ff56199 100644
--- a/public/assets/javascripts/rectangles/util/coords.js
+++ b/public/assets/javascripts/rectangles/util/coords.js
@@ -30,4 +30,4 @@ function offsetFromPoint(event, element) {
return 'left: ' + l + '%, top: ' + t + '%';
}
} : null;
-}
+} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/util/measurement.js b/public/assets/javascripts/rectangles/util/measurement.js
index d6a0b35..6346eac 100644
--- a/public/assets/javascripts/rectangles/util/measurement.js
+++ b/public/assets/javascripts/rectangles/util/measurement.js
@@ -28,6 +28,10 @@ function measurementToString( n ) {
case 'ft':
ft = floor(n / 36)
inch = abs(round((n % 36) / 3))
+ if (inch == 12) {
+ inch = 0
+ ft += 1
+ }
s = ft + "'"
if (inch > 0) {
s += " " + inch + '"'
diff --git a/public/assets/javascripts/rectangles/util/mouse.js b/public/assets/javascripts/rectangles/util/mouse.js
index cb36038..2b98cee 100644
--- a/public/assets/javascripts/rectangles/util/mouse.js
+++ b/public/assets/javascripts/rectangles/util/mouse.js
@@ -76,6 +76,14 @@ function mouse (opt) {
window.addEventListener("mousemove", base.mousemove)
window.addEventListener("mouseup", base.mouseup)
}
+ base.unbind = function(){
+ if (opt.el) {
+ opt.el.removeEventListener("mousedown", base.mousedown)
+ opt.el.removeEventListener("contextmenu", base.contextmenu)
+ }
+ window.removeEventListener("mousemove", base.mousemove)
+ window.removeEventListener("mouseup", base.mouseup)
+ }
base.bind_el = function(el){
el.addEventListener("mousedown", base.mousedown)
@@ -126,7 +134,7 @@ function mouse (opt) {
}
var x = pos.a, y = pos.b
-
+
if (base.down) {
base.cursor.x.b = x
base.cursor.y.b = y
diff --git a/public/assets/javascripts/rectangles/util/wheel.js b/public/assets/javascripts/rectangles/util/wheel.js
index 712d470..4155a70 100644
--- a/public/assets/javascripts/rectangles/util/wheel.js
+++ b/public/assets/javascripts/rectangles/util/wheel.js
@@ -3,8 +3,8 @@
base.wheel = new wheel({
el: document.querySelector("#map"),
- update: function(e, val, delta){
- // do something with val
+ update: function(e, delta){
+ // do something with delta
},
})
@@ -13,7 +13,7 @@
function wheel (opt) {
opt = defaults(opt, {
el: document,
- fn: function(e, val, delta){},
+ update: function(e, delta){},
propagate: false,
locked: false,
reversible: true,
@@ -22,7 +22,7 @@ function wheel (opt) {
})
opt.el.addEventListener('wheel', onMouseWheel, false);
-// opt.el.addEventListener('mousewheel', onMouseWheel, false);
+ // opt.el.addEventListener('mousewheel', onMouseWheel, false);
opt.el.addEventListener('DOMMouseScroll', onMouseWheel, false);
function onMouseWheel (e) {
@@ -58,6 +58,8 @@ function wheel (opt) {
// opt.val = clamp(opt.val + delta, opt.min, opt.max)
+ // deltaX is also passed, but these values tend to be unusable
+ // try http://vvalls.com/assets/test/wheel.html with a trackpad
opt.update(e, deltaY, deltaX)
}
diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js
index 3532428..61b1d1b 100644
--- a/public/assets/javascripts/ui/_router.js
+++ b/public/assets/javascripts/ui/_router.js
@@ -9,6 +9,7 @@ var SiteRouter = Router.extend({
"click [data-role='new-project-modal']": 'newProject',
"click [data-role='edit-project-modal']": 'editProject',
"click [data-role='edit-profile-modal']": 'editProfile',
+ "click [data-role='edit-subscription-modal']": 'editSubscription',
"click [data-role='new-document-modal']": 'newDocument',
"click [data-role='edit-document-modal']": 'editDocument',
"click [data-role='destroy-document-modal']": 'destroyDocument',
@@ -17,31 +18,38 @@ var SiteRouter = Router.extend({
},
routes: {
- "/": 'home',
- "/home": 'home',
- "/login": 'signin',
- "/signin": 'signin',
- "/signup": 'signup',
+ "/": 'home',
+ "/home": 'home',
+ "/login": 'signin',
+ "/signin": 'signin',
+ "/signup": 'signup',
- "/auth/usernameTaken": 'usernameTaken',
- "/auth/password": 'passwordReset',
- "/auth/forgotPassword": 'passwordForgot',
+ "/auth/usernameTaken": 'usernameTaken',
+ "/auth/password": 'passwordReset',
+ "/auth/forgotPassword": 'passwordForgot',
- "/profile": 'profile',
- "/profile/edit": 'editProfile',
- "/profile/:name": 'profile',
- "/about/:name/edit": 'editDocument',
- "/about/new": 'newDocument',
+ "/profile": 'profile',
+ "/profile/edit": 'editProfile',
+ "/profile/billing": 'editSubscription',
+ "/profile/:name": 'profile',
+ "/about/:name/edit": 'editDocument',
+ "/about/new": 'newDocument',
- "/layout": 'layoutPicker',
- "/layout/:name": 'layoutEditor',
+ "/layout": 'layoutPicker',
+ "/layout/:name": 'layoutEditor',
- "/project": 'projectPicker',
- "/project/new": 'newProject',
- "/project/new/:layout": 'projectNewWithLayout',
- "/project/:name": 'projectViewer',
- "/project/:name/edit": 'projectEditor',
- "/project/:name/view": 'projectViewer',
+ "/blueprint": 'blueprintEditor',
+ "/blueprint/:name": 'blueprintEditor',
+
+ "/project": 'projectPicker',
+ "/project/new": 'newProject',
+ "/project/blueprint/:blueprint": 'projectNewWithBlueprint',
+ "/project/new/:layout": 'projectNewWithLayout',
+ "/project/:name": 'projectViewer',
+ "/project/:name/edit": 'projectEditor',
+ "/project/:name/view": 'projectViewer',
+
+ "/test/blueprint": 'blueprintEditor',
},
mobileRoutes: {
@@ -56,6 +64,7 @@ var SiteRouter = Router.extend({
"/profile": 'profile',
"/profile/edit": 'editProfile',
+ "/profile/billing": 'editSubscription',
"/profile/:name": 'profile',
"/project/:name": 'projectViewer',
@@ -69,6 +78,7 @@ var SiteRouter = Router.extend({
this.newProjectModal = new NewProjectModal()
this.editProjectModal = new EditProjectModal()
this.editProfileModal = new EditProfileModal()
+ this.editSubscriptionModal = new EditSubscriptionModal()
this.passwordForgotModal = new PasswordForgot()
this.documentModal = new DocumentModal()
this.profileView = new ProfileView()
@@ -83,7 +93,9 @@ var SiteRouter = Router.extend({
})
}
- $("body").removeClass("loading")
+ setTimeout(function(){
+ $("body").removeClass("loading")
+ }, 200)
},
layoutEditor: function(e, name){
@@ -112,6 +124,22 @@ var SiteRouter = Router.extend({
window.history.pushState(null, document.title, "/project/new")
this.newProjectModal.load()
},
+
+ projectNewWithBlueprint: function(e, blueprint){
+ e && e.preventDefault()
+
+ Rooms.shapesMode = true
+
+ app.mode.editor = true
+ app.launch()
+ if (app.unsupported) return
+
+ blueprint = slugify(blueprint)
+
+ window.history.pushState(null, document.title, "/project/blueprint/" + blueprint)
+ this.editorView = app.controller = new EditorView()
+ this.editorView.loadBlueprint(blueprint)
+ },
projectNewWithLayout: function(e, layout){
e && e.preventDefault()
@@ -153,6 +181,15 @@ var SiteRouter = Router.extend({
this.readerView = app.controller = new ReaderView()
this.readerView.load(name)
},
+
+ blueprintEditor: function(e, name){
+ environment.init = environment.minimal
+ app.launch()
+ if (app.unsupported) return
+
+ this.blueprintView = app.controller = new BlueprintView ()
+ this.blueprintView.load(name)
+ },
signup: function(e){
e && e.preventDefault()
@@ -195,7 +232,12 @@ var SiteRouter = Router.extend({
this.editProfileModal.load()
},
+ editSubscription: function(e){
+ e && e.preventDefault()
+ window.history.pushState(null, document.title, "/profile/billing")
+ this.editSubscriptionModal.load()
+ },
newDocument: function(e){
e && e.preventDefault()
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js
new file mode 100644
index 0000000..7704689
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js
@@ -0,0 +1,129 @@
+
+var wallHeight = 180
+var shapes = new ShapeList
+var last_point = new vec2 (0,0)
+
+var BlueprintEditor = View.extend(AnimatedView.prototype).extend({
+
+ regions: [],
+
+ initialize: function(opt){
+ this.parent = opt.parent
+
+ $(window).resize(this.resize.bind(this))
+
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+ cam = scene.camera
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ movements = new MX.Movements(cam, viewHeight)
+ movements.init()
+ movements.lock()
+
+ app.on("move", function(pos){
+ cam.x = pos.x
+ cam.y = pos.y
+ cam.z = pos.z
+ })
+
+ var floorplan = this.floorplan = new MX.Image({
+ backface: true,
+ })
+ scene.add(this.floorplan)
+
+ // recenter perspective view by rightclicking map
+ this.floorplan.el.addEventListener("contextmenu", function(e){
+ e.preventDefault()
+ var offset = offsetFromPoint(e, this)
+ var x = (offset.left - 0.5) * floorplan.width * floorplan.scale
+ var z = (offset.top - 0.5) * floorplan.height * floorplan.scale
+ controls.opt.center.x = -x
+ controls.opt.center.y = 0
+ controls.opt.center.z = z
+ }, true)
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ el: scene.el,
+ radius: 3000,
+ radiusRange: [ 10, 10000 ],
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+ },
+
+ resize: function(){
+ if (this.parent.orbiting) {
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ this.parent.map.resize( window.innerWidth/2, window.innerHeight )
+ this.parent.map.canvas.style.display = "block"
+ }
+ else {
+ scene.width = window.innerWidth
+ scene.height = window.innerHeight
+ this.parent.map.canvas.style.display = "none"
+ }
+ },
+
+ loadFloorplan: function(media){
+ // console.log(media)
+ this.floorplan.load({
+ media: media,
+ keepImage: true,
+ rotationX: -PI/2,
+ rotationY: PI,
+ scale: media.scale,
+ })
+ this.startAnimating()
+ this.regions = RegionList.buildByShape()
+ },
+
+ animate: function(t, dt){
+ map.update(t)
+
+ movements.update(dt)
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ this.floorplan.draw(map.draw.ctx, true)
+
+ map.draw.coords()
+
+ if (shapes.workline) {
+ shapes.workline.draw(map.draw.ctx, "rgba(255,255,0,0.1)", "#f80")
+ if (map.ui.placing && last_point) {
+ shapes.workline.draw_line( map.draw.ctx, last_point )
+ }
+ }
+
+ shapes.draw(map.draw.ctx, "rgba(255,255,0,0.1)", "#f80")
+
+ map.draw.ctx.strokeStyle = "#f00";
+ map.draw.x_at( this.parent.startPosition )
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+// var colors = ["rgba(0,0,0,0.1)"]
+// var colors = ["rgba(255,255,255,1)"]
+
+// map.draw.regions(this.regions, colors, "#000")
+
+// this.regions.forEach(function(room,i){
+// map.draw.ctx.fillStyle = colors[i % colors.length]
+// map.draw.ctx.fillRect( room.x.a, room.y.a, room.width(), room.height() )
+// })
+
+ map.draw.ctx.restore()
+ },
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintInfo.js b/public/assets/javascripts/ui/blueprint/BlueprintInfo.js
new file mode 100644
index 0000000..51b310e
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintInfo.js
@@ -0,0 +1,92 @@
+
+var BlueprintInfo = View.extend({
+ el: "#blueprintInfo",
+
+ events: {
+ "mousedown": "stopPropagation",
+ "keydown": 'stopPropagation',
+ "change [name=height]": 'changeHeight',
+ "keydown [name=height]": 'enterHeight',
+ "change [name=units]": 'changeUnits',
+ "keydown [name=viewHeight]": 'enterViewHeight',
+ "change [name=viewHeight]": 'changeViewHeight',
+ "click .openScaler": 'openScaler',
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.$height = this.$("[name=height]")
+ this.$units = this.$("[name=units]")
+ this.$viewHeight = this.$("[name=viewHeight]")
+ this.$unitName = this.$(".unitName")
+ this.$blueprintScaleDisplay = this.$("#blueprintScaleDisplay")
+ },
+
+ load: function(data){
+ this.$viewHeight.unitVal( window.viewHeight = data.viewHeight || app.defaults.viewHeight )
+ this.$height.unitVal( window.wallHeight = data.wallHeight || app.defaults.wallHeight )
+ this.$units.val( data.units )
+ this.$('span.units').html( data.units )
+ this.$unitName.html( data.units )
+
+ var resolution
+ switch (data.units) {
+ case 'ft':
+ resolution = app.defaults.footResolution
+ break
+ case 'm':
+ resolution = app.defaults.meterResolution
+ break
+ case 'px':
+ default:
+ resolution = 1
+ break
+ }
+ this.$blueprintScaleDisplay.html( ((1/data.scale) * resolution).toFixed(1) )
+ this.show()
+ },
+
+ toggle: function(state){
+ this.$el.toggleClass("active", state)
+ this.$viewHeight.unitVal( window.viewHeight )
+ },
+
+ openScaler: function(){
+ this.parent.scaler.pick( this.parent.data, true )
+ this.parent.scaler.show()
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+
+ hide: function(){
+ this.toggle(false)
+ },
+
+ deselect: function(){
+ this.toggle(true)
+ },
+
+ enterHeight: function(e){
+ if (e.keyCode == 13) this.changeHeight(e)
+ },
+ changeHeight: function(e){
+ e.stopPropagation()
+ window.wallHeight = this.$height.unitVal()
+ shapes.forEach(function(line){
+ line.mx.set_height( window.wallHeight )
+ })
+ },
+ changeUnits: function(){
+ app.units = this.$units.val()
+ this.$('.units').resetUnitVal()
+ },
+ enterViewHeight: function(e){
+ if (e.keyCode == 13) this.changeViewHeight(e)
+ },
+ changeViewHeight: function(){
+ window.viewHeight = this.$viewHeight.unitVal()
+ }
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintNotice.js b/public/assets/javascripts/ui/blueprint/BlueprintNotice.js
new file mode 100644
index 0000000..4b799a6
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintNotice.js
@@ -0,0 +1,62 @@
+var BlueprintNotice = View.extend(ToggleableView.prototype).extend({
+
+ el: "#blueprintNotice",
+
+ events: {
+ "click .next": "next",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.$notice = this.$(".notice")
+ this.$next = this.$(".next")
+ },
+
+ notice: function(msg){
+ this.$notice.html(msg)
+ },
+
+ showCreateProjectNotice: function(){
+ this.notice("<a href='/project/blueprint/" + this.parent.data.slug +
+ "'>Start a new project</a> with this blueprint.")
+ this.$next.hide()
+ this.nextFn = null
+ this.show()
+ },
+
+ showStartPositionNotice: function(){
+ this.parent.settings.hide()
+ this.notice("First, click the map to set the starting location.")
+ this.$next.show().html("Next")
+ this.show()
+ this.nextFn = this.showStartAngleNotice.bind(this)
+ },
+
+ showStartAngleNotice: function(){
+ this.parent.settings.hide()
+ this.notice("Next, rotate the camera to the desired orientation.")
+ this.$next.show().html("Done")
+ this.show()
+ this.nextFn = this.doneSettingPosition.bind(this)
+ this.parent.toolbar.toggleOrbitMode(false)
+ },
+
+ doneSettingPosition: function(){
+ this.nextFn = null
+ this.$next.hide()
+ this.hide()
+ this.parent.settings.show()
+ this.parent.startPosition.rotationX = cam.rotationX
+ this.parent.startPosition.rotationY = cam.rotationY
+ this.parent.toolbar.toggleOrbitMode(true)
+ this.parent.toolbar.orthoPolylineMode()
+ },
+
+ nextFn: null,
+ next: function(){
+ if (this.nextFn) {
+ this.nextFn()
+ }
+ },
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js
new file mode 100644
index 0000000..cd370ef
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js
@@ -0,0 +1,158 @@
+
+var BlueprintScaler = ModalFormView.extend(AnimatedView.prototype).extend({
+ el: ".blueprintScaler",
+
+ fixedClose: true,
+
+ action: "/api/blueprint/scale",
+
+ events: {
+ "change [name=blueprint-dimensions]": "changeDimensions",
+ "change [name=blueprint-units]": "changeUnits",
+ "click .uploadNewBlueprint": "showUploader",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+
+ this.$blueprintMap = this.$("#blueprintMap")
+ this.$blueprintDimensionsRapper = this.$("#blueprintDimensions")
+ this.$dimensions = this.$("[name=blueprint-dimensions]")
+ this.$pixels = this.$("[name=blueprint-pixels]")
+ this.$units = this.$("[name=blueprint-units]")
+ this.$save = this.$("#saveBlueprint")
+
+ this.map = new Map ({
+ type: "ortho",
+ el: this.$blueprintMap.get(0),
+ width: window.innerWidth,
+ height: window.innerHeight,
+ zoom: -2,
+ zoom_min: -7.0,
+ zoom_max: 2,
+ })
+ this.lineTool = new LineTool
+ this.map.ui.add_tool("line", this.lineTool)
+ this.map.ui.set_tool("line")
+
+ scene = scene || { camera: { x: 0, y: 0, z: 0 } }
+
+ this.floorplan = new MX.Image ()
+ },
+
+ showUploader: function(){
+ this.parent.uploader.show()
+ },
+
+ pick: function(media, shouldEdit){
+ this.media = media
+
+ this.floorplan.load({ media: media, scale: 1, keepImage: true })
+
+ if (!! media.units && ! shouldEdit) {
+ this.parent.ready(media)
+ this.hide()
+ this.stopAnimating()
+ return
+ }
+
+ if (media.units && media.line && media.scale) {
+ var points = media.line.split(",")
+ this.lineTool.line[0] = new vec2( +points[0], +points[1] )
+ this.lineTool.line[1] = new vec2( +points[2], +points[3] )
+
+ app.units = media.units
+ this.$units.val( media.units )
+ this.$dimensions.unitVal( media.scale * this.lineLength() )
+ }
+
+ this.startAnimating()
+ },
+
+ animate: function(t, dt){
+ this.map.update(t)
+
+ this.map.draw.ctx.save()
+ this.map.draw.translate()
+
+ this.floorplan.draw(this.map.draw.ctx, true)
+
+ this.map.draw.ctx.save()
+ this.map.draw.ctx.strokeStyle = "#f00"
+ this.map.draw.ctx.lineWidth = 1/map.zoom
+ switch (this.lineTool.line.length) {
+ case 1:
+ this.map.draw.line(
+ this.lineTool.line[0].a,
+ this.lineTool.line[0].b,
+ this.lineTool.cursor.x.a,
+ this.lineTool.cursor.y.a
+ )
+ break
+ case 2:
+ this.map.draw.line(
+ this.lineTool.line[0].a,
+ this.lineTool.line[0].b,
+ this.lineTool.line[1].a,
+ this.lineTool.line[1].b
+ )
+ break
+ }
+ this.map.draw.ctx.restore()
+
+ this.map.draw.coords()
+
+ this.map.draw.mouse(this.map.ui.mouse.cursor)
+
+ this.map.draw.ctx.restore()
+ },
+
+ changeDimensions: function(){
+ app.units = this.$units.val()
+ this.$dimensions.unitVal()
+ },
+ changeUnits: function(){
+ app.units = this.$units.val()
+ this.$dimensions.resetUnitVal()
+ },
+ lineLength: function(){
+ if (this.lineTool.line.length !== 2) return 0
+ var line = this.lineTool.line
+ return dist( line[0].a, line[0].b, line[1].a, line[1].b )
+ },
+
+ validate: function(){
+ var val = this.$dimensions.unitVal()
+ var errors = []
+ if (! this.lineLength()) {
+ errors.push("no line")
+ this.$dimensions.val("")
+ alert("Please click two corners of a wall and then specify how long it is in feet or meters.")
+ }
+ else if (val == 0) {
+ errors.push("no measurement")
+ alert("Please tell us how long the wall is in feet or meters.")
+ }
+ return errors
+ },
+
+ showErrors: function(){},
+
+ serialize: function(){
+ var fd = new FormData(), line = this.lineTool.line
+ fd.append( "_id", this.media._id)
+ fd.append( "units", this.$units.val() )
+ fd.append( "scale", this.$dimensions.unitVal() / this.lineLength() )
+ fd.append( "line", [line[0].a,line[0].b,line[1].a,line[1].b].join(",") )
+ fd.append( "_csrf", $("[name=_csrf]").val())
+ return fd
+ },
+
+ success: function(){
+ this.media.scale = this.$dimensions.unitVal() / this.lineLength()
+ this.stopAnimating()
+ this.parent.ready(this.media)
+ this.hide()
+ },
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintSettings.js b/public/assets/javascripts/ui/blueprint/BlueprintSettings.js
new file mode 100644
index 0000000..8addb9c
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintSettings.js
@@ -0,0 +1,123 @@
+
+var BlueprintSettings = FormView.extend(ToggleableView.prototype).extend({
+ el: "#blueprintSettings",
+
+ action: "/api/blueprint/edit",
+ destroyAction: "/api/blueprint/destroy",
+
+ events: {
+ "mousedown": "stopPropagation",
+ "keydown": 'stopPropagation',
+ "keydown [name=name]": 'enterSubmit',
+ "click [data-role='save-layout']": 'clickSave',
+ "click [data-role='clear-layout']": 'clear',
+ "click [data-role='destroy-layout']": 'destroy',
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.__super__.initialize.call(this)
+
+ this.$id = this.$("[name=_id]")
+ this.$csrf = this.$("[name=_csrf]")
+ this.$name = this.$("[name=name]")
+ },
+
+ load: function(data){
+ this.$id.val(data._id)
+ if (data.name) {
+ this.$name.val(data.name)
+ this.hide()
+ }
+ else {
+ this.$name.val("")
+ }
+ if (data.shapes) {
+ shapes.destroy()
+ shapes.deserialize( data.shapes )
+ shapes.build()
+ }
+ },
+
+ clear: function(){
+ shapes.destroy()
+ },
+
+ destroy: function(){
+ var msg = "Are you sure you want to delete the blueprint " + sanitize(this.$name.val()) + "?"
+ ConfirmModal.confirm(msg, function(){
+ $.ajax({
+ url: this.destroyAction,
+ type: "delete",
+ data: { _id: this.$id.val(), _csrf: this.$csrf.val() },
+ success: function(data){
+ window.location.href = "/layout"
+ }
+ })
+ }.bind(this))
+ },
+
+ enterSubmit: function (e) {
+ e.stopPropagation()
+ var base = this
+ if (e.keyCode == 13) {
+ setTimeout(function(){ base.save(e) }, 100)
+ }
+ },
+
+ validate: function(){
+ var errors = []
+ var name = this.$name.val()
+ if (! name || ! name.length) {
+ errors.push("Blueprint needs a name.")
+ }
+ if (shapes.count() == 0) {
+ errors.push("Please add some walls.")
+ }
+ return errors
+ },
+
+ showErrors: function(errors){
+ var $errors = $("<span>")
+ errors.forEach(function(err){
+ var $row = $("<div>")
+ $row.html(err)
+ $errors.append( $row )
+ })
+ ErrorModal.alert($errors)
+ },
+
+ serialize: function(){
+ var fd = new FormData()
+ fd.append( "_csrf", this.$csrf.val() )
+ fd.append( "_id", this.$id.val() )
+ fd.append( "name", this.$name.val() )
+ fd.append( "shapes", JSON.stringify( shapes.serialize() ) )
+ fd.append( "startPosition", JSON.stringify( this.parent.quantizeStartPosition() ) )
+ fd.append( "wallHeight", this.parent.info.$height.unitVal() )
+ fd.append( "units", this.parent.info.$units.val() )
+ return fd
+ },
+
+ clickSave: function(){
+ this.toggle(false)
+ this.save()
+ },
+
+ success: function(data){
+ this.parent.data = data
+
+ this.$id.val(data._id)
+ this.$name.val(data.name)
+ this.action = this.updateAction
+
+ this.hide()
+ this.parent.notice.showCreateProjectNotice()
+
+ Minotaur.unwatch(this)
+ Minotaur.hide()
+
+ window.history.pushState(null, document.title, "/blueprint/" + data.slug)
+ },
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js b/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js
new file mode 100644
index 0000000..458357d
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js
@@ -0,0 +1,97 @@
+var BlueprintToolbar = View.extend({
+
+ el: "#blueprintToolbar",
+
+ events: {
+ "click [data-role=upload-floorplan]": 'showUploader',
+ "click [data-role=toggle-orbit-mode]": 'toggleOrbitMode',
+ "click [data-role=arrow-mode]": 'arrowMode',
+ "click [data-role=polyline-mode]": 'polylineMode',
+ "click [data-role=ortho-polyline-mode]": 'orthoPolylineMode',
+ "click [data-role=eraser-mode]": 'eraserMode',
+ "click [data-role=start-position-mode]": 'startPositionMode',
+ "click [data-role=toggle-layout-settings]": 'toggleSettings',
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+
+ this.$modes = this.$('.mode')
+ this.$toggleOrbitMode = this.$('[data-role=toggle-orbit-mode]')
+ this.$arrowMode = this.$('[data-role=arrow-mode]')
+ this.$polylineMode = this.$('[data-role=polyline-mode]')
+ this.$orthoPolylineMode = this.$('[data-role=ortho-polyline-mode]')
+ this.$eraserMode = this.$('[data-role=eraser-mode]')
+ this.$startPositionMode = this.$('[data-role=start-position-mode]')
+
+ keys.on('escape', function(){
+ app.controller.toolbar.toggleOrbitMode()
+ })
+
+ this.arrowMode()
+ },
+
+ showUploader: function(){
+ this.parent.scaler.show()
+ this.parent.uploader.show()
+ },
+
+ toggleOrbitMode: function(state){
+ this.parent.orbiting = typeof state == "boolean" ? state : ! this.parent.orbiting
+ this.$toggleOrbitMode.toggleClass("inuse", ! this.parent.orbiting)
+ this.parent.editor.resize()
+ if (this.parent.orbiting) {
+ controls.toggle(true)
+ movements.lock()
+ }
+ else {
+ controls.toggle(false)
+ movements.unlock()
+ movements.gravity(true)
+ var pos = this.parent.quantizeStartPosition()
+ cam.rotationX = pos.rotationX
+ cam.rotationY = pos.rotationY
+ cam.x = pos.x
+ cam.y = viewHeight
+ cam.z = pos.z
+ }
+ },
+
+ toggleSettings: function(){
+ this.parent.settings.toggle()
+ this.parent.notice.toggle( ! this.parent.data.isNew && ! this.parent.settings.visible() )
+ },
+
+ setActiveMode: function( $el ) {
+ this.$modes.removeClass('active')
+ $el.addClass('active')
+ },
+
+ arrowMode: function(){
+ this.setActiveMode( this.$arrowMode )
+ this.parent.map.ui.set_tool("arrow")
+ },
+
+ polylineMode: function(){
+ this.setActiveMode( this.$polylineMode )
+ this.parent.map.ui.set_tool("polyline")
+ },
+
+ orthoPolylineMode: function(){
+ this.setActiveMode( this.$orthoPolylineMode )
+ this.parent.map.ui.set_tool("ortho-polyline")
+ },
+
+ eraserMode: function(){
+ this.setActiveMode( this.$eraserMode )
+ this.parent.map.ui.set_tool("eraser")
+ },
+
+ startPositionMode: function(){
+ this.setActiveMode( this.$startPositionMode )
+ this.parent.map.ui.set_tool("start-position")
+ this.parent.settings.hide()
+ this.parent.notice.showStartPositionNotice()
+ },
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js
new file mode 100644
index 0000000..aa62a4c
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js
@@ -0,0 +1,147 @@
+
+var BlueprintUploader = UploadView.extend({
+ el: ".blueprintUploader",
+
+ mediaTag: "blueprint",
+ createAction: "/api/blueprint/new",
+ uploadAction: "/api/blueprint/upload",
+ listAction: "/api/blueprint/user",
+ destroyAction: "/api/blueprint/destroy",
+
+ events: {
+ "mousedown": 'stopPropagation',
+ "change .url": "enterUrl",
+ "keydown .url": "enterSetUrl",
+
+ "click .blueprint": "pick",
+ "click .remove": "destroy",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.__super__.initialize.call(this)
+
+ this.$url = this.$(".url")
+ this.$blueprints = this.$(".blueprints")
+ },
+
+ loaded: false,
+ nameToShow: null,
+ load: function(name){
+ this.nameToShow = name || ""
+ $.get(this.listAction, { tag: this.mediaTag }, this.populate.bind(this))
+ },
+
+ populate: function(data){
+ this.loaded = true
+ if (data && data.length) {
+ this.$blueprints.show()
+ data.forEach(this.append.bind(this))
+ if (this.nameToShow === "new") {
+ // don't pick anything..
+ this.show()
+ }
+ else if (! this.nameToShow) {
+ this.hide()
+ data.some(function(el){
+ if (el.slug == this.nameToShow) {
+ this.parent.scaler.pick(el)
+ return true
+ }
+ }.bind(this))
+ }
+ else {
+ this.hide()
+ this.parent.scaler.pick(data[0])
+ }
+ }
+ else {
+ this.parent.scaler.hideClose()
+ this.show()
+ }
+ },
+
+ pick: function(e){
+ var $el = $(e.currentTarget)
+ var media = $el.data("media")
+ this.hide()
+ this.parent.scaler.pick(media)
+ if (media.slug) {
+ window.history.pushState(null, document.title, "/blueprint/" + media.slug)
+ }
+ },
+
+ destroy: function(e){
+ e.stopPropagation()
+ var $el = $(e.currentTarget)
+ var _id = $el.closest(".blueprint").data("id")
+ $el.remove()
+ $.ajax({
+ type: "delete",
+ url: this.destroyAction,
+ data: { _id: _id, _csrf: $("[name=_csrf]").val() }
+ }).complete(function(){
+ })
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+ hide: function(){
+ this.toggle(false)
+ },
+ toggle: function (state) {
+ this.$el.toggleClass("active", state)
+ },
+
+ addUrl: function (url){
+ Parser.loadImage(url, function(media){
+ if (! media) return
+ media._csrf = $("[name=_csrf]").val()
+ media.tag = this.mediaTag
+
+ var request = $.ajax({
+ type: "post",
+ url: this.createAction,
+ data: media,
+ })
+ request.done(this.add.bind(this))
+
+ }.bind(this))
+ },
+ enterUrl: function(){
+ var url = this.$url.sanitize()
+ this.addUrl(url)
+ this.$url.val("")
+ },
+ enterSetUrl: function (e) {
+ e.stopPropagation()
+ if (e.keyCode == 13) {
+ setTimeout(this.enterUrl.bind(this), 100)
+ }
+ },
+
+ add: function(media){
+ this.$blueprints.show()
+ this.append(media)
+ this.hide()
+ this.parent.scaler.pick(media, true)
+ },
+
+ append: function(media){
+ var $el = $("<span>")
+ var img = new Image ()
+ img.src = media.url
+ var remove = document.createElement("span")
+ remove.className = "remove"
+ remove.innerHTML = "<span>x</span>"
+
+ $el.data("id", media._id)
+ $el.data("media", media)
+ $el.append(img)
+ $el.append(remove)
+ $el.addClass("blueprint")
+ this.$blueprints.append($el)
+ },
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js
new file mode 100644
index 0000000..e249c91
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js
@@ -0,0 +1,97 @@
+
+var BlueprintView = View.extend({
+ el: "#blueprintView",
+
+ action: "/api/blueprint/show/",
+
+ events: {
+ },
+
+ initialize: function(){
+// this.colorControl = new ColorControl ({ parent: this })
+// this.cursor = new HelpCursor({ parent: this })
+ this.map = this.buildMap()
+ this.editor = new BlueprintEditor ({ parent: this })
+ this.toolbar = new BlueprintToolbar ({ parent: this })
+ this.uploader = new BlueprintUploader ({ parent: this })
+ this.scaler = new BlueprintScaler ({ parent: this })
+ this.info = new BlueprintInfo ({ parent: this })
+ this.settings = new BlueprintSettings ({ parent: this })
+ this.notice = new BlueprintNotice ({ parent: this })
+ Rooms.shapesMode = true
+ },
+
+ load: function(name){
+ name = sanitize(name) || "new"
+ this.uploader.load(name)
+// name = sanitize(name)
+// $.get(this.action + name, this.ready.bind(this))
+ },
+
+ orbiting: true,
+ startPosition: {},
+ quantizeStartPosition: function(){
+ //
+ var regions = RegionList.build()
+ var pos = this.startPosition
+ var startPositionIsInARoom = regions.some(function(region){
+ return region.contains(pos.x, pos.z)
+ })
+ if (startPositionIsInARoom) {
+ return this.startPosition
+ }
+ else {
+ var center = regions[0].center()
+ return {
+ x: center.a,
+ y: viewHeight,
+ z: center.b,
+ rotationX: 0,
+ rotationY: Math.PI/2,
+ }
+ }
+ },
+
+ buildMap: function(){
+ // i forget if this has to be global
+ map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: -2,
+ zoom_min: -6.2,
+ zoom_max: 1,
+ })
+ map.ui.add_tool("arrow", new ArrowTool)
+ map.ui.add_tool("polyline", new PolylineTool)
+ map.ui.add_tool("ortho-polyline", new OrthoPolylineTool)
+ map.ui.add_tool("eraser", new EraserTool)
+ map.ui.add_tool("position", new PositionTool)
+ map.ui.add_tool("start-position", new StartPositionTool)
+ map.ui.placing = false
+ return map
+ },
+
+ ready: function(data){
+ this.data = data
+ this.info.load(data)
+ this.settings.load(data)
+ this.editor.loadFloorplan(data)
+ if (! data.shapes || data.shapes.length == 0) {
+ this.startPosition = { x: 0, y: 0, z: 0, rotationX: 0, rotationY: Math.PI/2 }
+ }
+ else {
+ this.startPosition = data.startPosition
+ }
+ this.notice.hide()
+ this.settings.show()
+ },
+
+ hideExtras: function(){
+ },
+
+ pickWall: function(wall, pos){
+ },
+
+})
diff --git a/public/assets/javascripts/ui/builder/BuilderInfo.js b/public/assets/javascripts/ui/builder/BuilderInfo.js
index 9a7dbf9..aa58d6e 100644
--- a/public/assets/javascripts/ui/builder/BuilderInfo.js
+++ b/public/assets/javascripts/ui/builder/BuilderInfo.js
@@ -40,8 +40,8 @@ var BuilderInfo = View.extend({
load: function(data){
this.$viewHeight.unitVal( window.viewHeight = data.viewHeight || app.defaults.viewHeight )
- this.$units.val( "ft" )
- this.$unitName.html( "ft" )
+ this.$units.val( data.units || "ft" )
+ this.$unitName.html( data.units || "ft" )
if (Rooms.regions.length == 0) {
this.changeHeightGlobal(true)
diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js
index b319404..5aa88e9 100644
--- a/public/assets/javascripts/ui/editor/EditorSettings.js
+++ b/public/assets/javascripts/ui/editor/EditorSettings.js
@@ -41,7 +41,12 @@ var EditorSettings = FormView.extend({
this.action = data.isNew ? this.createAction : this.updateAction
this.parent.data = data
- data.rooms && Rooms.deserialize(data.rooms, data.walls)
+ if (data.shapes && data.shapes.length) {
+ Rooms.deserializeFromShapes(data, data.walls)
+ }
+ else if (data.rooms) {
+ Rooms.deserialize(data.rooms, data.walls)
+ }
if (data.startPosition) {
scene.camera.move(data.startPosition)
this.startPosition = data.startPosition
@@ -77,6 +82,7 @@ var EditorSettings = FormView.extend({
data.privacy && this.$privacy.find("[value=" + data.privacy + "]").prop("checked", "checked")
data.media && Scenery.deserialize(data.media)
+ data.sculpture && Sculpture.deserialize(data.sculpture)
}
},
@@ -112,6 +118,7 @@ var EditorSettings = FormView.extend({
clear: function(e){
e.preventDefault()
Scenery.removeAll()
+ Sculpture.removeAll()
},
destroy: function(){
@@ -187,10 +194,16 @@ var EditorSettings = FormView.extend({
fd.append( "description", this.$description.val() )
fd.append( "privacy", this.$privacy.filter(":checked").val() == "private" )
fd.append( "viewHeight", window.viewHeight )
- fd.append( "rooms", JSON.stringify( Rooms.serialize() ) )
+ if (Rooms.shapesMode) {
+ fd.append( "shapes", JSON.stringify( shapes.serialize() ) )
+ }
+ else {
+ fd.append( "rooms", JSON.stringify( Rooms.serialize() ) )
+ }
fd.append( "walls", JSON.stringify( Walls.serialize() ) )
fd.append( "colors", JSON.stringify( Walls.colors ) )
fd.append( "media", JSON.stringify( Scenery.serialize() ) )
+ fd.append( "sculpture", JSON.stringify( Sculpture.serialize() ) )
fd.append( "startPosition", JSON.stringify( this.startPosition || false ) )
fd.append( "lastPosition", JSON.stringify( app.position(scene.camera) ) )
diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js
index 50d3650..c05b373 100644
--- a/public/assets/javascripts/ui/editor/EditorView.js
+++ b/public/assets/javascripts/ui/editor/EditorView.js
@@ -2,6 +2,7 @@
var EditorView = View.extend({
el: "#editorView",
+ blueprintAction: "/api/blueprint/user/",
projectAction: "/api/project/",
layoutAction: "/api/layout/",
@@ -17,6 +18,7 @@ var EditorView = View.extend({
this.mediaUpload = new MediaUpload ({ parent: this })
this.mediaTumblr = new MediaTumblr ({ parent: this })
this.mediaEditor = new MediaEditor ({ parent: this })
+ this.sculptureEditor = new SculptureEditor ({ parent: this })
this.wallpaperPicker = new WallpaperPicker ({ parent: this })
this.colorControl = new ColorControl ({ parent: this })
this.textEditor = new TextEditor ({ parent: this })
@@ -40,6 +42,10 @@ var EditorView = View.extend({
$.get(this.layoutAction + layout, this.readyLayout.bind(this))
},
+ loadBlueprint: function(blueprint){
+ $.get(this.blueprintAction + blueprint, this.readyLayout.bind(this))
+ },
+
ready: function(data){
$("#map").hide()
@@ -56,12 +62,19 @@ var EditorView = View.extend({
},
pick: function(scenery){
- if (scenery.type == "text") {
+ if (scenery.isSculpture) {
+ this.mediaEditor.hide()
+ this.textEditor.hide()
+ this.sculptureEditor.pick(scenery)
+ }
+ else if (scenery.type == "text") {
this.mediaEditor.hide()
+ this.sculptureEditor.hide()
this.textEditor.pick(scenery)
}
else {
this.textEditor.hide()
+ this.sculptureEditor.hide()
this.mediaEditor.pick(scenery)
}
},
@@ -72,9 +85,11 @@ var EditorView = View.extend({
},
hideExtras: function(){
+ this.sculptureEditor.hide()
this.mediaEditor.hide()
this.textEditor.hide()
this.share.hide()
+ Sculpture.resize.hide()
Scenery.resize.hide()
Scenery.hovering = false
}
diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js
new file mode 100644
index 0000000..953260c
--- /dev/null
+++ b/public/assets/javascripts/ui/editor/SculptureEditor.js
@@ -0,0 +1,237 @@
+
+var SculptureEditor = FormView.extend({
+ el: "#sculptureEditor",
+
+ events: {
+ "keydown": 'taint',
+ "focus [name]": "clearMinotaur",
+ "click [data-role=play-media]": "togglePaused",
+ "mousedown [name=keyframe]": "stopPropagation",
+ "mousedown": "stopPropagation",
+ "change [name=keyframe]": "seek",
+ "change [name=autoplay]": "setAutoplay",
+ "change [name=billboard]": "setBillboard",
+ "change [name=outline]": "setOutline",
+ "change [name=outlineColor]": "setOutlineColor",
+ "change [name=loop]": "setLoop",
+ "change [name=mute]": "setMute",
+ "change [name=width]": 'changeWidth',
+ "change [name=height]": 'changeHeight',
+ "change [name=depth]": 'changeDepth',
+ "change [name=units]": 'changeUnits',
+ "click [data-role=destroy-sculpture]": "destroy",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.__super__.initialize.call(this)
+
+ this.$name = this.$("[name=name]")
+ this.$description = this.$("[name=description]")
+
+ this.$billboard = this.$("[name=billboard]")
+ this.$outline = this.$("[name=outline]")
+ this.$outlineColor = this.$("[name=outlineColor]")
+
+ // image fields
+ this.$width = this.$("[name=width]")
+ this.$height = this.$("[name=height]")
+ this.$depth = this.$("[name=depth]")
+ this.$units = this.$("[name=units]")
+
+ // video fields
+ this.$playButton = this.$("[data-role=play-media]")
+ this.$autoplay = this.$("[name=autoplay]")
+ this.$loop = this.$("[name=loop]")
+ this.$mute = this.$("[name=mute]")
+ this.$keyframe = this.$("[name=keyframe]")
+ },
+
+ toggle: function(state) {
+ if (state) {
+ this.parent.settings.toggle()
+ }
+ this.$el.toggleClass("active", state);
+ },
+
+ togglePaused: function(state){
+ var state = this.sculpture.toggle(state)
+ this.$playButton.toggleClass("paused", ! state)
+ },
+
+ pick: function(sculpture) {
+ if (this.sculpture && sculpture !== this.sculpture) {
+ this.unbind()
+ }
+
+ this.bind(sculpture)
+ this.$el.addClass("active")
+
+// app.controller.toolbar.resetMode()
+ app.controller.toolbar.resetControls()
+ Sculpture.resize.show(sculpture)
+ Sculpture.hovering = true
+
+ var media = sculpture.media
+
+ // console.log(media)
+ this.$name.val(media.title || "") // || filenameFromUrl(media.url) )
+ this.$description.val(media.description || "")
+ this.setDimensions()
+ this.$units.val( "ft" )
+
+ this.$outline.prop( 'checked', !! sculpture.outline )
+ this.$outlineColor.val( sculpture.outlineColor || "#000000" )
+ this.$billboard.prop( 'checked', !! sculpture.billboard )
+
+ switch (media.type) {
+ case "image":
+ this.$(".video").hide()
+ this.$(".audio").hide()
+ this.$(".image").show()
+ break
+
+ case "youtube":
+ case "vimeo":
+ case "video":
+ this.$(".image").hide()
+ this.$(".audio").hide()
+ this.$(".video").show()
+
+ this.$playButton.toggleClass("paused", ! this.sculpture.paused())
+ this.$autoplay.prop('checked', !! media.autoplay)
+ this.$loop.prop('checked', !! media.loop)
+ this.$mute.prop('checked', !! media.mute)
+ this.$keyframe.val( Number(media.keyframe || 0) )
+ break
+
+ case "soundcloud":
+ this.$(".image").hide()
+ this.$(".video").hide()
+ this.$(".audio").show()
+ this.$playButton.toggleClass("paused", ! this.sculpture.paused())
+ this.$autoplay.prop('checked', !! media.autoplay)
+ this.$loop.prop('checked', !! media.loop)
+ break
+ }
+ },
+
+ hide: function(sculpture){
+ if (this.sculpture) {
+ this.unbind()
+ }
+ this.toggle(false)
+ },
+
+ seek: function(){
+ var n = parseFloat( this.$keyframe.val() )
+ this.sculpture.seek(n)
+ this.tainted = true
+
+ this.sculpture.media.keyframe = n
+ },
+ setAutoplay: function(){
+ var checked = this.$autoplay.prop('checked')
+ this.sculpture.media.autoplay = checked
+ this.tainted = true
+ if (checked && this.sculpture.paused()) {
+ this.togglePaused()
+ }
+ },
+ setLoop: function(){
+ var checked = this.$loop.prop('checked')
+ this.sculpture.setLoop(checked)
+ this.tainted = true
+ },
+ setMute: function(){
+ var checked = this.$mute.prop('checked')
+ this.sculpture.media.mute = checked
+ this.sculpture.mute(checked)
+ this.tainted = true
+ },
+
+ setBillboard: function(){
+ var checked = this.$billboard.prop('checked')
+ this.sculpture.setBillboard(checked)
+ this.tainted = true
+ },
+ setOutline: function(){
+ var checked = this.$outline.prop('checked')
+ this.sculpture.setOutline(checked)
+ this.tainted = true
+ },
+ setOutlineColor: function(){
+ var color = this.$outlineColor.val()
+ this.sculpture.setOutlineColor(color)
+ this.tainted = true
+ },
+
+ setDimensions: function(){
+ if (! this.sculpture) return
+ this.$width.unitVal( Number(this.sculpture.naturalDimensions.a * this.sculpture.scale) || "" )
+ this.$height.unitVal( Number(this.sculpture.naturalDimensions.b * this.sculpture.scale) || "" )
+ this.$depth.unitVal( Number(this.sculpture.naturalDimensions.c * this.sculpture.scale) || "" )
+ this.tainted = true
+ },
+ changeWidth: function(e){
+ e.stopPropagation()
+ this.sculpture.set_scale( this.$width.unitVal() / this.sculpture.naturalDimensions.a )
+ this.setDimensions()
+ this.sculpture.updateOutline()
+ },
+ changeHeight: function(e){
+ e.stopPropagation()
+ this.sculpture.set_scale( this.$height.unitVal() / this.sculpture.naturalDimensions.b )
+ this.setDimensions()
+ this.sculpture.updateOutline()
+ },
+ changeDepth: function(e){
+ e.stopPropagation()
+ this.sculpture.set_depth( this.$depth.unitVal() )
+ this.$depth.unitVal( Number(this.sculpture.naturalDimensions.c * this.sculpture.scale) || "" )
+ this.sculpture.updateOutline()
+ },
+ changeUnits: function(){
+ app.units = this.$units.val()
+ this.$('.units').resetUnitVal()
+ },
+
+ taint: function(e){
+ e.stopPropagation()
+ this.tainted = true
+ },
+
+ bind: function(sculpture){
+ this.sculpture = sculpture
+ this.sculpture.mx.bound = true
+ this.sculpture.mx.el.classList.add("picked")
+ },
+
+ unbind: function(){
+ if (this.sculpture) {
+ this.sculpture.focused = false
+ if (this.tainted && this.sculpture.media) {
+ this.sculpture.media.title = this.$name.val()
+ this.sculpture.media.description = this.$description.val()
+ Minotaur.watch( app.router.editorView.settings )
+ }
+ if (this.sculpture.mx) {
+ this.sculpture.mx.bound = false
+ this.sculpture.mx.el.classList.remove("picked")
+ }
+ }
+ this.tainted = false
+ this.sculpture = null
+ },
+
+ destroy: function(){
+ var sculpture = this.sculpture
+ this.hide()
+
+ sculpture.remove()
+
+ this.tainted = false
+ this.sculpture = null
+ },
+
+})
diff --git a/public/assets/javascripts/ui/lib/AnimatedView.js b/public/assets/javascripts/ui/lib/AnimatedView.js
new file mode 100644
index 0000000..3c50b0a
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/AnimatedView.js
@@ -0,0 +1,31 @@
+var AnimatedView = View.extend({
+
+ _animating: false,
+ last_t: 0,
+
+ startAnimating: function(){
+ if (this._animating) return
+ this._animating = true
+ this._animate()
+ },
+
+ stopAnimating: function(){
+ this._animating = false
+ },
+
+ _animate: function(t){
+ if (! this._animating) return
+
+ requestAnimationFrame(this._animate.bind(this))
+
+ var dt = t - this.last_t
+ this.last_t = t
+
+ if (! t) return
+
+ this.animate(t, dt)
+ },
+
+ animate: function(t, dt){},
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/ConfirmModal.js b/public/assets/javascripts/ui/lib/ConfirmModal.js
index a72b31e..7d9da67 100644
--- a/public/assets/javascripts/ui/lib/ConfirmModal.js
+++ b/public/assets/javascripts/ui/lib/ConfirmModal.js
@@ -4,21 +4,31 @@ var ConfirmModal = new( ModalFormView.extend({
el: ".mediaDrawer.confirm",
events: {
- "click .yes": "advance",
- "click .no": "hide",
+ "click .yes": "agree",
+ "click .no": "cancel",
},
- confirm: function(question, callback){
+ confirm: function(question, agreeCallback, cancelCallback){
this.$(".question").empty().append(question)
- this.callback = callback
+ this.agreeCallback = agreeCallback
+ this.cancelCallback = cancelCallback
this.show()
},
- advance: function(e){
+ agree: function(e){
e && e.preventDefault()
this.hide()
- this.callback && this.callback()
- this.callback = null
+ this.agreeCallback && this.agreeCallback()
+ this.agreeCallback = null
+ this.cancelCallback = null
+ },
+
+ cancel: function(e){
+ e && e.preventDefault()
+ this.hide()
+ this.cancelCallback && this.cancelCallback()
+ this.agreeCallback = null
+ this.cancelCallback = null
}
}) ) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/FormView.js b/public/assets/javascripts/ui/lib/FormView.js
index f5845e7..33effc8 100644
--- a/public/assets/javascripts/ui/lib/FormView.js
+++ b/public/assets/javascripts/ui/lib/FormView.js
@@ -63,7 +63,7 @@ var FormView = View.extend({
save: function(e, successCallback, errorCallback){
e && e.preventDefault()
- this.$errors.hide().css("opacity", 0.0);
+ this.$errors && this.$errors.hide().css("opacity", 0.0);
if (this.validate) {
var errors = this.validate()
diff --git a/public/assets/javascripts/ui/lib/LabColorPicker.js b/public/assets/javascripts/ui/lib/LabColorPicker.js
index 7ddcdd5..2c8fb90 100644
--- a/public/assets/javascripts/ui/lib/LabColorPicker.js
+++ b/public/assets/javascripts/ui/lib/LabColorPicker.js
@@ -1,9 +1,12 @@
var LabColorPicker = function (parent, w, h) {
var base = this
var canvas = this.canvas = document.createElement('canvas')
- var ctx = this.ctx = canvas.getContext('2d')
- var imageData = ctx.createImageData(w,h)
- var data = imageData.data
+ canvas.width = w
+ canvas.height = h
+ var ctx = this.ctx = canvas.getContext('2d-lodpi')
+// canvas.className = "colorPicker"
+// var imageData = ctx.createImageData(w, h)
+// var data = imageData.data
var cursor = this.cursor = document.createElement("div")
cursor.className = "colorPickerCursor"
@@ -15,10 +18,6 @@ var LabColorPicker = function (parent, w, h) {
brightnessControl.setAttribute("max", "110")
brightnessControl.setAttribute("value", "0")
- canvas.width = w
- canvas.height = h
- canvas.className = "colorPicker"
-
var ww = w-1
var hh = h-1
@@ -84,11 +83,14 @@ var LabColorPicker = function (parent, w, h) {
}
this.paint = function() {
val = clamp(val, L_range[0], L_range[1])
- var x, y, t
- for (var i = 0; i < w; i++) {
- for (var j = 0; j < h; j++) {
- x = mix( i/ww, a_range[0], a_range[1] )
- y = mix( j/hh, b_range[0], b_range[1] )
+ var imageData = ctx.createImageData(canvas.width, canvas.height)
+ var data = imageData.data
+ var x, y, t, cw = imageData.width, ch = imageData.height
+ var cww = cw-1, chh = ch-1
+ for (var i = 0; i < cw; i++) {
+ for (var j = 0; j < ch; j++) {
+ x = mix( i/cww, a_range[0], a_range[1] )
+ y = mix( j/chh, b_range[0], b_range[1] )
t = (j*w + i) * 4
rgb = xyz2rgb(hunterlab2xyz(val, x, y))
data[t] = Math.round( rgb[0] )
diff --git a/public/assets/javascripts/ui/lib/ModalView.js b/public/assets/javascripts/ui/lib/ModalView.js
index 6f1c729..e0070ce 100644
--- a/public/assets/javascripts/ui/lib/ModalView.js
+++ b/public/assets/javascripts/ui/lib/ModalView.js
@@ -35,6 +35,11 @@ var ModalView = View.extend({
$("body").removeClass("noOverflow");
},
+ hideClose: function(){
+ $("#fixed_close").removeClass("active")
+ $("#fixed_close").unbind("click", this.hide.bind(this))
+ },
+
close: function(){
if (window.isModalView) {
window.location.pathname = "/"
diff --git a/public/assets/javascripts/ui/lib/Parser.js b/public/assets/javascripts/ui/lib/Parser.js
index 411f425..ab9d08d 100644
--- a/public/assets/javascripts/ui/lib/Parser.js
+++ b/public/assets/javascripts/ui/lib/Parser.js
@@ -62,10 +62,11 @@ var Parser = {
dataType: "jsonp",
data: {
id: id,
- key: "AIzaSyDYPKGD0-_VRBWpUYRmX8Qg6BtWmcPU_cM",
+ key: "AIzaSyCMlxLNawPWFwOIsrEz3bwfl_gZgkQwfMk",
part: "id,contentDetails,snippet,status",
},
success: function(result){
+ console.log(result.items)
var res = result.items[0]
done({
url: url,
@@ -279,4 +280,4 @@ var Parser = {
},
};
-Parser.lookup = _.indexBy(Parser.integrations, 'type');
+Parser.lookup = _.keyBy(Parser.integrations, 'type');
diff --git a/public/assets/javascripts/ui/lib/ToggleableView.js b/public/assets/javascripts/ui/lib/ToggleableView.js
new file mode 100644
index 0000000..371629f
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/ToggleableView.js
@@ -0,0 +1,19 @@
+var ToggleableView = View.extend({
+
+ toggle: function(state){
+ this.$el.toggleClass("active", state)
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+
+ hide: function(){
+ this.toggle(false)
+ },
+
+ visible: function(){
+ return this.$el.hasClass("active")
+ }
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/Toolbar.js b/public/assets/javascripts/ui/lib/Toolbar.js
new file mode 100644
index 0000000..a9ce51c
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/Toolbar.js
@@ -0,0 +1,22 @@
+var Toolbar = Fiber.extend(function(base){
+ var exports = {}
+ exports.init = function(rapper){
+ this.rapper = (typeof rapper == "string") ? $(rapper)[0] : rapper
+ this.tools = {}
+ this.els = {}
+ }
+ exports.add = function(role, fn){
+ var self = this
+ this.tools[role] = fn
+ this.els[role] = $("[data-role=" + role + "]", self.rapper)
+ this.els[role].click(function(){
+ $(".active", self.rapper).removeClass('active')
+ $(this).addClass('active')
+ fn()
+ })
+ }
+ exports.pick = function(role){
+ this.els[role].trigger("click")
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/reader/MediaPlayer.js b/public/assets/javascripts/ui/reader/MediaPlayer.js
index 8424d9c..8e65976 100644
--- a/public/assets/javascripts/ui/reader/MediaPlayer.js
+++ b/public/assets/javascripts/ui/reader/MediaPlayer.js
@@ -1,5 +1,5 @@
-var MediaPlayer = FormView.extend({
+var MediaPlayer = View.extend({
el: "#mediaPlayer",
events: {
diff --git a/public/assets/javascripts/ui/reader/ReaderView.js b/public/assets/javascripts/ui/reader/ReaderView.js
index 617a145..43e81d8 100644
--- a/public/assets/javascripts/ui/reader/ReaderView.js
+++ b/public/assets/javascripts/ui/reader/ReaderView.js
@@ -31,7 +31,12 @@ var ReaderView = View.extend({
this.tracker = new Tracker ({ mode: mode })
- $.get(this.projectAction + name, this.ready.bind(this))
+ if ('vvalls_data' in window) {
+ this.ready(window.vvalls_data)
+ }
+ else {
+ $.get(this.projectAction + name, this.ready.bind(this))
+ }
},
getQS: function(){
@@ -71,9 +76,15 @@ var ReaderView = View.extend({
},
build: function(data){
- data.rooms && Rooms.deserialize(data.rooms)
+ if (data.shapes.length) {
+ Rooms.deserializeFromShapes(data)
+ }
+ else {
+ Rooms.deserialize(data.rooms)
+ }
data.walls && Walls.deserialize(data.walls)
data.media && Scenery.deserialize(data.media)
+ data.sculpture && Sculpture.deserialize(data.sculpture)
data.startPosition && scene.camera.move(data.startPosition)
cam.y = window.viewHeight = data.viewHeight || app.defaults.viewHeight
@@ -84,9 +95,12 @@ var ReaderView = View.extend({
Walls.setColor[mode](colors[mode])
})
- editor.permissions.clear()
+ window.editor && editor.permissions.clear()
- this.listen()
+ // disable until we start using spinning again
+ // this.listen()
+
+ app.tube("site-ready")
},
listen: function(){
diff --git a/public/assets/javascripts/ui/reader/Tracker.js b/public/assets/javascripts/ui/reader/Tracker.js
index ce32c59..d2dec39 100644
--- a/public/assets/javascripts/ui/reader/Tracker.js
+++ b/public/assets/javascripts/ui/reader/Tracker.js
@@ -1,8 +1,12 @@
-(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
-(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
-m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
-})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
-
+if (window.location.host.indexOf("lvh.me") === -1) {
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+}
+else {
+ ga = function(){}
+}
ga('create', 'UA-56883705-1', 'auto');
ga('send', 'pageview');
diff --git a/public/assets/javascripts/ui/reader/_router.js b/public/assets/javascripts/ui/reader/_router.js
new file mode 100644
index 0000000..f3b121b
--- /dev/null
+++ b/public/assets/javascripts/ui/reader/_router.js
@@ -0,0 +1,24 @@
+
+var SiteRouter = Router.extend({
+ el: "body",
+
+ initialize: function(){
+ app.launch()
+ if (app.unsupported) return
+
+ this.readerView = app.controller = new ReaderView()
+ this.readerView.load()
+
+ $("body").removeClass("loading")
+ }
+
+})
+
+var editor = {
+ permissions: new Permissions({
+ 'pick': true,
+ 'move': true,
+ 'resize': true,
+ 'destroy': false,
+ })
+}
diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js
new file mode 100644
index 0000000..c1dc9f8
--- /dev/null
+++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js
@@ -0,0 +1,290 @@
+
+var EditSubscriptionModal = ModalView.extend({
+ el: ".mediaDrawer.editSubscription",
+ action: "/api/subscription",
+ syncAction: "/api/subscription/sync",
+ updateAction: "/api/subscription",
+ destroyAction: "/api/subscription/destroy",
+
+ fixedClose: true,
+ editing: false,
+ subscriber: null,
+ tempSubscriber: null,
+
+ events: {
+ "click [data-role='addLayouts']": 'addLayouts',
+ "click [data-role='changePlan']": 'changePlan',
+ "click [data-role='cancelSubscription']": 'destroy',
+ "click .gear": 'sync',
+ "click .planList button": 'followLink',
+
+ "click [data-role=showEditMenu]": "editMode",
+
+ "click [data-role=closeMenu]": "resetMode",
+
+ "input [data-role=basicLayoutInput]": "updateQuantity",
+ "input [data-role=proLayoutInput]": "updateQuantity",
+ "click [data-role=saveChanges]": "saveChanges",
+
+ "change [name=planRadio]": "updatePlan",
+ "click [data-role=savePlan]": "savePlan",
+
+ "submit form": "preventDefault",
+ },
+
+ initialize: function(){
+ // this.parent = opt.parent
+ this.__super__.initialize.call(this)
+
+ // two sections
+ this.$freePlan = this.$(".freePlan")
+ this.$paidPlan = this.$(".paidPlan")
+
+ // subscription table
+ this.$planInfo = this.$(".planInfo")
+ this.$planRow = this.$(".planRow")
+ this.$basicLayoutRow = this.$(".basicLayoutRow")
+ this.$proLayoutRow = this.$(".proLayoutRow")
+ this.$totalRow = this.$(".totalRow")
+ this.$planList = this.$(".planList")
+
+ this.$billingInterval = this.$("[data-role=billingInterval]")
+
+ // plan stuff
+ this.$planName = this.$("[data-role=planName]")
+ this.$planCost = this.$("[data-role=planCost]")
+ this.$planTotal = this.$("[data-role=planTotal]")
+
+ this.$basicPlanName = this.$("[data-role=basicPlanName]")
+ this.$basicPlanCost = this.$("[data-role=basicPlanCost]")
+
+ this.$proPlanName = this.$("[data-role=proPlanName]")
+ this.$proPlanCost = this.$("[data-role=proPlanCost]")
+
+ // basic + pro layout stuff
+ this.$basicLayoutCost = this.$("[data-role=basicLayoutCost]")
+ this.$basicLayoutQuantity = this.$("[data-role=basicLayoutQuantity]")
+ this.$basicLayoutTotal = this.$("[data-role=basicLayoutTotal]")
+
+ this.$proLayoutCost = this.$("[data-role=proLayoutCost]")
+ this.$proLayoutQuantity = this.$("[data-role=proLayoutQuantity]")
+ this.$proLayoutTotal = this.$("[data-role=proLayoutTotal]")
+
+ // menus.. main menu
+ this.$showEditMenu = this.$("[data-role=showEditMenu]")
+ this.$cancelSubscription = this.$("[data-role=cancelSubscription]")
+
+ // three submenus
+ this.$editMenu = this.$("[data-role=editMenu]")
+ this.$planMenu = this.$("[data-role=planMenu]")
+
+ this.$buyLayouts = this.$("[data-role=buyLayouts]")
+ this.$closeMenu = this.$("[data-role=closeMenu]")
+ this.$changePlan = this.$("[data-role=changePlan]")
+
+ // input fields
+ this.$basicLayoutInput = this.$("[data-role=basicLayoutInput]")
+ this.$proLayoutInput = this.$("[data-role=proLayoutInput]")
+ this.$planRadio = this.$("[name=planRadio]")
+ this.$basicPlanInput = this.$("[data-role=basicPlanInput]")
+ this.$proPlanInput = this.$("[data-role=proPlanInput]")
+
+ this.$gear = this.$(".gear")
+ },
+
+ plan_levels: {
+ free: 0,
+ basic: 1,
+ pro: 2,
+ custom: 3,
+ artist: 4,
+ },
+
+ loaded: false,
+ load: function(){
+ if (this.loaded) { return this.show() }
+ $.get(this.action, this.didLoad.bind(this))
+ },
+ didLoad: function(data){
+ this.loaded = true
+ this.plans = data.plans
+ if (data.subscription) {
+ this.subscriber = data.subscription
+ }
+ else if (data.error) {
+ // ...no subscription found
+ this.subscriber = null
+ }
+ return this.show()
+ },
+ followLink: function(e){
+ e.preventDefault();
+ window.location.href = $(e.target).closest("a").attr("href")
+ },
+
+ show: function(){
+ this.$gear.removeClass("turning")
+ if (! this.subscriber) {
+ this.$freePlan.show()
+ this.$paidPlan.hide()
+ this.$planList.load("/partials/plans", function(){
+ this.$(".free_plan_info").remove()
+ this.__super__.show.call(this)
+ }.bind(this))
+ return
+ }
+
+ this.$freePlan.hide()
+ this.$paidPlan.show()
+
+ this.resetMode()
+
+ this.__super__.show.call(this)
+ },
+ reset: function(){
+ var subscriber = this.subscriber
+ var plan = this.getPlan(subscriber.plan_type)
+ this.displayTotals(subscriber, plan)
+ },
+ getPlan: function(plan_type){
+ return this.plans[ this.plan_levels[ plan_type ] ]
+ },
+ calculateTotals: function(subscriber, plan){
+ var t = {}
+ t.is_pro = subscriber.plan_type == "pro"
+ t.is_monthly = subscriber.plan_period == "monthly"
+ t.plan_price = t.is_monthly ? plan.monthly_price : plan.yearly_price
+ t.basic_layout_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.basic_layout_yearly_price
+ t.basic_layout_total = subscriber.basic_layouts * t.basic_layout_price
+ t.pro_layout_price = t.is_monthly ? plan.pro_layout_monthly_price : plan.pro_layout_yearly_price
+ t.pro_layout_total = t.is_pro ? subscriber.pro_layouts * t.pro_layout_price : 0
+ t.plan_total = t.plan_price + t.basic_layout_total + t.pro_layout_total
+ return t
+ },
+ displayTotals: function(subscriber, plan){
+ var totals = this.calculateTotals(subscriber, plan)
+
+ this.$basicPlanName.html ( this.plans[1].name )
+ this.$proPlanName.html ( this.plans[2].name )
+ this.$basicPlanCost.toDollars ( totals.is_monthly ? this.plans[1].monthly_price : this.plans[2].yearly_price)
+ this.$proPlanCost.toDollars ( totals.is_monthly ? this.plans[2].monthly_price : this.plans[2].yearly_price)
+
+ this.$planName.html ( plan.name )
+ this.$planCost.toDollars ( totals.plan_price )
+
+ this.$billingInterval.html ( totals.is_monthly ? "mo." : "yr." )
+ this.$basicLayoutRow.toggle ( subscriber.basic_layouts > 0 )
+ this.$proLayoutRow.toggle ( totals.is_pro && subscriber.pro_layouts > 0)
+
+ this.$basicLayoutCost.toDollars ( totals.basic_layout_price )
+ this.$basicLayoutQuantity.html ( subscriber.basic_layouts )
+ this.$basicLayoutTotal.toDollars ( totals.basic_layout_total )
+
+ this.$proLayoutCost.toDollars ( totals.pro_layout_price )
+ this.$proLayoutQuantity.html ( subscriber.pro_layouts )
+ this.$proLayoutTotal.toDollars ( totals.pro_layout_total )
+
+ this.$planTotal.toDollars ( totals.plan_total )
+ },
+
+ editMode: function(e){
+ e && e.preventDefault()
+
+ this.editing = true
+ this.$el.addClass("editing")
+ this.tempSubscriber = defaults({}, this.subscriber)
+ this.$basicLayoutInput.val( this.subscriber.basic_layouts )
+ this.$proLayoutInput.val( this.subscriber.pro_layouts )
+ this.$basicLayoutRow.show()
+ this.$proLayoutRow.toggle(this.subscriber.plan_type == "pro")
+ switch (this.subscriber.plan_type) {
+ case 'basic': this.$basicPlanInput.prop('checked', true); break;
+ case 'pro': this.$proPlanInput.prop('checked', true); break;
+ }
+ },
+ resetMode: function(e){
+ e && e.preventDefault()
+ this.editing = false
+ this.$el.removeClass("editing")
+ this.reset()
+ },
+
+ updateQuantity: function(e){
+ e && e.preventDefault()
+ var plan = this.getPlan( this.tempSubscriber.plan_type )
+ this.tempSubscriber.basic_layouts = clamp( this.$basicLayoutInput.int() || 0, 0, 100)
+ this.tempSubscriber.pro_layouts = clamp( this.$proLayoutInput.int() || 0, 0, 100)
+
+ this.$basicLayoutInput.val(this.tempSubscriber.basic_layouts)
+ this.$proLayoutInput.val(this.tempSubscriber.pro_layouts)
+ this.displayTotals(this.tempSubscriber, plan)
+ this.$basicLayoutRow.show()
+ this.$proLayoutRow.toggle(this.tempSubscriber.plan_type == "pro")
+ },
+ saveChanges: function(e){
+ e && e.preventDefault()
+ var is_changed = false
+ var diff = {}
+ "plan_type basic_layouts pro_layouts".split(" ").forEach(function(field){
+ diff[field] = this.tempSubscriber[field]
+ if (this.tempSubscriber[field] != this.subscriber[field]) {
+ is_changed = true
+ }
+ }.bind(this))
+
+ if (is_changed) {
+ this.update(diff)
+ }
+ this.subscriber = this.tempSubscriber
+ this.resetMode()
+ },
+
+ updatePlan: function(e){
+ e && e.preventDefault()
+ this.tempSubscriber.plan_type = this.$("[name=planRadio]:checked").val()
+ this.updateQuantity()
+ },
+
+ sync: function(){
+ this.$gear.addClass("turning")
+ $.ajax({
+ url: this.syncAction,
+ type: "put",
+ data: { _csrf: $("[name=_csrf]").val() },
+ success: this.didLoad.bind(this)
+ })
+ },
+
+ update: function(data){
+ data['_csrf'] = $("[name=_csrf]").val()
+ this.$gear.addClass("turning")
+ $.ajax({
+ url: this.updateAction,
+ type: "put",
+ data: data,
+ success: function(data){
+ this.$gear.removeClass("turning")
+ }.bind(this)
+ })
+ },
+
+ destroy: function(e){
+ e.preventDefault()
+ var msg = "Are you sure you want to cancel your subscription?"
+ ConfirmModal.confirm(msg, function(){
+ $.ajax({
+ url: this.destroyAction,
+ type: "delete",
+ data: { _csrf: $("[name=_csrf]").val() },
+ success: function(data){
+ this.subscriber = null
+ this.didLoad(data)
+ }.bind(this)
+ })
+ }.bind(this),
+ function(){
+ this.show()
+ }.bind(this))
+ },
+
+})
diff --git a/public/assets/javascripts/ui/site/HomeView.js b/public/assets/javascripts/ui/site/HomeView.js
index a04bac1..20452bd 100644
--- a/public/assets/javascripts/ui/site/HomeView.js
+++ b/public/assets/javascripts/ui/site/HomeView.js
@@ -22,7 +22,7 @@ var HomeView = View.extend({
player.api('play')
})
- $('.videoModal .ion-ios7-close-empty').click( function(){
+ $('.videoModal .ion-ios-close-empty').click( function(){
player.api('pause')
hide()
})
diff --git a/public/assets/javascripts/ui/site/LayoutsIndex.js b/public/assets/javascripts/ui/site/LayoutsIndex.js
new file mode 100644
index 0000000..f7272bb
--- /dev/null
+++ b/public/assets/javascripts/ui/site/LayoutsIndex.js
@@ -0,0 +1,85 @@
+
+var LayoutsIndex = View.extend({
+
+ initialize: function(){
+ this.$templates = this.$(".templates")
+ this.$templatesList = this.$(".templates-list")
+ this.$noTemplates = this.$(".no-templates")
+ this.$form = this.$("form")
+
+ this.$userTemplatesList = this.$(".userTemplatesList")
+ this.$blueprintsList = this.$(".blueprintsList")
+ this.$newBlueprintButton = this.$("[data-role='create-new-blueprint']")
+ },
+
+ load: function(type){
+ this.$templates.children("span").remove()
+
+ $.get(this.action, this.populate.bind(this))
+ },
+
+ populate: function(data){
+ if (! data.layouts.length) {
+ this.$templates.hide()
+ this.$form.hide()
+ this.$noTemplates.show()
+ }
+ this.$templatesList.empty()
+ data.layouts.forEach(function(room){
+ var $span = $("<span>")
+ $span.data("slug", room.slug)
+
+ var $label = $("<label>")
+ $label.html( room.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + room.photo + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+ this.show()
+ }
+
+})
+
+
+
+var ProjectsModal = ModalView.extend(LayoutsIndex.prototype).extend({
+ el: ".mediaDrawer.projects",
+
+ action: "/api/project",
+
+ events: {
+ "click .templates span": 'toggleActive',
+ "submit form": 'newProject',
+ },
+
+ populate: function(data){
+ if (! data.length) {
+ app.router.newProject()
+ }
+ else {
+ this.__super__.populate.call(this, data)
+ }
+ },
+
+ toggleActive: function(e){
+ e.preventDefault()
+ this.$(".templates .active").removeClass("active")
+ var $layout = $(e.currentTarget)
+ $layout.addClass("active")
+
+ // actually do
+ window.location.pathname = "/project/" + $layout.data("slug") + "/edit"
+ },
+
+ newProject: function(e){
+ e && e.preventDefault()
+ window.location.pathname = "/project/new"
+ }
+
+})
+
diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js
index 5974fc3..427a376 100644
--- a/public/assets/javascripts/ui/site/LayoutsModal.js
+++ b/public/assets/javascripts/ui/site/LayoutsModal.js
@@ -1,27 +1,52 @@
+var LayoutsModal = ModalView.extend(LayoutsIndex.prototype).extend({
+ el: ".mediaDrawer.layouts",
-var LayoutsIndex = View.extend({
+ action: "/api/layout",
- initialize: function(){
- this.$templates = this.$(".templates")
- this.$templatesList = this.$(".templates-list")
- this.$noTemplates = this.$(".no-templates")
- this.$form = this.$("form")
+ events: {
+ "click [data-role='create-new-layout']": 'createNewLayout',
+ "click [data-role='create-new-blueprint']": 'createNewBlueprint',
+ "click .templates span": 'pick',
},
+
+ pick: function(e){
+ e.preventDefault()
+ var layout = $(e.currentTarget).data("slug")
+ var isBlueprint = $(e.currentTarget).data("blueprint")
- load: function(type){
- this.$templates.children("span").remove()
+ if (! layout || ! layout.length) return
- $.get(this.action, this.populate.bind(this))
+ if (isBlueprint) {
+ window.location.pathname = "/blueprint/" + layout
+ }
+ else {
+ window.location.pathname = "/layout/" + layout
+ }
+ },
+
+ createNewLayout: function(e){
+ e.preventDefault()
+ window.location.pathname = "/layout/new"
+ },
+
+ createNewBlueprint: function(e){
+ e.preventDefault()
+ window.location.pathname = "/blueprint/new"
},
populate: function(data){
- if (! data.length) {
+/*
+ if (data.user.plan_level < 1 && data.projectCount == 1) {
+ // show lockout message
+ }
+*/
+ if (! data.layouts.length && ! data.user_layouts.length) {
this.$templates.hide()
this.$form.hide()
this.$noTemplates.show()
}
this.$templatesList.empty()
- data.forEach(function(room){
+ data.layouts.forEach(function(room){
var $span = $("<span>")
$span.data("slug", room.slug)
@@ -36,103 +61,46 @@ var LayoutsIndex = View.extend({
this.$templatesList.append($span)
}.bind(this))
- this.show()
- }
-
-})
-var ProjectsModal = ModalView.extend(LayoutsIndex.prototype).extend({
- el: ".mediaDrawer.projects",
-
- action: "/api/project",
-
- events: {
- "click .templates span": 'toggleActive',
- "submit form": 'newProject',
- },
-
- populate: function(data){
- if (! data.length) {
- app.router.newProject()
- }
- else {
- this.__super__.populate.call(this, data)
- }
- },
-
- toggleActive: function(e){
- e.preventDefault()
- this.$(".templates .active").removeClass("active")
- var $layout = $(e.currentTarget)
- $layout.addClass("active")
-
- // actually do
- window.location.pathname = "/project/" + $layout.data("slug") + "/edit"
- },
-
- newProject: function(e){
- e && e.preventDefault()
- window.location.pathname = "/project/new"
- }
-
-})
-
-
-var LayoutsModal = ModalView.extend(LayoutsIndex.prototype).extend({
- el: ".mediaDrawer.layouts",
-
- action: "/api/layout",
-
- events: {
- "click .templates span": 'toggleActive',
- "submit form": 'newLayout',
- },
-
- toggleActive: function(e){
- e.preventDefault()
- this.$(".templates .active").removeClass("active")
- var $layout = $(e.currentTarget)
- $layout.addClass("active")
+ data.user_layouts.forEach(function(room){
+ var $span = $("<span>")
+ $span.data("slug", room.slug)
+
+ var $label = $("<label>")
+ $label.html( room.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + room.photo + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+
+ data.blueprints.forEach(function(blueprint){
+ var $span = $("<span>")
+ $span.data("slug", blueprint.slug)
+ $span.data("blueprint", true)
+
+ var $label = $("<label>")
+ $label.html( blueprint.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + blueprint.url + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
- // actually do
- window.location.pathname = "/layout/" + $layout.data("slug")
+ this.show()
},
-
+
newLayout: function(e){
e && e.preventDefault()
window.location.pathname = "/layout/new"
}
})
-
-
-var NewProjectModal = ModalView.extend(LayoutsIndex.prototype).extend({
- el: ".mediaDrawer.newProject",
-
- action: "/api/layout",
-
- events: {
- "click [data-role='create-new-layout']": 'createNewLayout',
- "click .templates span": 'choose',
- "submit form": 'choose',
- },
-
- toggleActive: function(e){
- e.preventDefault()
- this.$(".templates .active").removeClass("active")
- $(e.currentTarget).addClass("active")
- },
-
- choose: function(e){
- e && e.preventDefault()
-// var layout = this.$(".templates .active").data("slug")
- var layout = $(e.currentTarget).data("slug")
- if (! layout || ! layout.length) return
- window.location.pathname = "/project/new/" + layout
- },
-
- createNewLayout: function(){
- window.location.pathname = "/project/new/empty"
- },
-
-})
diff --git a/public/assets/javascripts/ui/site/NewProjectModal.js b/public/assets/javascripts/ui/site/NewProjectModal.js
new file mode 100644
index 0000000..5e79929
--- /dev/null
+++ b/public/assets/javascripts/ui/site/NewProjectModal.js
@@ -0,0 +1,118 @@
+var NewProjectModal = ModalView.extend(LayoutsIndex.prototype).extend({
+ el: ".mediaDrawer.newProject",
+
+ action: "/api/layout",
+
+ events: {
+ "click [data-role='create-new-layout']": 'createNewLayout',
+ "click [data-role='create-new-blueprint']": 'createNewBlueprint',
+ "click .templates span": 'pick',
+ },
+
+ toggleActive: function(e){
+ e.preventDefault()
+ this.$(".templates .active").removeClass("active")
+ $(e.currentTarget).addClass("active")
+ },
+
+ pick: function(e){
+ e && e.preventDefault()
+// var layout = this.$(".templates .active").data("slug")
+ var layout = $(e.currentTarget).data("slug")
+ var isBlueprint = $(e.currentTarget).data("blueprint")
+ if (! layout || ! layout.length) return
+
+ if (isBlueprint) {
+ window.location.pathname = "/project/blueprint/" + layout
+ }
+ else {
+ window.location.pathname = "/project/new/" + layout
+ }
+ },
+
+ createNewLayout: function(e){
+ e.preventDefault()
+ window.location.pathname = "/project/new/empty"
+ },
+
+ createNewBlueprint: function(e){
+ e.preventDefault()
+ window.location.pathname = "/blueprint/new"
+ },
+
+ populate: function(data){
+/*
+ if (data.user.plan_level < 1 && data.projectCount == 1) {
+ // show lockout message
+ this.$newBlueprintButton.hide()
+ }
+*/
+ if (! data.layouts.length && ! data.user_layouts.length) {
+ this.$templates.hide()
+ this.$form.hide()
+ this.$noTemplates.show()
+ }
+ if (! data.blueprints.length) {
+ this.$blueprintsList.parent().hide()
+ }
+ if (! data.user_layouts.length) {
+ this.$userTemplatesList.parent().hide()
+ }
+
+ this.$templatesList.empty()
+ data.layouts.forEach(function(room){
+ var $span = $("<span>")
+ $span.data("slug", room.slug)
+
+ var $label = $("<label>")
+ $label.html( room.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + room.photo + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+
+ data.user_layouts.forEach(function(room){
+ var $span = $("<span>")
+ $span.data("slug", room.slug)
+
+ var $label = $("<label>")
+ $label.html( room.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + room.photo + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+
+ data.blueprints.forEach(function(blueprint){
+ if (! blueprint.slug) { return }
+
+ var $span = $("<span>")
+ $span.data("blueprint", true)
+ $span.data("slug", blueprint.slug)
+
+ var $label = $("<label>")
+ $label.html( blueprint.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + blueprint.url + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+
+ this.show()
+ },
+
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/site/StaffView.js b/public/assets/javascripts/ui/site/StaffView.js
index 0398f71..97f86c2 100644
--- a/public/assets/javascripts/ui/site/StaffView.js
+++ b/public/assets/javascripts/ui/site/StaffView.js
@@ -4,11 +4,15 @@ var StaffView = View.extend({
events: {
"click #toggle-staff": "toggleStaff",
"click #toggle-featured": "toggleFeatured",
+ "click #toggle-stock": "toggleStock",
+ "click #toggle-artist": "toggleArtist",
},
initialize: function() {
this.$toggleStaff = $("#toggle-staff")
this.$toggleFeatured = $("#toggle-featured")
+ this.$toggleStock = $("#toggle-stock")
+ this.$toggleArtist = $("#toggle-artist")
this.$mediaEmbed = $("#media-embed")
if (this.$toggleStaff.length && this.$toggleStaff.data().isstaff) {
this.$toggleStaff.html("Is Staff")
@@ -16,6 +20,12 @@ var StaffView = View.extend({
if (this.$toggleFeatured.length && this.$toggleFeatured.data().featured) {
this.$toggleFeatured.html("Featured Project")
}
+ if (this.$toggleStock.length && this.$toggleStock.data().stock) {
+ this.$toggleStock.html("Layout is Stock")
+ }
+ if (this.$toggleArtist.length && this.$toggleArtist.data().isartist) {
+ this.$toggleArtist.html("Is Artist")
+ }
if (this.$mediaEmbed.length) {
var media = this.$mediaEmbed.data()
this.$mediaEmbed.html( Parser.tag( media ) )
@@ -67,6 +77,41 @@ var StaffView = View.extend({
$("#isFeaturedProject").html(data.state ? "yes" : "no")
}.bind(this)
})
- },
+ },
+
+ toggleStock: function(){
+ var state = ! this.$toggleStock.data().stock
+ $.ajax({
+ type: "put",
+ dataType: "json",
+ url: window.location.href + "/stock",
+ data: {
+ state: state,
+ _csrf: $("#_csrf").val(),
+ },
+ success: function(data){
+ this.$toggleStock.data("stock", data.state)
+ this.$toggleStock.html(data.state ? "Stock Layout" : "Make this layout Stock")
+ $("#isStockLayout").html(data.state ? "yes" : "no")
+ }.bind(this)
+ })
+ },
+ toggleArtist: function(){
+ var state = ! this.$toggleArtist.data().isartist
+ $.ajax({
+ type: "put",
+ dataType: "json",
+ url: window.location.href + "/artist",
+ data: {
+ state: state,
+ _csrf: $("#_csrf").val(),
+ },
+ success: function(data){
+ this.$toggleArtist.data("stock", data.state)
+ this.$toggleArtist.html(data.state ? "Is Artist" : "Make Artist")
+ $("#isArtist").html(data.state ? "yes" : "no")
+ }.bind(this)
+ })
+ },
})
diff --git a/public/assets/javascripts/util.js b/public/assets/javascripts/util.js
index 2cfe0de..0f5c6ed 100644
--- a/public/assets/javascripts/util.js
+++ b/public/assets/javascripts/util.js
@@ -6,6 +6,7 @@ if (window.$) {
$.fn.disable = function() { return $(this).attr("disabled","disabled") }
$.fn.sanitize = function(s) { return trim(sanitize($(this).val())) }
$.fn.htmlSafe = function(s) { return $(this).html(sanitize(s)) }
+ $.fn.toDollars = function(i) { return $(this).html((i/100).toFixed(2)) }
}
function trim (s){ return s.replace(/^\s+/,"").replace(/\s+$/,"") }
diff --git a/public/assets/javascripts/vendor/polyfill.js b/public/assets/javascripts/vendor/polyfill.js
index 499cbc5..2139618 100644
--- a/public/assets/javascripts/vendor/polyfill.js
+++ b/public/assets/javascripts/vendor/polyfill.js
@@ -48,7 +48,7 @@ function has3d(){
} else if ( browser.webkit ) {
browser.safari = true;
}
- $.browser = browser;
+ if (window.$) $.browser = browser;
return browser;
})( navigator.userAgent );
@@ -58,6 +58,7 @@ var is_ipad = (navigator.userAgent.match(/iPad/i))
var is_android = (navigator.userAgent.match(/Android/i))
var is_mobile = is_iphone || is_ipad || is_android
var is_desktop = ! is_mobile;
+var app_devicePixelRatio = is_mobile ? devicePixelRatio : 1;
// rAF shim
diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css
index 62a5682..3ed312e 100755
--- a/public/assets/stylesheets/app.css
+++ b/public/assets/stylesheets/app.css
@@ -53,9 +53,11 @@ body.noOverflow{
overflow:hidden;
}
-body.loading * {
- -webkit-transition: all 0 ease 0 !important;
- transition: all 0 ease 0 !important;
+body.loading *,
+body.loading .animate {
+ opacity: 0.2;
+ -webkit-transition: none !important;
+ transition: none !important;
}
html, body {
@@ -72,7 +74,7 @@ body.pastePaper .wallpaper.active span:hover{
cursor:url(../img/paintbucket.png), auto;
}
-a{
+a {
color:black;
text-decoration: none;
}
@@ -139,7 +141,7 @@ a{
background: rgba(255,255,255,0.9);
}
-.videoModal .ion-ios7-close-empty {
+.videoModal .ion-ios-close-empty {
position: absolute;
right: 50px;
top: 10px;
@@ -148,7 +150,7 @@ a{
color:#444;
}
-.desktop .videoModal .ion-ios7-close-empty:hover {
+.desktop .videoModal .ion-ios-close-empty:hover {
color:black;
}
@@ -156,7 +158,7 @@ a{
display: none;
border-right:0px!important;
}
-.editProfile, .profileLink {
+.profileLink {
border-right:0px!important;
}
.editing #help-button {
@@ -604,7 +606,9 @@ iframe.embed {
.page h1:nth-child(2) {
margin-top: 40px;
}
-
+.page h1.leader {
+ margin-top: 60px;
+}
.page p {
margin: 20px;
}
@@ -673,7 +677,21 @@ iframe.embed {
font-weight: 300;
}
+.aboutintro {
+ text-align: center;
+ line-height: 43px;
+ font-size: 24px;
+ padding: 5% 0;
+ font-weight: 300;
+}
+.aboutintro .inner {
+ max-width: 800px;
+ margin: 0 auto;
+ text-align: center;
+}
+
/* PROFILE PAGE */
+
.profilePic {
background-size: cover;
background-position: center;
@@ -687,7 +705,7 @@ iframe.embed {
border-right: 1px solid;
}
-.profilePic .ion-ios7-person-outline {
+.profilePic .ion-ios-person-outline {
font-size: 100px;
}
@@ -833,6 +851,7 @@ iframe.embed {
}
+
.projectList.about.gopro {
padding:6% 0;
}
@@ -884,14 +903,264 @@ iframe.embed {
background:black;
color:white;
}
+
+/* PLANS BROCHURE */
+.about_custom {
+ clear: both;
+ max-width: 600px;
+ margin: 0 auto;
+ font-size: 14px;
+ border-bottom: 1px solid #e5e5e5;
+}
+.about_custom h3 {
+ text-transform: uppercase;
+ letter-spacing: 3px;
+ font-size: 1.25em;
+ font-weight: 500;
+ background: #3A3A3A;
+ color: white;
+ text-align: center;
+}
+.about_custom li {
+ list-style-type: none;
+ line-height: 2em;
+ padding: 10px 20px;
+ background: white;
+ text-align: center;
+ border-left: 1px solid #e5e5e5;
+ border-right: 1px solid #e5e5e5;
+}
+.about_custom a {
+ border-bottom: 1px solid black;
+}
+
+ul#plans {
+ margin: 0 auto;
+ text-align: center;
+ font-size: 14px;
+}
+
+ul#plans>li {
+ display: inline-block;
+ width: 300px;
+ vertical-align: top;
+ margin: 0 25px 25px 0;
+ position: relative;
+}
+
+ul#plans>li.most-popular:before {
+ content: 'Most Popular';
+ display: block;
+ background: #F17E6F;
+ color: white;
+ font-size: 1em;
+ font-weight: 500;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ width: 100%;
+ position: absolute;
+ top: -31px;
+}
+
+ul#plans .top {
+ background: #3A3A3A;
+ color: white;
+ padding: 30px 0;
+ height: 266px;
+}
+
+ul#plans h2 {
+ padding: 0;
+ font-size: 1.25em;
+ margin-bottom: 1.75em;
+ text-transform: uppercase;
+ letter-spacing: 3px;
+ font-weight: 500;
+}
+
+ul#plans h3 {
+ margin: 0 0 20px;
+ font-weight: 200;
+}
+
+ul#plans h3 span.dollar {
+ font-size: 1.25em;
+ vertical-align: top;
+ position: relative;
+ top: -14px;
+}
+
+ul#plans h3 span.price {
+ font-size: 5em;
+ font-weight: 100;
+}
+
+ul#plans h4 {
+ font-size: 0.85em;
+ color: #e6e6e6;
+ margin: 0 auto;
+ width: 50%;
+ font-weight: 500;
+ line-height: 30px;
+}
+
+ul#plans ul {
+ border-left: 1px solid #e5e5e5;
+ border-right: 1px solid #e5e5e5;
+}
+
+ul#plans ul li {
+ text-align: left;
+ border-bottom: 1px solid #e5e5e5;
+ padding: 5px 20px;
+ font-weight: 700;
+ list-style: none;
+ background: white;
+ color:#333;
+}
+
+ul#plans .signup {
+ background: #3A3A3A;
+ padding: 25px 0;
+}
+
+.signup .current {
+ display: inline-block;
+ color: white;
+ font-weight: bold;
+ font-size: 1em;
+ padding: 4px 30px 3px;
+}
+
+.signup .button {
+ font-weight: bold;
+ padding: 16px 30px 14px;
+ -o-transition: background 0.2s ease-in-out;
+ -webkit-transition: background 0.2s ease-in-out;
+ transition: background 0.2s ease-in-out;
+ display: inline-block;
+ background: #F17E6F;
+ color: white;
+ text-decoration: none;
+ font-size: 1em;
+ padding: 4px 30px 3px;
+ border: none;
+ cursor: pointer;
+}
+
+
+.signup .button:hover {
+ color: white;
+ background: #ef6958;
+}
+
+
+/* debug sync button */
+.editSubscription .gear {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ opacity: 0.1;
+ cursor: pointer;
+ -webkit-transition: all 0.3s;
+ -webkit-transform-origin: 49% 53%;
+ transition: all 0.3s;
+ transform-origin: 49% 53%;
+}
+.editSubscription .gear.turning {
+ opacity: 0.3;
+ -webkit-animation: gear 1s infinite linear;
+ animation: gear 1s infinite linear;
+}
+@-webkit-keyframes gear {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(720deg); }
+}
+@keyframes gear {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(720deg); }
+}
+.paidPlan {
+ text-align: left;
+ font-size: 14px;
+}
+.planInfo {
+ margin: 10px 0;
+ width: 100%;
+ padding: 0;
+}
+.planInfo td, .planInfo th {
+ text-align: left;
+ padding: 10px 3px;
+ margin: 0;
+}
+.planInfo td {
+ height: 60px;
+ vertical-align: middle;
+}
+.planInfo td:nth-child(2),
+.planInfo th:nth-child(2),
+.planInfo td:nth-child(3),
+.planInfo td:nth-child(4),
+.planInfo th:nth-child(3) {
+ text-align: right;
+}
+.planInfo td:nth-child(4) {
+ width: 90px;
+}
+
+.planInfo [data-role="billingInterval"] {
+ font-size: 10px;
+}
+.totalRow td:nth-child(4) {
+ border-top: 1px solid;
+}
+.paidPlan button {
+ width: 200px;
+ float: none;
+ margin: 5px 7px;
+}
+.paidPlan [data-role="cancelSubscription"] {
+ color: #800;
+ border-color: black;
+ width: 200px;
+ float: none;
+}
+.paidPlan [data-role="cancelSubscription"]:hover {
+ color: white;
+ background: red;
+ border-color: red;
+}
+/* purchase mode */
+.paidPlan input[type=number] { display: none; float: right; }
+form .paidPlan div { float: none; }
+form .paidPlan label { float: none; font-size: 16px; margin: 0 10px; }
+.paidPlan .upgradeMenu div { padding: 5px 10px; }
+.paidPlan .editMenu { display: none }
+.paidPlan .planMenu { display: none }
+
+.editing .section_break { display: none }
+.editing .paidPlan .currentPlanLevel { display: none }
+.editing .paidPlan .billingMenu { display: none }
+.editing .paidPlan .editMenu { display: block }
+.editing .paidPlan .planMenu { display: block }
+.editing .paidPlan input[type=number] { display: inline-block }
+.editing .paidPlan input[type=number]+span { display: none }
+
+.editMenu .fineprint { font-size: 12px; width: auto; text-align: justify; }
+/* LAYOUTS MODAL */
+
.templates {
overflow: auto;
max-height: 100%;
width: 100%;
height: 100%;
padding: 20px 0 40px 0;
+ text-align: center;
}
-.templates-list {
+.templates-list,
+.userTemplatesList,
+.blueprintsList {
display: inline-block;
width: 100%;
margin-bottom: 40px;
@@ -902,8 +1171,8 @@ iframe.embed {
}
.templates::-webkit-scrollbar-thumb {
-background-color: white;
-border-left: 1px solid black;
+ background-color: white;
+ border-left: 1px solid black;
}
.templates::-webkit-scrollbar-track {
@@ -918,8 +1187,7 @@ border-left: 1px solid black;
}
.templates span {
- display: block;
- float: left;
+ display: inline-block;
margin: 1vw 0;
width:20%;
padding: 2vw;
@@ -974,6 +1242,8 @@ border-left: 1px solid black;
float:right;
}
+/* MX SCENE STUFF */
+
.mx-scene {
position:fixed;
top:0;
@@ -1001,6 +1271,13 @@ border-left: 1px solid black;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
+.mx-outline {
+ border-width: 2px;
+ border-style: dashed;
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+}
.destroyActive .mx-scene, .destroyActive .mx-object3d.image {
cursor:url(/assets/img/delete-cursor.png), auto;
}
@@ -1229,7 +1506,8 @@ border-left: 1px solid black;
cursor:pointer;
}
-.menu span.inuse {
+.menu span.inuse,
+.menu span.active {
color:white;
background:black;
cursor:pointer;
@@ -1255,7 +1533,7 @@ border-left: 1px solid black;
font-weight:600;
}
-.menu span.ion-ios7-sunny-outline:hover:after {
+.menu span.ion-ios-sunny-outline:hover:after {
width: 130px;
}
@@ -1303,12 +1581,12 @@ border-left: 1px solid black;
.animate {
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
- -webkit-transform: translateY(-100%);
- transform: translateY(-100%);
+ -webkit-transform: translateY(-200%);
+ transform: translateY(-200%);
}
.mediaDrawer {
- -webkit-transform: translateY(-100%);
- transform: translateY(-100%);
+ -webkit-transform: translateY(-200%);
+ transform: translateY(-200%);
background: white;
text-align: center;
overflow-x: hidden;
@@ -1324,7 +1602,8 @@ border-left: 1px solid black;
.mediaDrawer.signin, .mediaDrawer.signup,
.mediaDrawer.alert, .mediaDrawer.confirm,
.mediaDrawer.passwordForgot, .mediaDrawer.passwordReset, .mediaDrawer.usernameTaken,
-.mediaDrawer.layouts, .mediaDrawer.projects, .mediaDrawer.newProject {
+.mediaDrawer.layouts, .mediaDrawer.projects, .mediaDrawer.newProject,
+.mediaDrawer.blueprintEditor {
display:table;
}
.confirm button {
@@ -1423,7 +1702,7 @@ border-left: 1px solid black;
transform: translateY(0%);
}
-.fileUpload .ion-ios7-upload-outline {
+.fileUpload .ion-ios-upload-outline {
font-size:40px;
}
.fileUpload .upload-icon.uploading {
@@ -2075,6 +2354,20 @@ input[type="range"]::-webkit-slider-thumb {
transition: -webkit-transform 0.2s ease-in-out;
width: 210px;
}
+#blueprintNotice.settings {
+ width: 230px;
+}
+#blueprintNotice a {
+ border-bottom: 1px solid;
+}
+#blueprintNotice .next {
+ display: inline-block;
+ background: black; color: white;
+ padding: 4px;
+ margin: 4px 0 0 0;
+ float: right;
+ cursor: pointer;
+}
#textEditor.settings {
width: 320px;
}
@@ -2212,6 +2505,9 @@ input[type="range"]::-webkit-slider-thumb {
top: 5px;
font-weight:600;
}
+.setting.number.scale label {
+ top: 0;
+}
.setting.number label:after {
content:":";
}
@@ -2251,6 +2547,9 @@ input[type="range"]::-webkit-slider-thumb {
#mediaEditor .setting.number [type=text] {
width: 140px;
}
+#sculptureEditor .setting.number input[type=text] {
+ width: 130px;
+}
.playButton,.muteButton {
border-radius: 50%;
@@ -2468,7 +2767,7 @@ form li {
form label {
float:left;
}
-form input[type="text"],form input[type="password"] {
+form input[type="text"],form input[type="password"],form input[type="number"] {
border: 1px solid;
font-size: 20px;
padding: 5px;
@@ -2488,7 +2787,7 @@ form input[type="submit"]:hover {
border:1px solid black;
cursor:pointer;
}
-form p{
+form p {
display: block;
float: left;
font-size: 15px;
@@ -2976,6 +3275,105 @@ a[data-role="forgot-password"] {
}
+/* blueprint upload box */
+
+.blueprintUploader {
+ -webkit-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ width: 340px;
+ position: absolute;
+ top: 50%; left: 50%;
+ background: white;
+ padding: 10px;
+ border: 1px solid black;
+ box-shadow: -3px 3px #000;
+ -webkit-transform: translate3D(0%,-200%,0);
+ transform: translate3D(0%,-200%,0);
+ margin-left: -175px;
+ margin-top: -200px;
+ opacity: 0;
+}
+.blueprintUploader.active {
+ -webkit-transform: translate3D(0,0,0);
+ transform: translate3D(0,0,0);
+ opacity: 1;
+}
+.blueprintUploader .toolButton {
+ float: none;
+ width: 108px;
+ display: inline-block;
+}
+.blueprintUploader .url {
+ font-size: 15px;
+ border: 1px solid #888;
+ padding: 2px;
+ font-weight: 300;
+ position: relative;
+ top: 3px;
+ margin-right: 10px;
+ width: 190px;
+}
+.blueprintUploader p {
+ font-weight: 300;
+ font-size: 13px;
+}
+.blueprintUploader .blueprints {
+ display: none;
+}
+.blueprintUploader .blueprints h5 {
+ width: 250px;
+ margin: 10px auto;
+ padding-top: 9px;
+}
+.blueprints .blueprint {
+ border: 2px solid black;
+ background: white;
+ padding: 0px;
+ position: relative;
+ display: inline-block;
+ margin: 0 2px;
+}
+.blueprints .blueprint img {
+ height: 100px;
+ max-width: 200px;
+ display: block;
+ cursor: pointer;
+}
+.blueprints .blueprint .remove {
+ box-shadow: -2px 2px #000;
+ cursor: pointer;
+ position: absolute;
+ color: red;
+ top: 7px;
+ right: 7px;
+ width: 20px; height: 20px;
+ text-align: center;
+ background: #fff;
+ border: 1px solid black;
+}
+.blueprints .blueprint .remove span {
+ position: relative;
+ top: -2px;
+}
+.blueprintUploader .wallpaperUpload .upload-icon {
+ margin: 0 4px;
+}
+.uploadNewBlueprint {
+ color: #333;
+ border-bottom: 1px solid;
+ cursor: pointer;
+}
+
+
+[data-role="create-new-blueprint"] {
+ margin-bottom: 10px;
+}
+.openScaler {
+ margin-left: 10px;
+ border-bottom: 1px solid;
+ cursor: pointer;
+}
+
/* KEYBOARD SHORTCUTS */
.keyboard { float: left; width: 50%; margin-top: 50px; }
@@ -3038,8 +3436,8 @@ a[data-role="forgot-password"] {
form li {
font-size: 16px;
}
- form input[type="text"], form input[type="password"] {
- font-size: 15px;
+ form input[type="text"],form input[type="password"],form input[type="number"] {
+ font-size: 15px;
}
.page h1 {
font-size: 26px;
@@ -3160,7 +3558,7 @@ a[data-role="forgot-password"] {
.footer {
padding:50px 0 120px 0;
}
- .videoModal .ion-ios7-close-empty {
+ .videoModal .ion-ios-close-empty {
right: 10px;
top: 20px;
}
@@ -3261,4 +3659,4 @@ a[data-role="forgot-password"] {
.settings {
right: 80px;
}
-} \ No newline at end of file
+}
diff --git a/public/assets/stylesheets/ionicons.css b/public/assets/stylesheets/ionicons.css
index 34c20e2..885aa6b 100755
--- a/public/assets/stylesheets/ionicons.css
+++ b/public/assets/stylesheets/ionicons.css
@@ -1,25 +1,17 @@
+@charset "UTF-8";
/*!
- Ionicons, v1.5.2
+ Ionicons, v2.0.0
Created by Ben Sperry for the Ionic Framework, http://ionicons.com/
https://twitter.com/benjsperry https://twitter.com/ionicframework
MIT License: https://github.com/driftyco/ionicons
-*/
-@font-face { font-family: "Ionicons"; src: url("../fonts/ionicons.eot?v=1.5.2"); src: url("../fonts/ionicons.eot?v=1.5.2#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=1.5.2") format("truetype"), url("../fonts/ionicons.woff?v=1.5.2") format("woff"), url("../fonts/ionicons.svg?v=1.5.2#Ionicons") format("svg"); font-weight: normal; font-style: normal; }
-.ion, .ion-loading-a, .ion-loading-b, .ion-loading-c, .ion-loading-d, .ion-looping, .ion-refreshing, .ion-ios7-reloading, .ionicons, .ion-alert:before, .ion-alert-circled:before, .ion-android-add:before, .ion-android-add-contact:before, .ion-android-alarm:before, .ion-android-archive:before, .ion-android-arrow-back:before, .ion-android-arrow-down-left:before, .ion-android-arrow-down-right:before, .ion-android-arrow-forward:before, .ion-android-arrow-up-left:before, .ion-android-arrow-up-right:before, .ion-android-battery:before, .ion-android-book:before, .ion-android-calendar:before, .ion-android-call:before, .ion-android-camera:before, .ion-android-chat:before, .ion-android-checkmark:before, .ion-android-clock:before, .ion-android-close:before, .ion-android-contact:before, .ion-android-contacts:before, .ion-android-data:before, .ion-android-developer:before, .ion-android-display:before, .ion-android-download:before, .ion-android-drawer:before, .ion-android-dropdown:before, .ion-android-earth:before, .ion-android-folder:before, .ion-android-forums:before, .ion-android-friends:before, .ion-android-hand:before, .ion-android-image:before, .ion-android-inbox:before, .ion-android-information:before, .ion-android-keypad:before, .ion-android-lightbulb:before, .ion-android-locate:before, .ion-android-location:before, .ion-android-mail:before, .ion-android-microphone:before, .ion-android-mixer:before, .ion-android-more:before, .ion-android-note:before, .ion-android-playstore:before, .ion-android-printer:before, .ion-android-promotion:before, .ion-android-reminder:before, .ion-android-remove:before, .ion-android-search:before, .ion-android-send:before, .ion-android-settings:before, .ion-android-share:before, .ion-android-social:before, .ion-android-social-user:before, .ion-android-sort:before, .ion-android-stair-drawer:before, .ion-android-star:before, .ion-android-stopwatch:before, .ion-android-storage:before, .ion-android-system-back:before, .ion-android-system-home:before, .ion-android-system-windows:before, .ion-android-timer:before, .ion-android-trash:before, .ion-android-user-menu:before, .ion-android-volume:before, .ion-android-wifi:before, .ion-aperture:before, .ion-archive:before, .ion-arrow-down-a:before, .ion-arrow-down-b:before, .ion-arrow-down-c:before, .ion-arrow-expand:before, .ion-arrow-graph-down-left:before, .ion-arrow-graph-down-right:before, .ion-arrow-graph-up-left:before, .ion-arrow-graph-up-right:before, .ion-arrow-left-a:before, .ion-arrow-left-b:before, .ion-arrow-left-c:before, .ion-arrow-move:before, .ion-arrow-resize:before, .ion-arrow-return-left:before, .ion-arrow-return-right:before, .ion-arrow-right-a:before, .ion-arrow-right-b:before, .ion-arrow-right-c:before, .ion-arrow-shrink:before, .ion-arrow-swap:before, .ion-arrow-up-a:before, .ion-arrow-up-b:before, .ion-arrow-up-c:before, .ion-asterisk:before, .ion-at:before, .ion-bag:before, .ion-battery-charging:before, .ion-battery-empty:before, .ion-battery-full:before, .ion-battery-half:before, .ion-battery-low:before, .ion-beaker:before, .ion-beer:before, .ion-bluetooth:before, .ion-bonfire:before, .ion-bookmark:before, .ion-briefcase:before, .ion-bug:before, .ion-calculator:before, .ion-calendar:before, .ion-camera:before, .ion-card:before, .ion-cash:before, .ion-chatbox:before, .ion-chatbox-working:before, .ion-chatboxes:before, .ion-chatbubble:before, .ion-chatbubble-working:before, .ion-chatbubbles:before, .ion-checkmark:before, .ion-checkmark-circled:before, .ion-checkmark-round:before, .ion-chevron-down:before, .ion-chevron-left:before, .ion-chevron-right:before, .ion-chevron-up:before, .ion-clipboard:before, .ion-clock:before, .ion-close:before, .ion-close-circled:before, .ion-close-round:before, .ion-closed-captioning:before, .ion-cloud:before, .ion-code:before, .ion-code-download:before, .ion-code-working:before, .ion-coffee:before, .ion-compass:before, .ion-compose:before, .ion-connection-bars:before, .ion-contrast:before, .ion-cube:before, .ion-disc:before, .ion-document:before, .ion-document-text:before, .ion-drag:before, .ion-earth:before, .ion-edit:before, .ion-egg:before, .ion-eject:before, .ion-email:before, .ion-eye:before, .ion-eye-disabled:before, .ion-female:before, .ion-filing:before, .ion-film-marker:before, .ion-fireball:before, .ion-flag:before, .ion-flame:before, .ion-flash:before, .ion-flash-off:before, .ion-flask:before, .ion-folder:before, .ion-fork:before, .ion-fork-repo:before, .ion-forward:before, .ion-funnel:before, .ion-game-controller-a:before, .ion-game-controller-b:before, .ion-gear-a:before, .ion-gear-b:before, .ion-grid:before, .ion-hammer:before, .ion-happy:before, .ion-headphone:before, .ion-heart:before, .ion-heart-broken:before, .ion-help:before, .ion-help-buoy:before, .ion-help-circled:before, .ion-home:before, .ion-icecream:before, .ion-icon-social-google-plus:before, .ion-icon-social-google-plus-outline:before, .ion-image:before, .ion-images:before, .ion-information:before, .ion-information-circled:before, .ion-ionic:before, .ion-ios7-alarm:before, .ion-ios7-alarm-outline:before, .ion-ios7-albums:before, .ion-ios7-albums-outline:before, .ion-ios7-americanfootball:before, .ion-ios7-americanfootball-outline:before, .ion-ios7-analytics:before, .ion-ios7-analytics-outline:before, .ion-ios7-arrow-back:before, .ion-ios7-arrow-down:before, .ion-ios7-arrow-forward:before, .ion-ios7-arrow-left:before, .ion-ios7-arrow-right:before, .ion-ios7-arrow-thin-down:before, .ion-ios7-arrow-thin-left:before, .ion-ios7-arrow-thin-right:before, .ion-ios7-arrow-thin-up:before, .ion-ios7-arrow-up:before, .ion-ios7-at:before, .ion-ios7-at-outline:before, .ion-ios7-barcode:before, .ion-ios7-barcode-outline:before, .ion-ios7-baseball:before, .ion-ios7-baseball-outline:before, .ion-ios7-basketball:before, .ion-ios7-basketball-outline:before, .ion-ios7-bell:before, .ion-ios7-bell-outline:before, .ion-ios7-bolt:before, .ion-ios7-bolt-outline:before, .ion-ios7-bookmarks:before, .ion-ios7-bookmarks-outline:before, .ion-ios7-box:before, .ion-ios7-box-outline:before, .ion-ios7-briefcase:before, .ion-ios7-briefcase-outline:before, .ion-ios7-browsers:before, .ion-ios7-browsers-outline:before, .ion-ios7-calculator:before, .ion-ios7-calculator-outline:before, .ion-ios7-calendar:before, .ion-ios7-calendar-outline:before, .ion-ios7-camera:before, .ion-ios7-camera-outline:before, .ion-ios7-cart:before, .ion-ios7-cart-outline:before, .ion-ios7-chatboxes:before, .ion-ios7-chatboxes-outline:before, .ion-ios7-chatbubble:before, .ion-ios7-chatbubble-outline:before, .ion-ios7-checkmark:before, .ion-ios7-checkmark-empty:before, .ion-ios7-checkmark-outline:before, .ion-ios7-circle-filled:before, .ion-ios7-circle-outline:before, .ion-ios7-clock:before, .ion-ios7-clock-outline:before, .ion-ios7-close:before, .ion-ios7-close-empty:before, .ion-ios7-close-outline:before, .ion-ios7-cloud:before, .ion-ios7-cloud-download:before, .ion-ios7-cloud-download-outline:before, .ion-ios7-cloud-outline:before, .ion-ios7-cloud-upload:before, .ion-ios7-cloud-upload-outline:before, .ion-ios7-cloudy:before, .ion-ios7-cloudy-night:before, .ion-ios7-cloudy-night-outline:before, .ion-ios7-cloudy-outline:before, .ion-ios7-cog:before, .ion-ios7-cog-outline:before, .ion-ios7-compose:before, .ion-ios7-compose-outline:before, .ion-ios7-contact:before, .ion-ios7-contact-outline:before, .ion-ios7-copy:before, .ion-ios7-copy-outline:before, .ion-ios7-download:before, .ion-ios7-download-outline:before, .ion-ios7-drag:before, .ion-ios7-email:before, .ion-ios7-email-outline:before, .ion-ios7-expand:before, .ion-ios7-eye:before, .ion-ios7-eye-outline:before, .ion-ios7-fastforward:before, .ion-ios7-fastforward-outline:before, .ion-ios7-filing:before, .ion-ios7-filing-outline:before, .ion-ios7-film:before, .ion-ios7-film-outline:before, .ion-ios7-flag:before, .ion-ios7-flag-outline:before, .ion-ios7-folder:before, .ion-ios7-folder-outline:before, .ion-ios7-football:before, .ion-ios7-football-outline:before, .ion-ios7-gear:before, .ion-ios7-gear-outline:before, .ion-ios7-glasses:before, .ion-ios7-glasses-outline:before, .ion-ios7-heart:before, .ion-ios7-heart-outline:before, .ion-ios7-help:before, .ion-ios7-help-empty:before, .ion-ios7-help-outline:before, .ion-ios7-home:before, .ion-ios7-home-outline:before, .ion-ios7-infinite:before, .ion-ios7-infinite-outline:before, .ion-ios7-information:before, .ion-ios7-information-empty:before, .ion-ios7-information-outline:before, .ion-ios7-ionic-outline:before, .ion-ios7-keypad:before, .ion-ios7-keypad-outline:before, .ion-ios7-lightbulb:before, .ion-ios7-lightbulb-outline:before, .ion-ios7-location:before, .ion-ios7-location-outline:before, .ion-ios7-locked:before, .ion-ios7-locked-outline:before, .ion-ios7-loop:before, .ion-ios7-loop-strong:before, .ion-ios7-medkit:before, .ion-ios7-medkit-outline:before, .ion-ios7-mic:before, .ion-ios7-mic-off:before, .ion-ios7-mic-outline:before, .ion-ios7-minus:before, .ion-ios7-minus-empty:before, .ion-ios7-minus-outline:before, .ion-ios7-monitor:before, .ion-ios7-monitor-outline:before, .ion-ios7-moon:before, .ion-ios7-moon-outline:before, .ion-ios7-more:before, .ion-ios7-more-outline:before, .ion-ios7-musical-note:before, .ion-ios7-musical-notes:before, .ion-ios7-navigate:before, .ion-ios7-navigate-outline:before, .ion-ios7-paper:before, .ion-ios7-paper-outline:before, .ion-ios7-paperplane:before, .ion-ios7-paperplane-outline:before, .ion-ios7-partlysunny:before, .ion-ios7-partlysunny-outline:before, .ion-ios7-pause:before, .ion-ios7-pause-outline:before, .ion-ios7-paw:before, .ion-ios7-paw-outline:before, .ion-ios7-people:before, .ion-ios7-people-outline:before, .ion-ios7-person:before, .ion-ios7-person-outline:before, .ion-ios7-personadd:before, .ion-ios7-personadd-outline:before, .ion-ios7-photos:before, .ion-ios7-photos-outline:before, .ion-ios7-pie:before, .ion-ios7-pie-outline:before, .ion-ios7-play:before, .ion-ios7-play-outline:before, .ion-ios7-plus:before, .ion-ios7-plus-empty:before, .ion-ios7-plus-outline:before, .ion-ios7-pricetag:before, .ion-ios7-pricetag-outline:before, .ion-ios7-pricetags:before, .ion-ios7-pricetags-outline:before, .ion-ios7-printer:before, .ion-ios7-printer-outline:before, .ion-ios7-pulse:before, .ion-ios7-pulse-strong:before, .ion-ios7-rainy:before, .ion-ios7-rainy-outline:before, .ion-ios7-recording:before, .ion-ios7-recording-outline:before, .ion-ios7-redo:before, .ion-ios7-redo-outline:before, .ion-ios7-refresh:before, .ion-ios7-refresh-empty:before, .ion-ios7-refresh-outline:before, .ion-ios7-reload:before, .ion-ios7-reloading:before, .ion-ios7-reverse-camera:before, .ion-ios7-reverse-camera-outline:before, .ion-ios7-rewind:before, .ion-ios7-rewind-outline:before, .ion-ios7-search:before, .ion-ios7-search-strong:before, .ion-ios7-settings:before, .ion-ios7-settings-strong:before, .ion-ios7-shrink:before, .ion-ios7-skipbackward:before, .ion-ios7-skipbackward-outline:before, .ion-ios7-skipforward:before, .ion-ios7-skipforward-outline:before, .ion-ios7-snowy:before, .ion-ios7-speedometer:before, .ion-ios7-speedometer-outline:before, .ion-ios7-star:before, .ion-ios7-star-half:before, .ion-ios7-star-outline:before, .ion-ios7-stopwatch:before, .ion-ios7-stopwatch-outline:before, .ion-ios7-sunny:before, .ion-ios7-sunny-outline:before, .ion-ios7-telephone:before, .ion-ios7-telephone-outline:before, .ion-ios7-tennisball:before, .ion-ios7-tennisball-outline:before, .ion-ios7-thunderstorm:before, .ion-ios7-thunderstorm-outline:before, .ion-ios7-time:before, .ion-ios7-time-outline:before, .ion-ios7-timer:before, .ion-ios7-timer-outline:before, .ion-ios7-toggle:before, .ion-ios7-toggle-outline:before, .ion-ios7-trash:before, .ion-ios7-trash-outline:before, .ion-ios7-undo:before, .ion-ios7-undo-outline:before, .ion-ios7-unlocked:before, .ion-ios7-unlocked-outline:before, .ion-ios7-upload:before, .ion-ios7-upload-outline:before, .ion-ios7-videocam:before, .ion-ios7-videocam-outline:before, .ion-ios7-volume-high:before, .ion-ios7-volume-low:before, .ion-ios7-wineglass:before, .ion-ios7-wineglass-outline:before, .ion-ios7-world:before, .ion-ios7-world-outline:before, .ion-ipad:before, .ion-iphone:before, .ion-ipod:before, .ion-jet:before, .ion-key:before, .ion-knife:before, .ion-laptop:before, .ion-leaf:before, .ion-levels:before, .ion-lightbulb:before, .ion-link:before, .ion-load-a:before, .ion-loading-a:before, .ion-load-b:before, .ion-loading-b:before, .ion-load-c:before, .ion-loading-c:before, .ion-load-d:before, .ion-loading-d:before, .ion-location:before, .ion-locked:before, .ion-log-in:before, .ion-log-out:before, .ion-loop:before, .ion-looping:before, .ion-magnet:before, .ion-male:before, .ion-man:before, .ion-map:before, .ion-medkit:before, .ion-merge:before, .ion-mic-a:before, .ion-mic-b:before, .ion-mic-c:before, .ion-minus:before, .ion-minus-circled:before, .ion-minus-round:before, .ion-model-s:before, .ion-monitor:before, .ion-more:before, .ion-mouse:before, .ion-music-note:before, .ion-navicon:before, .ion-navicon-round:before, .ion-navigate:before, .ion-network:before, .ion-no-smoking:before, .ion-nuclear:before, .ion-outlet:before, .ion-paper-airplane:before, .ion-paperclip:before, .ion-pause:before, .ion-person:before, .ion-person-add:before, .ion-person-stalker:before, .ion-pie-graph:before, .ion-pin:before, .ion-pinpoint:before, .ion-pizza:before, .ion-plane:before, .ion-planet:before, .ion-play:before, .ion-playstation:before, .ion-plus:before, .ion-plus-circled:before, .ion-plus-round:before, .ion-podium:before, .ion-pound:before, .ion-power:before, .ion-pricetag:before, .ion-pricetags:before, .ion-printer:before, .ion-pull-request:before, .ion-qr-scanner:before, .ion-quote:before, .ion-radio-waves:before, .ion-record:before, .ion-refresh:before, .ion-refreshing:before, .ion-reply:before, .ion-reply-all:before, .ion-ribbon-a:before, .ion-ribbon-b:before, .ion-sad:before, .ion-scissors:before, .ion-search:before, .ion-settings:before, .ion-share:before, .ion-shuffle:before, .ion-skip-backward:before, .ion-skip-forward:before, .ion-social-android:before, .ion-social-android-outline:before, .ion-social-apple:before, .ion-social-apple-outline:before, .ion-social-bitcoin:before, .ion-social-bitcoin-outline:before, .ion-social-buffer:before, .ion-social-buffer-outline:before, .ion-social-designernews:before, .ion-social-designernews-outline:before, .ion-social-dribbble:before, .ion-social-dribbble-outline:before, .ion-social-dropbox:before, .ion-social-dropbox-outline:before, .ion-social-facebook:before, .ion-social-facebook-outline:before, .ion-social-foursquare:before, .ion-social-foursquare-outline:before, .ion-social-freebsd-devil:before, .ion-social-github:before, .ion-social-github-outline:before, .ion-social-google:before, .ion-social-google-outline:before, .ion-social-googleplus:before, .ion-social-googleplus-outline:before, .ion-social-hackernews:before, .ion-social-hackernews-outline:before, .ion-social-instagram:before, .ion-social-instagram-outline:before, .ion-social-linkedin:before, .ion-social-linkedin-outline:before, .ion-social-pinterest:before, .ion-social-pinterest-outline:before, .ion-social-reddit:before, .ion-social-reddit-outline:before, .ion-social-rss:before, .ion-social-rss-outline:before, .ion-social-skype:before, .ion-social-skype-outline:before, .ion-social-tumblr:before, .ion-social-tumblr-outline:before, .ion-social-tux:before, .ion-social-twitter:before, .ion-social-twitter-outline:before, .ion-social-usd:before, .ion-social-usd-outline:before, .ion-social-vimeo:before, .ion-social-vimeo-outline:before, .ion-social-windows:before, .ion-social-windows-outline:before, .ion-social-wordpress:before, .ion-social-wordpress-outline:before, .ion-social-yahoo:before, .ion-social-yahoo-outline:before, .ion-social-youtube:before, .ion-social-youtube-outline:before, .ion-speakerphone:before, .ion-speedometer:before, .ion-spoon:before, .ion-star:before, .ion-stats-bars:before, .ion-steam:before, .ion-stop:before, .ion-thermometer:before, .ion-thumbsdown:before, .ion-thumbsup:before, .ion-toggle:before, .ion-toggle-filled:before, .ion-trash-a:before, .ion-trash-b:before, .ion-trophy:before, .ion-umbrella:before, .ion-university:before, .ion-unlocked:before, .ion-upload:before, .ion-usb:before, .ion-videocamera:before, .ion-volume-high:before, .ion-volume-low:before, .ion-volume-medium:before, .ion-volume-mute:before, .ion-wand:before, .ion-waterdrop:before, .ion-wifi:before, .ion-wineglass:before, .ion-woman:before, .ion-wrench:before, .ion-xbox:before { display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
-
-.ion-spin, .ion-loading-a, .ion-loading-b, .ion-loading-c, .ion-loading-d, .ion-looping, .ion-refreshing, .ion-ios7-reloading { -webkit-animation: spin 1s infinite linear; -moz-animation: spin 1s infinite linear; -o-animation: spin 1s infinite linear; animation: spin 1s infinite linear; }
-@-moz-keyframes spin { 0% { -moz-transform: rotate(0deg); }
- 100% { -moz-transform: rotate(359deg); } }
-@-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); }
- 100% { -webkit-transform: rotate(359deg); } }
-@-o-keyframes spin { 0% { -o-transform: rotate(0deg); }
- 100% { -o-transform: rotate(359deg); } }
-@-ms-keyframes spin { 0% { -ms-transform: rotate(0deg); }
- 100% { -ms-transform: rotate(359deg); } }
-@keyframes spin { 0% { transform: rotate(0deg); }
- 100% { transform: rotate(359deg); } }
-.ion-loading-a { -webkit-animation-timing-function: steps(8, start); -moz-animation-timing-function: steps(8, start); animation-timing-function: steps(8, start); }
+ Android-style icons originally built by Google’s
+ Material Design Icons: https://github.com/google/material-design-icons
+ used under CC BY http://creativecommons.org/licenses/by/4.0/
+ Modified icons to fit ionicon’s grid from original.
+*/
+@font-face { font-family: "Ionicons"; src: url("../fonts/ionicons.eot?v=2.0.0"); src: url("../fonts/ionicons.eot?v=2.0.0#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=2.0.0") format("truetype"), url("../fonts/ionicons.woff?v=2.0.0") format("woff"), url("../fonts/ionicons.svg?v=2.0.0#Ionicons") format("svg"); font-weight: normal; font-style: normal; }
+.ion, .ionicons, .ion-alert:before, .ion-alert-circled:before, .ion-android-add:before, .ion-android-add-circle:before, .ion-android-alarm-clock:before, .ion-android-alert:before, .ion-android-apps:before, .ion-android-archive:before, .ion-android-arrow-back:before, .ion-android-arrow-down:before, .ion-android-arrow-dropdown:before, .ion-android-arrow-dropdown-circle:before, .ion-android-arrow-dropleft:before, .ion-android-arrow-dropleft-circle:before, .ion-android-arrow-dropright:before, .ion-android-arrow-dropright-circle:before, .ion-android-arrow-dropup:before, .ion-android-arrow-dropup-circle:before, .ion-android-arrow-forward:before, .ion-android-arrow-up:before, .ion-android-attach:before, .ion-android-bar:before, .ion-android-bicycle:before, .ion-android-boat:before, .ion-android-bookmark:before, .ion-android-bulb:before, .ion-android-bus:before, .ion-android-calendar:before, .ion-android-call:before, .ion-android-camera:before, .ion-android-cancel:before, .ion-android-car:before, .ion-android-cart:before, .ion-android-chat:before, .ion-android-checkbox:before, .ion-android-checkbox-blank:before, .ion-android-checkbox-outline:before, .ion-android-checkbox-outline-blank:before, .ion-android-checkmark-circle:before, .ion-android-clipboard:before, .ion-android-close:before, .ion-android-cloud:before, .ion-android-cloud-circle:before, .ion-android-cloud-done:before, .ion-android-cloud-outline:before, .ion-android-color-palette:before, .ion-android-compass:before, .ion-android-contact:before, .ion-android-contacts:before, .ion-android-contract:before, .ion-android-create:before, .ion-android-delete:before, .ion-android-desktop:before, .ion-android-document:before, .ion-android-done:before, .ion-android-done-all:before, .ion-android-download:before, .ion-android-drafts:before, .ion-android-exit:before, .ion-android-expand:before, .ion-android-favorite:before, .ion-android-favorite-outline:before, .ion-android-film:before, .ion-android-folder:before, .ion-android-folder-open:before, .ion-android-funnel:before, .ion-android-globe:before, .ion-android-hand:before, .ion-android-hangout:before, .ion-android-happy:before, .ion-android-home:before, .ion-android-image:before, .ion-android-laptop:before, .ion-android-list:before, .ion-android-locate:before, .ion-android-lock:before, .ion-android-mail:before, .ion-android-map:before, .ion-android-menu:before, .ion-android-microphone:before, .ion-android-microphone-off:before, .ion-android-more-horizontal:before, .ion-android-more-vertical:before, .ion-android-navigate:before, .ion-android-notifications:before, .ion-android-notifications-none:before, .ion-android-notifications-off:before, .ion-android-open:before, .ion-android-options:before, .ion-android-people:before, .ion-android-person:before, .ion-android-person-add:before, .ion-android-phone-landscape:before, .ion-android-phone-portrait:before, .ion-android-pin:before, .ion-android-plane:before, .ion-android-playstore:before, .ion-android-print:before, .ion-android-radio-button-off:before, .ion-android-radio-button-on:before, .ion-android-refresh:before, .ion-android-remove:before, .ion-android-remove-circle:before, .ion-android-restaurant:before, .ion-android-sad:before, .ion-android-search:before, .ion-android-send:before, .ion-android-settings:before, .ion-android-share:before, .ion-android-share-alt:before, .ion-android-star:before, .ion-android-star-half:before, .ion-android-star-outline:before, .ion-android-stopwatch:before, .ion-android-subway:before, .ion-android-sunny:before, .ion-android-sync:before, .ion-android-textsms:before, .ion-android-time:before, .ion-android-train:before, .ion-android-unlock:before, .ion-android-upload:before, .ion-android-volume-down:before, .ion-android-volume-mute:before, .ion-android-volume-off:before, .ion-android-volume-up:before, .ion-android-walk:before, .ion-android-warning:before, .ion-android-watch:before, .ion-android-wifi:before, .ion-aperture:before, .ion-archive:before, .ion-arrow-down-a:before, .ion-arrow-down-b:before, .ion-arrow-down-c:before, .ion-arrow-expand:before, .ion-arrow-graph-down-left:before, .ion-arrow-graph-down-right:before, .ion-arrow-graph-up-left:before, .ion-arrow-graph-up-right:before, .ion-arrow-left-a:before, .ion-arrow-left-b:before, .ion-arrow-left-c:before, .ion-arrow-move:before, .ion-arrow-resize:before, .ion-arrow-return-left:before, .ion-arrow-return-right:before, .ion-arrow-right-a:before, .ion-arrow-right-b:before, .ion-arrow-right-c:before, .ion-arrow-shrink:before, .ion-arrow-swap:before, .ion-arrow-up-a:before, .ion-arrow-up-b:before, .ion-arrow-up-c:before, .ion-asterisk:before, .ion-at:before, .ion-backspace:before, .ion-backspace-outline:before, .ion-bag:before, .ion-battery-charging:before, .ion-battery-empty:before, .ion-battery-full:before, .ion-battery-half:before, .ion-battery-low:before, .ion-beaker:before, .ion-beer:before, .ion-bluetooth:before, .ion-bonfire:before, .ion-bookmark:before, .ion-bowtie:before, .ion-briefcase:before, .ion-bug:before, .ion-calculator:before, .ion-calendar:before, .ion-camera:before, .ion-card:before, .ion-cash:before, .ion-chatbox:before, .ion-chatbox-working:before, .ion-chatboxes:before, .ion-chatbubble:before, .ion-chatbubble-working:before, .ion-chatbubbles:before, .ion-checkmark:before, .ion-checkmark-circled:before, .ion-checkmark-round:before, .ion-chevron-down:before, .ion-chevron-left:before, .ion-chevron-right:before, .ion-chevron-up:before, .ion-clipboard:before, .ion-clock:before, .ion-close:before, .ion-close-circled:before, .ion-close-round:before, .ion-closed-captioning:before, .ion-cloud:before, .ion-code:before, .ion-code-download:before, .ion-code-working:before, .ion-coffee:before, .ion-compass:before, .ion-compose:before, .ion-connection-bars:before, .ion-contrast:before, .ion-crop:before, .ion-cube:before, .ion-disc:before, .ion-document:before, .ion-document-text:before, .ion-drag:before, .ion-earth:before, .ion-easel:before, .ion-edit:before, .ion-egg:before, .ion-eject:before, .ion-email:before, .ion-email-unread:before, .ion-erlenmeyer-flask:before, .ion-erlenmeyer-flask-bubbles:before, .ion-eye:before, .ion-eye-disabled:before, .ion-female:before, .ion-filing:before, .ion-film-marker:before, .ion-fireball:before, .ion-flag:before, .ion-flame:before, .ion-flash:before, .ion-flash-off:before, .ion-folder:before, .ion-fork:before, .ion-fork-repo:before, .ion-forward:before, .ion-funnel:before, .ion-gear-a:before, .ion-gear-b:before, .ion-grid:before, .ion-hammer:before, .ion-happy:before, .ion-happy-outline:before, .ion-headphone:before, .ion-heart:before, .ion-heart-broken:before, .ion-help:before, .ion-help-buoy:before, .ion-help-circled:before, .ion-home:before, .ion-icecream:before, .ion-image:before, .ion-images:before, .ion-information:before, .ion-information-circled:before, .ion-ionic:before, .ion-ios-alarm:before, .ion-ios-alarm-outline:before, .ion-ios-albums:before, .ion-ios-albums-outline:before, .ion-ios-americanfootball:before, .ion-ios-americanfootball-outline:before, .ion-ios-analytics:before, .ion-ios-analytics-outline:before, .ion-ios-arrow-back:before, .ion-ios-arrow-down:before, .ion-ios-arrow-forward:before, .ion-ios-arrow-left:before, .ion-ios-arrow-right:before, .ion-ios-arrow-thin-down:before, .ion-ios-arrow-thin-left:before, .ion-ios-arrow-thin-right:before, .ion-ios-arrow-thin-up:before, .ion-ios-arrow-up:before, .ion-ios-at:before, .ion-ios-at-outline:before, .ion-ios-barcode:before, .ion-ios-barcode-outline:before, .ion-ios-baseball:before, .ion-ios-baseball-outline:before, .ion-ios-basketball:before, .ion-ios-basketball-outline:before, .ion-ios-bell:before, .ion-ios-bell-outline:before, .ion-ios-body:before, .ion-ios-body-outline:before, .ion-ios-bolt:before, .ion-ios-bolt-outline:before, .ion-ios-book:before, .ion-ios-book-outline:before, .ion-ios-bookmarks:before, .ion-ios-bookmarks-outline:before, .ion-ios-box:before, .ion-ios-box-outline:before, .ion-ios-briefcase:before, .ion-ios-briefcase-outline:before, .ion-ios-browsers:before, .ion-ios-browsers-outline:before, .ion-ios-calculator:before, .ion-ios-calculator-outline:before, .ion-ios-calendar:before, .ion-ios-calendar-outline:before, .ion-ios-camera:before, .ion-ios-camera-outline:before, .ion-ios-cart:before, .ion-ios-cart-outline:before, .ion-ios-chatboxes:before, .ion-ios-chatboxes-outline:before, .ion-ios-chatbubble:before, .ion-ios-chatbubble-outline:before, .ion-ios-checkmark:before, .ion-ios-checkmark-empty:before, .ion-ios-checkmark-outline:before, .ion-ios-circle-filled:before, .ion-ios-circle-outline:before, .ion-ios-clock:before, .ion-ios-clock-outline:before, .ion-ios-close:before, .ion-ios-close-empty:before, .ion-ios-close-outline:before, .ion-ios-cloud:before, .ion-ios-cloud-download:before, .ion-ios-cloud-download-outline:before, .ion-ios-cloud-outline:before, .ion-ios-cloud-upload:before, .ion-ios-cloud-upload-outline:before, .ion-ios-cloudy:before, .ion-ios-cloudy-night:before, .ion-ios-cloudy-night-outline:before, .ion-ios-cloudy-outline:before, .ion-ios-cog:before, .ion-ios-cog-outline:before, .ion-ios-color-filter:before, .ion-ios-color-filter-outline:before, .ion-ios-color-wand:before, .ion-ios-color-wand-outline:before, .ion-ios-compose:before, .ion-ios-compose-outline:before, .ion-ios-contact:before, .ion-ios-contact-outline:before, .ion-ios-copy:before, .ion-ios-copy-outline:before, .ion-ios-crop:before, .ion-ios-crop-strong:before, .ion-ios-download:before, .ion-ios-download-outline:before, .ion-ios-drag:before, .ion-ios-email:before, .ion-ios-email-outline:before, .ion-ios-eye:before, .ion-ios-eye-outline:before, .ion-ios-fastforward:before, .ion-ios-fastforward-outline:before, .ion-ios-filing:before, .ion-ios-filing-outline:before, .ion-ios-film:before, .ion-ios-film-outline:before, .ion-ios-flag:before, .ion-ios-flag-outline:before, .ion-ios-flame:before, .ion-ios-flame-outline:before, .ion-ios-flask:before, .ion-ios-flask-outline:before, .ion-ios-flower:before, .ion-ios-flower-outline:before, .ion-ios-folder:before, .ion-ios-folder-outline:before, .ion-ios-football:before, .ion-ios-football-outline:before, .ion-ios-game-controller-a:before, .ion-ios-game-controller-a-outline:before, .ion-ios-game-controller-b:before, .ion-ios-game-controller-b-outline:before, .ion-ios-gear:before, .ion-ios-gear-outline:before, .ion-ios-glasses:before, .ion-ios-glasses-outline:before, .ion-ios-grid-view:before, .ion-ios-grid-view-outline:before, .ion-ios-heart:before, .ion-ios-heart-outline:before, .ion-ios-help:before, .ion-ios-help-empty:before, .ion-ios-help-outline:before, .ion-ios-home:before, .ion-ios-home-outline:before, .ion-ios-infinite:before, .ion-ios-infinite-outline:before, .ion-ios-information:before, .ion-ios-information-empty:before, .ion-ios-information-outline:before, .ion-ios-ionic-outline:before, .ion-ios-keypad:before, .ion-ios-keypad-outline:before, .ion-ios-lightbulb:before, .ion-ios-lightbulb-outline:before, .ion-ios-list:before, .ion-ios-list-outline:before, .ion-ios-location:before, .ion-ios-location-outline:before, .ion-ios-locked:before, .ion-ios-locked-outline:before, .ion-ios-loop:before, .ion-ios-loop-strong:before, .ion-ios-medical:before, .ion-ios-medical-outline:before, .ion-ios-medkit:before, .ion-ios-medkit-outline:before, .ion-ios-mic:before, .ion-ios-mic-off:before, .ion-ios-mic-outline:before, .ion-ios-minus:before, .ion-ios-minus-empty:before, .ion-ios-minus-outline:before, .ion-ios-monitor:before, .ion-ios-monitor-outline:before, .ion-ios-moon:before, .ion-ios-moon-outline:before, .ion-ios-more:before, .ion-ios-more-outline:before, .ion-ios-musical-note:before, .ion-ios-musical-notes:before, .ion-ios-navigate:before, .ion-ios-navigate-outline:before, .ion-ios-nutrition:before, .ion-ios-nutrition-outline:before, .ion-ios-paper:before, .ion-ios-paper-outline:before, .ion-ios-paperplane:before, .ion-ios-paperplane-outline:before, .ion-ios-partlysunny:before, .ion-ios-partlysunny-outline:before, .ion-ios-pause:before, .ion-ios-pause-outline:before, .ion-ios-paw:before, .ion-ios-paw-outline:before, .ion-ios-people:before, .ion-ios-people-outline:before, .ion-ios-person:before, .ion-ios-person-outline:before, .ion-ios-personadd:before, .ion-ios-personadd-outline:before, .ion-ios-photos:before, .ion-ios-photos-outline:before, .ion-ios-pie:before, .ion-ios-pie-outline:before, .ion-ios-pint:before, .ion-ios-pint-outline:before, .ion-ios-play:before, .ion-ios-play-outline:before, .ion-ios-plus:before, .ion-ios-plus-empty:before, .ion-ios-plus-outline:before, .ion-ios-pricetag:before, .ion-ios-pricetag-outline:before, .ion-ios-pricetags:before, .ion-ios-pricetags-outline:before, .ion-ios-printer:before, .ion-ios-printer-outline:before, .ion-ios-pulse:before, .ion-ios-pulse-strong:before, .ion-ios-rainy:before, .ion-ios-rainy-outline:before, .ion-ios-recording:before, .ion-ios-recording-outline:before, .ion-ios-redo:before, .ion-ios-redo-outline:before, .ion-ios-refresh:before, .ion-ios-refresh-empty:before, .ion-ios-refresh-outline:before, .ion-ios-reload:before, .ion-ios-reverse-camera:before, .ion-ios-reverse-camera-outline:before, .ion-ios-rewind:before, .ion-ios-rewind-outline:before, .ion-ios-rose:before, .ion-ios-rose-outline:before, .ion-ios-search:before, .ion-ios-search-strong:before, .ion-ios-settings:before, .ion-ios-settings-strong:before, .ion-ios-shuffle:before, .ion-ios-shuffle-strong:before, .ion-ios-skipbackward:before, .ion-ios-skipbackward-outline:before, .ion-ios-skipforward:before, .ion-ios-skipforward-outline:before, .ion-ios-snowy:before, .ion-ios-speedometer:before, .ion-ios-speedometer-outline:before, .ion-ios-star:before, .ion-ios-star-half:before, .ion-ios-star-outline:before, .ion-ios-stopwatch:before, .ion-ios-stopwatch-outline:before, .ion-ios-sunny:before, .ion-ios-sunny-outline:before, .ion-ios-telephone:before, .ion-ios-telephone-outline:before, .ion-ios-tennisball:before, .ion-ios-tennisball-outline:before, .ion-ios-thunderstorm:before, .ion-ios-thunderstorm-outline:before, .ion-ios-time:before, .ion-ios-time-outline:before, .ion-ios-timer:before, .ion-ios-timer-outline:before, .ion-ios-toggle:before, .ion-ios-toggle-outline:before, .ion-ios-trash:before, .ion-ios-trash-outline:before, .ion-ios-undo:before, .ion-ios-undo-outline:before, .ion-ios-unlocked:before, .ion-ios-unlocked-outline:before, .ion-ios-upload:before, .ion-ios-upload-outline:before, .ion-ios-videocam:before, .ion-ios-videocam-outline:before, .ion-ios-volume-high:before, .ion-ios-volume-low:before, .ion-ios-wineglass:before, .ion-ios-wineglass-outline:before, .ion-ios-world:before, .ion-ios-world-outline:before, .ion-ipad:before, .ion-iphone:before, .ion-ipod:before, .ion-jet:before, .ion-key:before, .ion-knife:before, .ion-laptop:before, .ion-leaf:before, .ion-levels:before, .ion-lightbulb:before, .ion-link:before, .ion-load-a:before, .ion-load-b:before, .ion-load-c:before, .ion-load-d:before, .ion-location:before, .ion-lock-combination:before, .ion-locked:before, .ion-log-in:before, .ion-log-out:before, .ion-loop:before, .ion-magnet:before, .ion-male:before, .ion-man:before, .ion-map:before, .ion-medkit:before, .ion-merge:before, .ion-mic-a:before, .ion-mic-b:before, .ion-mic-c:before, .ion-minus:before, .ion-minus-circled:before, .ion-minus-round:before, .ion-model-s:before, .ion-monitor:before, .ion-more:before, .ion-mouse:before, .ion-music-note:before, .ion-navicon:before, .ion-navicon-round:before, .ion-navigate:before, .ion-network:before, .ion-no-smoking:before, .ion-nuclear:before, .ion-outlet:before, .ion-paintbrush:before, .ion-paintbucket:before, .ion-paper-airplane:before, .ion-paperclip:before, .ion-pause:before, .ion-person:before, .ion-person-add:before, .ion-person-stalker:before, .ion-pie-graph:before, .ion-pin:before, .ion-pinpoint:before, .ion-pizza:before, .ion-plane:before, .ion-planet:before, .ion-play:before, .ion-playstation:before, .ion-plus:before, .ion-plus-circled:before, .ion-plus-round:before, .ion-podium:before, .ion-pound:before, .ion-power:before, .ion-pricetag:before, .ion-pricetags:before, .ion-printer:before, .ion-pull-request:before, .ion-qr-scanner:before, .ion-quote:before, .ion-radio-waves:before, .ion-record:before, .ion-refresh:before, .ion-reply:before, .ion-reply-all:before, .ion-ribbon-a:before, .ion-ribbon-b:before, .ion-sad:before, .ion-sad-outline:before, .ion-scissors:before, .ion-search:before, .ion-settings:before, .ion-share:before, .ion-shuffle:before, .ion-skip-backward:before, .ion-skip-forward:before, .ion-social-android:before, .ion-social-android-outline:before, .ion-social-angular:before, .ion-social-angular-outline:before, .ion-social-apple:before, .ion-social-apple-outline:before, .ion-social-bitcoin:before, .ion-social-bitcoin-outline:before, .ion-social-buffer:before, .ion-social-buffer-outline:before, .ion-social-chrome:before, .ion-social-chrome-outline:before, .ion-social-codepen:before, .ion-social-codepen-outline:before, .ion-social-css3:before, .ion-social-css3-outline:before, .ion-social-designernews:before, .ion-social-designernews-outline:before, .ion-social-dribbble:before, .ion-social-dribbble-outline:before, .ion-social-dropbox:before, .ion-social-dropbox-outline:before, .ion-social-euro:before, .ion-social-euro-outline:before, .ion-social-facebook:before, .ion-social-facebook-outline:before, .ion-social-foursquare:before, .ion-social-foursquare-outline:before, .ion-social-freebsd-devil:before, .ion-social-github:before, .ion-social-github-outline:before, .ion-social-google:before, .ion-social-google-outline:before, .ion-social-googleplus:before, .ion-social-googleplus-outline:before, .ion-social-hackernews:before, .ion-social-hackernews-outline:before, .ion-social-html5:before, .ion-social-html5-outline:before, .ion-social-instagram:before, .ion-social-instagram-outline:before, .ion-social-javascript:before, .ion-social-javascript-outline:before, .ion-social-linkedin:before, .ion-social-linkedin-outline:before, .ion-social-markdown:before, .ion-social-nodejs:before, .ion-social-octocat:before, .ion-social-pinterest:before, .ion-social-pinterest-outline:before, .ion-social-python:before, .ion-social-reddit:before, .ion-social-reddit-outline:before, .ion-social-rss:before, .ion-social-rss-outline:before, .ion-social-sass:before, .ion-social-skype:before, .ion-social-skype-outline:before, .ion-social-snapchat:before, .ion-social-snapchat-outline:before, .ion-social-tumblr:before, .ion-social-tumblr-outline:before, .ion-social-tux:before, .ion-social-twitch:before, .ion-social-twitch-outline:before, .ion-social-twitter:before, .ion-social-twitter-outline:before, .ion-social-usd:before, .ion-social-usd-outline:before, .ion-social-vimeo:before, .ion-social-vimeo-outline:before, .ion-social-whatsapp:before, .ion-social-whatsapp-outline:before, .ion-social-windows:before, .ion-social-windows-outline:before, .ion-social-wordpress:before, .ion-social-wordpress-outline:before, .ion-social-yahoo:before, .ion-social-yahoo-outline:before, .ion-social-yen:before, .ion-social-yen-outline:before, .ion-social-youtube:before, .ion-social-youtube-outline:before, .ion-soup-can:before, .ion-soup-can-outline:before, .ion-speakerphone:before, .ion-speedometer:before, .ion-spoon:before, .ion-star:before, .ion-stats-bars:before, .ion-steam:before, .ion-stop:before, .ion-thermometer:before, .ion-thumbsdown:before, .ion-thumbsup:before, .ion-toggle:before, .ion-toggle-filled:before, .ion-transgender:before, .ion-trash-a:before, .ion-trash-b:before, .ion-trophy:before, .ion-tshirt:before, .ion-tshirt-outline:before, .ion-umbrella:before, .ion-university:before, .ion-unlocked:before, .ion-upload:before, .ion-usb:before, .ion-videocamera:before, .ion-volume-high:before, .ion-volume-low:before, .ion-volume-medium:before, .ion-volume-mute:before, .ion-wand:before, .ion-waterdrop:before, .ion-wifi:before, .ion-wineglass:before, .ion-woman:before, .ion-wrench:before, .ion-xbox:before { display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.ion-alert:before { content: "\f101"; }
@@ -27,27 +19,53 @@
.ion-android-add:before { content: "\f2c7"; }
-.ion-android-add-contact:before { content: "\f2c6"; }
+.ion-android-add-circle:before { content: "\f359"; }
+
+.ion-android-alarm-clock:before { content: "\f35a"; }
+
+.ion-android-alert:before { content: "\f35b"; }
-.ion-android-alarm:before { content: "\f2c8"; }
+.ion-android-apps:before { content: "\f35c"; }
.ion-android-archive:before { content: "\f2c9"; }
.ion-android-arrow-back:before { content: "\f2ca"; }
-.ion-android-arrow-down-left:before { content: "\f2cb"; }
+.ion-android-arrow-down:before { content: "\f35d"; }
+
+.ion-android-arrow-dropdown:before { content: "\f35f"; }
+
+.ion-android-arrow-dropdown-circle:before { content: "\f35e"; }
+
+.ion-android-arrow-dropleft:before { content: "\f361"; }
+
+.ion-android-arrow-dropleft-circle:before { content: "\f360"; }
+
+.ion-android-arrow-dropright:before { content: "\f363"; }
-.ion-android-arrow-down-right:before { content: "\f2cc"; }
+.ion-android-arrow-dropright-circle:before { content: "\f362"; }
+
+.ion-android-arrow-dropup:before { content: "\f365"; }
+
+.ion-android-arrow-dropup-circle:before { content: "\f364"; }
.ion-android-arrow-forward:before { content: "\f30f"; }
-.ion-android-arrow-up-left:before { content: "\f2cd"; }
+.ion-android-arrow-up:before { content: "\f366"; }
+
+.ion-android-attach:before { content: "\f367"; }
+
+.ion-android-bar:before { content: "\f368"; }
+
+.ion-android-bicycle:before { content: "\f369"; }
-.ion-android-arrow-up-right:before { content: "\f2ce"; }
+.ion-android-boat:before { content: "\f36a"; }
-.ion-android-battery:before { content: "\f2cf"; }
+.ion-android-bookmark:before { content: "\f36b"; }
-.ion-android-book:before { content: "\f2d0"; }
+.ion-android-bulb:before { content: "\f36c"; }
+
+.ion-android-bus:before { content: "\f36d"; }
.ion-android-calendar:before { content: "\f2d1"; }
@@ -55,74 +73,156 @@
.ion-android-camera:before { content: "\f2d3"; }
+.ion-android-cancel:before { content: "\f36e"; }
+
+.ion-android-car:before { content: "\f36f"; }
+
+.ion-android-cart:before { content: "\f370"; }
+
.ion-android-chat:before { content: "\f2d4"; }
-.ion-android-checkmark:before { content: "\f2d5"; }
+.ion-android-checkbox:before { content: "\f374"; }
-.ion-android-clock:before { content: "\f2d6"; }
+.ion-android-checkbox-blank:before { content: "\f371"; }
+
+.ion-android-checkbox-outline:before { content: "\f373"; }
+
+.ion-android-checkbox-outline-blank:before { content: "\f372"; }
+
+.ion-android-checkmark-circle:before { content: "\f375"; }
+
+.ion-android-clipboard:before { content: "\f376"; }
.ion-android-close:before { content: "\f2d7"; }
+.ion-android-cloud:before { content: "\f37a"; }
+
+.ion-android-cloud-circle:before { content: "\f377"; }
+
+.ion-android-cloud-done:before { content: "\f378"; }
+
+.ion-android-cloud-outline:before { content: "\f379"; }
+
+.ion-android-color-palette:before { content: "\f37b"; }
+
+.ion-android-compass:before { content: "\f37c"; }
+
.ion-android-contact:before { content: "\f2d8"; }
.ion-android-contacts:before { content: "\f2d9"; }
-.ion-android-data:before { content: "\f2da"; }
+.ion-android-contract:before { content: "\f37d"; }
-.ion-android-developer:before { content: "\f2db"; }
+.ion-android-create:before { content: "\f37e"; }
-.ion-android-display:before { content: "\f2dc"; }
+.ion-android-delete:before { content: "\f37f"; }
+
+.ion-android-desktop:before { content: "\f380"; }
+
+.ion-android-document:before { content: "\f381"; }
+
+.ion-android-done:before { content: "\f383"; }
+
+.ion-android-done-all:before { content: "\f382"; }
.ion-android-download:before { content: "\f2dd"; }
-.ion-android-drawer:before { content: "\f310"; }
+.ion-android-drafts:before { content: "\f384"; }
+
+.ion-android-exit:before { content: "\f385"; }
-.ion-android-dropdown:before { content: "\f2de"; }
+.ion-android-expand:before { content: "\f386"; }
-.ion-android-earth:before { content: "\f2df"; }
+.ion-android-favorite:before { content: "\f388"; }
+
+.ion-android-favorite-outline:before { content: "\f387"; }
+
+.ion-android-film:before { content: "\f389"; }
.ion-android-folder:before { content: "\f2e0"; }
-.ion-android-forums:before { content: "\f2e1"; }
+.ion-android-folder-open:before { content: "\f38a"; }
-.ion-android-friends:before { content: "\f2e2"; }
+.ion-android-funnel:before { content: "\f38b"; }
+
+.ion-android-globe:before { content: "\f38c"; }
.ion-android-hand:before { content: "\f2e3"; }
-.ion-android-image:before { content: "\f2e4"; }
+.ion-android-hangout:before { content: "\f38d"; }
-.ion-android-inbox:before { content: "\f2e5"; }
+.ion-android-happy:before { content: "\f38e"; }
-.ion-android-information:before { content: "\f2e6"; }
+.ion-android-home:before { content: "\f38f"; }
-.ion-android-keypad:before { content: "\f2e7"; }
+.ion-android-image:before { content: "\f2e4"; }
+
+.ion-android-laptop:before { content: "\f390"; }
-.ion-android-lightbulb:before { content: "\f2e8"; }
+.ion-android-list:before { content: "\f391"; }
.ion-android-locate:before { content: "\f2e9"; }
-.ion-android-location:before { content: "\f2ea"; }
+.ion-android-lock:before { content: "\f392"; }
.ion-android-mail:before { content: "\f2eb"; }
+.ion-android-map:before { content: "\f393"; }
+
+.ion-android-menu:before { content: "\f394"; }
+
.ion-android-microphone:before { content: "\f2ec"; }
-.ion-android-mixer:before { content: "\f2ed"; }
+.ion-android-microphone-off:before { content: "\f395"; }
+
+.ion-android-more-horizontal:before { content: "\f396"; }
+
+.ion-android-more-vertical:before { content: "\f397"; }
+
+.ion-android-navigate:before { content: "\f398"; }
+
+.ion-android-notifications:before { content: "\f39b"; }
+
+.ion-android-notifications-none:before { content: "\f399"; }
+
+.ion-android-notifications-off:before { content: "\f39a"; }
-.ion-android-more:before { content: "\f2ee"; }
+.ion-android-open:before { content: "\f39c"; }
-.ion-android-note:before { content: "\f2ef"; }
+.ion-android-options:before { content: "\f39d"; }
+
+.ion-android-people:before { content: "\f39e"; }
+
+.ion-android-person:before { content: "\f3a0"; }
+
+.ion-android-person-add:before { content: "\f39f"; }
+
+.ion-android-phone-landscape:before { content: "\f3a1"; }
+
+.ion-android-phone-portrait:before { content: "\f3a2"; }
+
+.ion-android-pin:before { content: "\f3a3"; }
+
+.ion-android-plane:before { content: "\f3a4"; }
.ion-android-playstore:before { content: "\f2f0"; }
-.ion-android-printer:before { content: "\f2f1"; }
+.ion-android-print:before { content: "\f3a5"; }
-.ion-android-promotion:before { content: "\f2f2"; }
+.ion-android-radio-button-off:before { content: "\f3a6"; }
-.ion-android-reminder:before { content: "\f2f3"; }
+.ion-android-radio-button-on:before { content: "\f3a7"; }
+
+.ion-android-refresh:before { content: "\f3a8"; }
.ion-android-remove:before { content: "\f2f4"; }
+.ion-android-remove-circle:before { content: "\f3a9"; }
+
+.ion-android-restaurant:before { content: "\f3aa"; }
+
+.ion-android-sad:before { content: "\f3ab"; }
+
.ion-android-search:before { content: "\f2f5"; }
.ion-android-send:before { content: "\f2f6"; }
@@ -131,33 +231,45 @@
.ion-android-share:before { content: "\f2f8"; }
-.ion-android-social:before { content: "\f2fa"; }
-
-.ion-android-social-user:before { content: "\f2f9"; }
+.ion-android-share-alt:before { content: "\f3ac"; }
-.ion-android-sort:before { content: "\f2fb"; }
+.ion-android-star:before { content: "\f2fc"; }
-.ion-android-stair-drawer:before { content: "\f311"; }
+.ion-android-star-half:before { content: "\f3ad"; }
-.ion-android-star:before { content: "\f2fc"; }
+.ion-android-star-outline:before { content: "\f3ae"; }
.ion-android-stopwatch:before { content: "\f2fd"; }
-.ion-android-storage:before { content: "\f2fe"; }
+.ion-android-subway:before { content: "\f3af"; }
+
+.ion-android-sunny:before { content: "\f3b0"; }
+
+.ion-android-sync:before { content: "\f3b1"; }
+
+.ion-android-textsms:before { content: "\f3b2"; }
+
+.ion-android-time:before { content: "\f3b3"; }
+
+.ion-android-train:before { content: "\f3b4"; }
-.ion-android-system-back:before { content: "\f2ff"; }
+.ion-android-unlock:before { content: "\f3b5"; }
-.ion-android-system-home:before { content: "\f300"; }
+.ion-android-upload:before { content: "\f3b6"; }
-.ion-android-system-windows:before { content: "\f301"; }
+.ion-android-volume-down:before { content: "\f3b7"; }
-.ion-android-timer:before { content: "\f302"; }
+.ion-android-volume-mute:before { content: "\f3b8"; }
-.ion-android-trash:before { content: "\f303"; }
+.ion-android-volume-off:before { content: "\f3b9"; }
-.ion-android-user-menu:before { content: "\f312"; }
+.ion-android-volume-up:before { content: "\f3ba"; }
-.ion-android-volume:before { content: "\f304"; }
+.ion-android-walk:before { content: "\f3bb"; }
+
+.ion-android-warning:before { content: "\f3bc"; }
+
+.ion-android-watch:before { content: "\f3bd"; }
.ion-android-wifi:before { content: "\f305"; }
@@ -215,6 +327,10 @@
.ion-at:before { content: "\f10f"; }
+.ion-backspace:before { content: "\f3bf"; }
+
+.ion-backspace-outline:before { content: "\f3be"; }
+
.ion-bag:before { content: "\f110"; }
.ion-battery-charging:before { content: "\f111"; }
@@ -237,6 +353,8 @@
.ion-bookmark:before { content: "\f26b"; }
+.ion-bowtie:before { content: "\f3c0"; }
+
.ion-briefcase:before { content: "\f26c"; }
.ion-bug:before { content: "\f2be"; }
@@ -307,6 +425,8 @@
.ion-contrast:before { content: "\f275"; }
+.ion-crop:before { content: "\f3c1"; }
+
.ion-cube:before { content: "\f318"; }
.ion-disc:before { content: "\f12d"; }
@@ -319,6 +439,8 @@
.ion-earth:before { content: "\f276"; }
+.ion-easel:before { content: "\f3c2"; }
+
.ion-edit:before { content: "\f2bf"; }
.ion-egg:before { content: "\f277"; }
@@ -327,6 +449,12 @@
.ion-email:before { content: "\f132"; }
+.ion-email-unread:before { content: "\f3c3"; }
+
+.ion-erlenmeyer-flask:before { content: "\f3c5"; }
+
+.ion-erlenmeyer-flask-bubbles:before { content: "\f3c4"; }
+
.ion-eye:before { content: "\f133"; }
.ion-eye-disabled:before { content: "\f306"; }
@@ -347,8 +475,6 @@
.ion-flash-off:before { content: "\f136"; }
-.ion-flask:before { content: "\f138"; }
-
.ion-folder:before { content: "\f139"; }
.ion-fork:before { content: "\f27a"; }
@@ -359,10 +485,6 @@
.ion-funnel:before { content: "\f31b"; }
-.ion-game-controller-a:before { content: "\f13b"; }
-
-.ion-game-controller-b:before { content: "\f13c"; }
-
.ion-gear-a:before { content: "\f13d"; }
.ion-gear-b:before { content: "\f13e"; }
@@ -373,6 +495,8 @@
.ion-happy:before { content: "\f31c"; }
+.ion-happy-outline:before { content: "\f3c6"; }
+
.ion-headphone:before { content: "\f140"; }
.ion-heart:before { content: "\f141"; }
@@ -389,10 +513,6 @@
.ion-icecream:before { content: "\f27d"; }
-.ion-icon-social-google-plus:before { content: "\f146"; }
-
-.ion-icon-social-google-plus-outline:before { content: "\f145"; }
-
.ion-image:before { content: "\f147"; }
.ion-images:before { content: "\f148"; }
@@ -403,479 +523,543 @@
.ion-ionic:before { content: "\f14b"; }
-.ion-ios7-alarm:before { content: "\f14d"; }
+.ion-ios-alarm:before { content: "\f3c8"; }
+
+.ion-ios-alarm-outline:before { content: "\f3c7"; }
+
+.ion-ios-albums:before { content: "\f3ca"; }
+
+.ion-ios-albums-outline:before { content: "\f3c9"; }
+
+.ion-ios-americanfootball:before { content: "\f3cc"; }
+
+.ion-ios-americanfootball-outline:before { content: "\f3cb"; }
+
+.ion-ios-analytics:before { content: "\f3ce"; }
+
+.ion-ios-analytics-outline:before { content: "\f3cd"; }
+
+.ion-ios-arrow-back:before { content: "\f3cf"; }
+
+.ion-ios-arrow-down:before { content: "\f3d0"; }
+
+.ion-ios-arrow-forward:before { content: "\f3d1"; }
+
+.ion-ios-arrow-left:before { content: "\f3d2"; }
+
+.ion-ios-arrow-right:before { content: "\f3d3"; }
+
+.ion-ios-arrow-thin-down:before { content: "\f3d4"; }
+
+.ion-ios-arrow-thin-left:before { content: "\f3d5"; }
+
+.ion-ios-arrow-thin-right:before { content: "\f3d6"; }
+
+.ion-ios-arrow-thin-up:before { content: "\f3d7"; }
+
+.ion-ios-arrow-up:before { content: "\f3d8"; }
+
+.ion-ios-at:before { content: "\f3da"; }
+
+.ion-ios-at-outline:before { content: "\f3d9"; }
+
+.ion-ios-barcode:before { content: "\f3dc"; }
+
+.ion-ios-barcode-outline:before { content: "\f3db"; }
+
+.ion-ios-baseball:before { content: "\f3de"; }
+
+.ion-ios-baseball-outline:before { content: "\f3dd"; }
+
+.ion-ios-basketball:before { content: "\f3e0"; }
+
+.ion-ios-basketball-outline:before { content: "\f3df"; }
+
+.ion-ios-bell:before { content: "\f3e2"; }
+
+.ion-ios-bell-outline:before { content: "\f3e1"; }
+
+.ion-ios-body:before { content: "\f3e4"; }
+
+.ion-ios-body-outline:before { content: "\f3e3"; }
+
+.ion-ios-bolt:before { content: "\f3e6"; }
+
+.ion-ios-bolt-outline:before { content: "\f3e5"; }
-.ion-ios7-alarm-outline:before { content: "\f14c"; }
+.ion-ios-book:before { content: "\f3e8"; }
-.ion-ios7-albums:before { content: "\f14f"; }
+.ion-ios-book-outline:before { content: "\f3e7"; }
-.ion-ios7-albums-outline:before { content: "\f14e"; }
+.ion-ios-bookmarks:before { content: "\f3ea"; }
-.ion-ios7-americanfootball:before { content: "\f31f"; }
+.ion-ios-bookmarks-outline:before { content: "\f3e9"; }
-.ion-ios7-americanfootball-outline:before { content: "\f31e"; }
+.ion-ios-box:before { content: "\f3ec"; }
-.ion-ios7-analytics:before { content: "\f321"; }
+.ion-ios-box-outline:before { content: "\f3eb"; }
-.ion-ios7-analytics-outline:before { content: "\f320"; }
+.ion-ios-briefcase:before { content: "\f3ee"; }
-.ion-ios7-arrow-back:before { content: "\f150"; }
+.ion-ios-briefcase-outline:before { content: "\f3ed"; }
-.ion-ios7-arrow-down:before { content: "\f151"; }
+.ion-ios-browsers:before { content: "\f3f0"; }
-.ion-ios7-arrow-forward:before { content: "\f152"; }
+.ion-ios-browsers-outline:before { content: "\f3ef"; }
-.ion-ios7-arrow-left:before { content: "\f153"; }
+.ion-ios-calculator:before { content: "\f3f2"; }
-.ion-ios7-arrow-right:before { content: "\f154"; }
+.ion-ios-calculator-outline:before { content: "\f3f1"; }
-.ion-ios7-arrow-thin-down:before { content: "\f27e"; }
+.ion-ios-calendar:before { content: "\f3f4"; }
-.ion-ios7-arrow-thin-left:before { content: "\f27f"; }
+.ion-ios-calendar-outline:before { content: "\f3f3"; }
-.ion-ios7-arrow-thin-right:before { content: "\f280"; }
+.ion-ios-camera:before { content: "\f3f6"; }
-.ion-ios7-arrow-thin-up:before { content: "\f281"; }
+.ion-ios-camera-outline:before { content: "\f3f5"; }
-.ion-ios7-arrow-up:before { content: "\f155"; }
+.ion-ios-cart:before { content: "\f3f8"; }
-.ion-ios7-at:before { content: "\f157"; }
+.ion-ios-cart-outline:before { content: "\f3f7"; }
-.ion-ios7-at-outline:before { content: "\f156"; }
+.ion-ios-chatboxes:before { content: "\f3fa"; }
-.ion-ios7-barcode:before { content: "\f323"; }
+.ion-ios-chatboxes-outline:before { content: "\f3f9"; }
-.ion-ios7-barcode-outline:before { content: "\f322"; }
+.ion-ios-chatbubble:before { content: "\f3fc"; }
-.ion-ios7-baseball:before { content: "\f325"; }
+.ion-ios-chatbubble-outline:before { content: "\f3fb"; }
-.ion-ios7-baseball-outline:before { content: "\f324"; }
+.ion-ios-checkmark:before { content: "\f3ff"; }
-.ion-ios7-basketball:before { content: "\f327"; }
+.ion-ios-checkmark-empty:before { content: "\f3fd"; }
-.ion-ios7-basketball-outline:before { content: "\f326"; }
+.ion-ios-checkmark-outline:before { content: "\f3fe"; }
-.ion-ios7-bell:before { content: "\f159"; }
+.ion-ios-circle-filled:before { content: "\f400"; }
-.ion-ios7-bell-outline:before { content: "\f158"; }
+.ion-ios-circle-outline:before { content: "\f401"; }
-.ion-ios7-bolt:before { content: "\f15b"; }
+.ion-ios-clock:before { content: "\f403"; }
-.ion-ios7-bolt-outline:before { content: "\f15a"; }
+.ion-ios-clock-outline:before { content: "\f402"; }
-.ion-ios7-bookmarks:before { content: "\f15d"; }
+.ion-ios-close:before { content: "\f406"; }
-.ion-ios7-bookmarks-outline:before { content: "\f15c"; }
+.ion-ios-close-empty:before { content: "\f404"; }
-.ion-ios7-box:before { content: "\f15f"; }
+.ion-ios-close-outline:before { content: "\f405"; }
-.ion-ios7-box-outline:before { content: "\f15e"; }
+.ion-ios-cloud:before { content: "\f40c"; }
-.ion-ios7-briefcase:before { content: "\f283"; }
+.ion-ios-cloud-download:before { content: "\f408"; }
-.ion-ios7-briefcase-outline:before { content: "\f282"; }
+.ion-ios-cloud-download-outline:before { content: "\f407"; }
-.ion-ios7-browsers:before { content: "\f161"; }
+.ion-ios-cloud-outline:before { content: "\f409"; }
-.ion-ios7-browsers-outline:before { content: "\f160"; }
+.ion-ios-cloud-upload:before { content: "\f40b"; }
-.ion-ios7-calculator:before { content: "\f285"; }
+.ion-ios-cloud-upload-outline:before { content: "\f40a"; }
-.ion-ios7-calculator-outline:before { content: "\f284"; }
+.ion-ios-cloudy:before { content: "\f410"; }
-.ion-ios7-calendar:before { content: "\f163"; }
+.ion-ios-cloudy-night:before { content: "\f40e"; }
-.ion-ios7-calendar-outline:before { content: "\f162"; }
+.ion-ios-cloudy-night-outline:before { content: "\f40d"; }
-.ion-ios7-camera:before { content: "\f165"; }
+.ion-ios-cloudy-outline:before { content: "\f40f"; }
-.ion-ios7-camera-outline:before { content: "\f164"; }
+.ion-ios-cog:before { content: "\f412"; }
-.ion-ios7-cart:before { content: "\f167"; }
+.ion-ios-cog-outline:before { content: "\f411"; }
-.ion-ios7-cart-outline:before { content: "\f166"; }
+.ion-ios-color-filter:before { content: "\f414"; }
-.ion-ios7-chatboxes:before { content: "\f169"; }
+.ion-ios-color-filter-outline:before { content: "\f413"; }
-.ion-ios7-chatboxes-outline:before { content: "\f168"; }
+.ion-ios-color-wand:before { content: "\f416"; }
-.ion-ios7-chatbubble:before { content: "\f16b"; }
+.ion-ios-color-wand-outline:before { content: "\f415"; }
-.ion-ios7-chatbubble-outline:before { content: "\f16a"; }
+.ion-ios-compose:before { content: "\f418"; }
-.ion-ios7-checkmark:before { content: "\f16e"; }
+.ion-ios-compose-outline:before { content: "\f417"; }
-.ion-ios7-checkmark-empty:before { content: "\f16c"; }
+.ion-ios-contact:before { content: "\f41a"; }
-.ion-ios7-checkmark-outline:before { content: "\f16d"; }
+.ion-ios-contact-outline:before { content: "\f419"; }
-.ion-ios7-circle-filled:before { content: "\f16f"; }
+.ion-ios-copy:before { content: "\f41c"; }
-.ion-ios7-circle-outline:before { content: "\f170"; }
+.ion-ios-copy-outline:before { content: "\f41b"; }
-.ion-ios7-clock:before { content: "\f172"; }
+.ion-ios-crop:before { content: "\f41e"; }
-.ion-ios7-clock-outline:before { content: "\f171"; }
+.ion-ios-crop-strong:before { content: "\f41d"; }
-.ion-ios7-close:before { content: "\f2bc"; }
+.ion-ios-download:before { content: "\f420"; }
-.ion-ios7-close-empty:before { content: "\f2bd"; }
+.ion-ios-download-outline:before { content: "\f41f"; }
-.ion-ios7-close-outline:before { content: "\f2bb"; }
+.ion-ios-drag:before { content: "\f421"; }
-.ion-ios7-cloud:before { content: "\f178"; }
+.ion-ios-email:before { content: "\f423"; }
-.ion-ios7-cloud-download:before { content: "\f174"; }
+.ion-ios-email-outline:before { content: "\f422"; }
-.ion-ios7-cloud-download-outline:before { content: "\f173"; }
+.ion-ios-eye:before { content: "\f425"; }
-.ion-ios7-cloud-outline:before { content: "\f175"; }
+.ion-ios-eye-outline:before { content: "\f424"; }
-.ion-ios7-cloud-upload:before { content: "\f177"; }
+.ion-ios-fastforward:before { content: "\f427"; }
-.ion-ios7-cloud-upload-outline:before { content: "\f176"; }
+.ion-ios-fastforward-outline:before { content: "\f426"; }
-.ion-ios7-cloudy:before { content: "\f17a"; }
+.ion-ios-filing:before { content: "\f429"; }
-.ion-ios7-cloudy-night:before { content: "\f308"; }
+.ion-ios-filing-outline:before { content: "\f428"; }
-.ion-ios7-cloudy-night-outline:before { content: "\f307"; }
+.ion-ios-film:before { content: "\f42b"; }
-.ion-ios7-cloudy-outline:before { content: "\f179"; }
+.ion-ios-film-outline:before { content: "\f42a"; }
-.ion-ios7-cog:before { content: "\f17c"; }
+.ion-ios-flag:before { content: "\f42d"; }
-.ion-ios7-cog-outline:before { content: "\f17b"; }
+.ion-ios-flag-outline:before { content: "\f42c"; }
-.ion-ios7-compose:before { content: "\f17e"; }
+.ion-ios-flame:before { content: "\f42f"; }
-.ion-ios7-compose-outline:before { content: "\f17d"; }
+.ion-ios-flame-outline:before { content: "\f42e"; }
-.ion-ios7-contact:before { content: "\f180"; }
+.ion-ios-flask:before { content: "\f431"; }
-.ion-ios7-contact-outline:before { content: "\f17f"; }
+.ion-ios-flask-outline:before { content: "\f430"; }
-.ion-ios7-copy:before { content: "\f182"; }
+.ion-ios-flower:before { content: "\f433"; }
-.ion-ios7-copy-outline:before { content: "\f181"; }
+.ion-ios-flower-outline:before { content: "\f432"; }
-.ion-ios7-download:before { content: "\f184"; }
+.ion-ios-folder:before { content: "\f435"; }
-.ion-ios7-download-outline:before { content: "\f183"; }
+.ion-ios-folder-outline:before { content: "\f434"; }
-.ion-ios7-drag:before { content: "\f185"; }
+.ion-ios-football:before { content: "\f437"; }
-.ion-ios7-email:before { content: "\f187"; }
+.ion-ios-football-outline:before { content: "\f436"; }
-.ion-ios7-email-outline:before { content: "\f186"; }
+.ion-ios-game-controller-a:before { content: "\f439"; }
-.ion-ios7-expand:before { content: "\f30d"; }
+.ion-ios-game-controller-a-outline:before { content: "\f438"; }
-.ion-ios7-eye:before { content: "\f189"; }
+.ion-ios-game-controller-b:before { content: "\f43b"; }
-.ion-ios7-eye-outline:before { content: "\f188"; }
+.ion-ios-game-controller-b-outline:before { content: "\f43a"; }
-.ion-ios7-fastforward:before { content: "\f18b"; }
+.ion-ios-gear:before { content: "\f43d"; }
-.ion-ios7-fastforward-outline:before { content: "\f18a"; }
+.ion-ios-gear-outline:before { content: "\f43c"; }
-.ion-ios7-filing:before { content: "\f18d"; }
+.ion-ios-glasses:before { content: "\f43f"; }
-.ion-ios7-filing-outline:before { content: "\f18c"; }
+.ion-ios-glasses-outline:before { content: "\f43e"; }
-.ion-ios7-film:before { content: "\f18f"; }
+.ion-ios-grid-view:before { content: "\f441"; }
-.ion-ios7-film-outline:before { content: "\f18e"; }
+.ion-ios-grid-view-outline:before { content: "\f440"; }
-.ion-ios7-flag:before { content: "\f191"; }
+.ion-ios-heart:before { content: "\f443"; }
-.ion-ios7-flag-outline:before { content: "\f190"; }
+.ion-ios-heart-outline:before { content: "\f442"; }
-.ion-ios7-folder:before { content: "\f193"; }
+.ion-ios-help:before { content: "\f446"; }
-.ion-ios7-folder-outline:before { content: "\f192"; }
+.ion-ios-help-empty:before { content: "\f444"; }
-.ion-ios7-football:before { content: "\f329"; }
+.ion-ios-help-outline:before { content: "\f445"; }
-.ion-ios7-football-outline:before { content: "\f328"; }
+.ion-ios-home:before { content: "\f448"; }
-.ion-ios7-gear:before { content: "\f195"; }
+.ion-ios-home-outline:before { content: "\f447"; }
-.ion-ios7-gear-outline:before { content: "\f194"; }
+.ion-ios-infinite:before { content: "\f44a"; }
-.ion-ios7-glasses:before { content: "\f197"; }
+.ion-ios-infinite-outline:before { content: "\f449"; }
-.ion-ios7-glasses-outline:before { content: "\f196"; }
+.ion-ios-information:before { content: "\f44d"; }
-.ion-ios7-heart:before { content: "\f199"; }
+.ion-ios-information-empty:before { content: "\f44b"; }
-.ion-ios7-heart-outline:before { content: "\f198"; }
+.ion-ios-information-outline:before { content: "\f44c"; }
-.ion-ios7-help:before { content: "\f19c"; }
+.ion-ios-ionic-outline:before { content: "\f44e"; }
-.ion-ios7-help-empty:before { content: "\f19a"; }
+.ion-ios-keypad:before { content: "\f450"; }
-.ion-ios7-help-outline:before { content: "\f19b"; }
+.ion-ios-keypad-outline:before { content: "\f44f"; }
-.ion-ios7-home:before { content: "\f32b"; }
+.ion-ios-lightbulb:before { content: "\f452"; }
-.ion-ios7-home-outline:before { content: "\f32a"; }
+.ion-ios-lightbulb-outline:before { content: "\f451"; }
-.ion-ios7-infinite:before { content: "\f19e"; }
+.ion-ios-list:before { content: "\f454"; }
-.ion-ios7-infinite-outline:before { content: "\f19d"; }
+.ion-ios-list-outline:before { content: "\f453"; }
-.ion-ios7-information:before { content: "\f1a1"; }
+.ion-ios-location:before { content: "\f456"; }
-.ion-ios7-information-empty:before { content: "\f19f"; }
+.ion-ios-location-outline:before { content: "\f455"; }
-.ion-ios7-information-outline:before { content: "\f1a0"; }
+.ion-ios-locked:before { content: "\f458"; }
-.ion-ios7-ionic-outline:before { content: "\f1a2"; }
+.ion-ios-locked-outline:before { content: "\f457"; }
-.ion-ios7-keypad:before { content: "\f1a4"; }
+.ion-ios-loop:before { content: "\f45a"; }
-.ion-ios7-keypad-outline:before { content: "\f1a3"; }
+.ion-ios-loop-strong:before { content: "\f459"; }
-.ion-ios7-lightbulb:before { content: "\f287"; }
+.ion-ios-medical:before { content: "\f45c"; }
-.ion-ios7-lightbulb-outline:before { content: "\f286"; }
+.ion-ios-medical-outline:before { content: "\f45b"; }
-.ion-ios7-location:before { content: "\f1a6"; }
+.ion-ios-medkit:before { content: "\f45e"; }
-.ion-ios7-location-outline:before { content: "\f1a5"; }
+.ion-ios-medkit-outline:before { content: "\f45d"; }
-.ion-ios7-locked:before { content: "\f1a8"; }
+.ion-ios-mic:before { content: "\f461"; }
-.ion-ios7-locked-outline:before { content: "\f1a7"; }
+.ion-ios-mic-off:before { content: "\f45f"; }
-.ion-ios7-loop:before { content: "\f32d"; }
+.ion-ios-mic-outline:before { content: "\f460"; }
-.ion-ios7-loop-strong:before { content: "\f32c"; }
+.ion-ios-minus:before { content: "\f464"; }
-.ion-ios7-medkit:before { content: "\f289"; }
+.ion-ios-minus-empty:before { content: "\f462"; }
-.ion-ios7-medkit-outline:before { content: "\f288"; }
+.ion-ios-minus-outline:before { content: "\f463"; }
-.ion-ios7-mic:before { content: "\f1ab"; }
+.ion-ios-monitor:before { content: "\f466"; }
-.ion-ios7-mic-off:before { content: "\f1a9"; }
+.ion-ios-monitor-outline:before { content: "\f465"; }
-.ion-ios7-mic-outline:before { content: "\f1aa"; }
+.ion-ios-moon:before { content: "\f468"; }
-.ion-ios7-minus:before { content: "\f1ae"; }
+.ion-ios-moon-outline:before { content: "\f467"; }
-.ion-ios7-minus-empty:before { content: "\f1ac"; }
+.ion-ios-more:before { content: "\f46a"; }
-.ion-ios7-minus-outline:before { content: "\f1ad"; }
+.ion-ios-more-outline:before { content: "\f469"; }
-.ion-ios7-monitor:before { content: "\f1b0"; }
+.ion-ios-musical-note:before { content: "\f46b"; }
-.ion-ios7-monitor-outline:before { content: "\f1af"; }
+.ion-ios-musical-notes:before { content: "\f46c"; }
-.ion-ios7-moon:before { content: "\f1b2"; }
+.ion-ios-navigate:before { content: "\f46e"; }
-.ion-ios7-moon-outline:before { content: "\f1b1"; }
+.ion-ios-navigate-outline:before { content: "\f46d"; }
-.ion-ios7-more:before { content: "\f1b4"; }
+.ion-ios-nutrition:before { content: "\f470"; }
-.ion-ios7-more-outline:before { content: "\f1b3"; }
+.ion-ios-nutrition-outline:before { content: "\f46f"; }
-.ion-ios7-musical-note:before { content: "\f1b5"; }
+.ion-ios-paper:before { content: "\f472"; }
-.ion-ios7-musical-notes:before { content: "\f1b6"; }
+.ion-ios-paper-outline:before { content: "\f471"; }
-.ion-ios7-navigate:before { content: "\f1b8"; }
+.ion-ios-paperplane:before { content: "\f474"; }
-.ion-ios7-navigate-outline:before { content: "\f1b7"; }
+.ion-ios-paperplane-outline:before { content: "\f473"; }
-.ion-ios7-paper:before { content: "\f32f"; }
+.ion-ios-partlysunny:before { content: "\f476"; }
-.ion-ios7-paper-outline:before { content: "\f32e"; }
+.ion-ios-partlysunny-outline:before { content: "\f475"; }
-.ion-ios7-paperplane:before { content: "\f1ba"; }
+.ion-ios-pause:before { content: "\f478"; }
-.ion-ios7-paperplane-outline:before { content: "\f1b9"; }
+.ion-ios-pause-outline:before { content: "\f477"; }
-.ion-ios7-partlysunny:before { content: "\f1bc"; }
+.ion-ios-paw:before { content: "\f47a"; }
-.ion-ios7-partlysunny-outline:before { content: "\f1bb"; }
+.ion-ios-paw-outline:before { content: "\f479"; }
-.ion-ios7-pause:before { content: "\f1be"; }
+.ion-ios-people:before { content: "\f47c"; }
-.ion-ios7-pause-outline:before { content: "\f1bd"; }
+.ion-ios-people-outline:before { content: "\f47b"; }
-.ion-ios7-paw:before { content: "\f331"; }
+.ion-ios-person:before { content: "\f47e"; }
-.ion-ios7-paw-outline:before { content: "\f330"; }
+.ion-ios-person-outline:before { content: "\f47d"; }
-.ion-ios7-people:before { content: "\f1c0"; }
+.ion-ios-personadd:before { content: "\f480"; }
-.ion-ios7-people-outline:before { content: "\f1bf"; }
+.ion-ios-personadd-outline:before { content: "\f47f"; }
-.ion-ios7-person:before { content: "\f1c2"; }
+.ion-ios-photos:before { content: "\f482"; }
-.ion-ios7-person-outline:before { content: "\f1c1"; }
+.ion-ios-photos-outline:before { content: "\f481"; }
-.ion-ios7-personadd:before { content: "\f1c4"; }
+.ion-ios-pie:before { content: "\f484"; }
-.ion-ios7-personadd-outline:before { content: "\f1c3"; }
+.ion-ios-pie-outline:before { content: "\f483"; }
-.ion-ios7-photos:before { content: "\f1c6"; }
+.ion-ios-pint:before { content: "\f486"; }
-.ion-ios7-photos-outline:before { content: "\f1c5"; }
+.ion-ios-pint-outline:before { content: "\f485"; }
-.ion-ios7-pie:before { content: "\f28b"; }
+.ion-ios-play:before { content: "\f488"; }
-.ion-ios7-pie-outline:before { content: "\f28a"; }
+.ion-ios-play-outline:before { content: "\f487"; }
-.ion-ios7-play:before { content: "\f1c8"; }
+.ion-ios-plus:before { content: "\f48b"; }
-.ion-ios7-play-outline:before { content: "\f1c7"; }
+.ion-ios-plus-empty:before { content: "\f489"; }
-.ion-ios7-plus:before { content: "\f1cb"; }
+.ion-ios-plus-outline:before { content: "\f48a"; }
-.ion-ios7-plus-empty:before { content: "\f1c9"; }
+.ion-ios-pricetag:before { content: "\f48d"; }
-.ion-ios7-plus-outline:before { content: "\f1ca"; }
+.ion-ios-pricetag-outline:before { content: "\f48c"; }
-.ion-ios7-pricetag:before { content: "\f28d"; }
+.ion-ios-pricetags:before { content: "\f48f"; }
-.ion-ios7-pricetag-outline:before { content: "\f28c"; }
+.ion-ios-pricetags-outline:before { content: "\f48e"; }
-.ion-ios7-pricetags:before { content: "\f333"; }
+.ion-ios-printer:before { content: "\f491"; }
-.ion-ios7-pricetags-outline:before { content: "\f332"; }
+.ion-ios-printer-outline:before { content: "\f490"; }
-.ion-ios7-printer:before { content: "\f1cd"; }
+.ion-ios-pulse:before { content: "\f493"; }
-.ion-ios7-printer-outline:before { content: "\f1cc"; }
+.ion-ios-pulse-strong:before { content: "\f492"; }
-.ion-ios7-pulse:before { content: "\f335"; }
+.ion-ios-rainy:before { content: "\f495"; }
-.ion-ios7-pulse-strong:before { content: "\f334"; }
+.ion-ios-rainy-outline:before { content: "\f494"; }
-.ion-ios7-rainy:before { content: "\f1cf"; }
+.ion-ios-recording:before { content: "\f497"; }
-.ion-ios7-rainy-outline:before { content: "\f1ce"; }
+.ion-ios-recording-outline:before { content: "\f496"; }
-.ion-ios7-recording:before { content: "\f1d1"; }
+.ion-ios-redo:before { content: "\f499"; }
-.ion-ios7-recording-outline:before { content: "\f1d0"; }
+.ion-ios-redo-outline:before { content: "\f498"; }
-.ion-ios7-redo:before { content: "\f1d3"; }
+.ion-ios-refresh:before { content: "\f49c"; }
-.ion-ios7-redo-outline:before { content: "\f1d2"; }
+.ion-ios-refresh-empty:before { content: "\f49a"; }
-.ion-ios7-refresh:before { content: "\f1d6"; }
+.ion-ios-refresh-outline:before { content: "\f49b"; }
-.ion-ios7-refresh-empty:before { content: "\f1d4"; }
+.ion-ios-reload:before { content: "\f49d"; }
-.ion-ios7-refresh-outline:before { content: "\f1d5"; }
+.ion-ios-reverse-camera:before { content: "\f49f"; }
-.ion-ios7-reload:before, .ion-ios7-reloading:before { content: "\f28e"; }
+.ion-ios-reverse-camera-outline:before { content: "\f49e"; }
-.ion-ios7-reverse-camera:before { content: "\f337"; }
+.ion-ios-rewind:before { content: "\f4a1"; }
-.ion-ios7-reverse-camera-outline:before { content: "\f336"; }
+.ion-ios-rewind-outline:before { content: "\f4a0"; }
-.ion-ios7-rewind:before { content: "\f1d8"; }
+.ion-ios-rose:before { content: "\f4a3"; }
-.ion-ios7-rewind-outline:before { content: "\f1d7"; }
+.ion-ios-rose-outline:before { content: "\f4a2"; }
-.ion-ios7-search:before { content: "\f1da"; }
+.ion-ios-search:before { content: "\f4a5"; }
-.ion-ios7-search-strong:before { content: "\f1d9"; }
+.ion-ios-search-strong:before { content: "\f4a4"; }
-.ion-ios7-settings:before { content: "\f339"; }
+.ion-ios-settings:before { content: "\f4a7"; }
-.ion-ios7-settings-strong:before { content: "\f338"; }
+.ion-ios-settings-strong:before { content: "\f4a6"; }
-.ion-ios7-shrink:before { content: "\f30e"; }
+.ion-ios-shuffle:before { content: "\f4a9"; }
-.ion-ios7-skipbackward:before { content: "\f1dc"; }
+.ion-ios-shuffle-strong:before { content: "\f4a8"; }
-.ion-ios7-skipbackward-outline:before { content: "\f1db"; }
+.ion-ios-skipbackward:before { content: "\f4ab"; }
-.ion-ios7-skipforward:before { content: "\f1de"; }
+.ion-ios-skipbackward-outline:before { content: "\f4aa"; }
-.ion-ios7-skipforward-outline:before { content: "\f1dd"; }
+.ion-ios-skipforward:before { content: "\f4ad"; }
-.ion-ios7-snowy:before { content: "\f309"; }
+.ion-ios-skipforward-outline:before { content: "\f4ac"; }
-.ion-ios7-speedometer:before { content: "\f290"; }
+.ion-ios-snowy:before { content: "\f4ae"; }
-.ion-ios7-speedometer-outline:before { content: "\f28f"; }
+.ion-ios-speedometer:before { content: "\f4b0"; }
-.ion-ios7-star:before { content: "\f1e0"; }
+.ion-ios-speedometer-outline:before { content: "\f4af"; }
-.ion-ios7-star-half:before { content: "\f33a"; }
+.ion-ios-star:before { content: "\f4b3"; }
-.ion-ios7-star-outline:before { content: "\f1df"; }
+.ion-ios-star-half:before { content: "\f4b1"; }
-.ion-ios7-stopwatch:before { content: "\f1e2"; }
+.ion-ios-star-outline:before { content: "\f4b2"; }
-.ion-ios7-stopwatch-outline:before { content: "\f1e1"; }
+.ion-ios-stopwatch:before { content: "\f4b5"; }
-.ion-ios7-sunny:before { content: "\f1e4"; }
+.ion-ios-stopwatch-outline:before { content: "\f4b4"; }
-.ion-ios7-sunny-outline:before { content: "\f1e3"; }
+.ion-ios-sunny:before { content: "\f4b7"; }
-.ion-ios7-telephone:before { content: "\f1e6"; }
+.ion-ios-sunny-outline:before { content: "\f4b6"; }
-.ion-ios7-telephone-outline:before { content: "\f1e5"; }
+.ion-ios-telephone:before { content: "\f4b9"; }
-.ion-ios7-tennisball:before { content: "\f33c"; }
+.ion-ios-telephone-outline:before { content: "\f4b8"; }
-.ion-ios7-tennisball-outline:before { content: "\f33b"; }
+.ion-ios-tennisball:before { content: "\f4bb"; }
-.ion-ios7-thunderstorm:before { content: "\f1e8"; }
+.ion-ios-tennisball-outline:before { content: "\f4ba"; }
-.ion-ios7-thunderstorm-outline:before { content: "\f1e7"; }
+.ion-ios-thunderstorm:before { content: "\f4bd"; }
-.ion-ios7-time:before { content: "\f292"; }
+.ion-ios-thunderstorm-outline:before { content: "\f4bc"; }
-.ion-ios7-time-outline:before { content: "\f291"; }
+.ion-ios-time:before { content: "\f4bf"; }
-.ion-ios7-timer:before { content: "\f1ea"; }
+.ion-ios-time-outline:before { content: "\f4be"; }
-.ion-ios7-timer-outline:before { content: "\f1e9"; }
+.ion-ios-timer:before { content: "\f4c1"; }
-.ion-ios7-toggle:before { content: "\f33e"; }
+.ion-ios-timer-outline:before { content: "\f4c0"; }
-.ion-ios7-toggle-outline:before { content: "\f33d"; }
+.ion-ios-toggle:before { content: "\f4c3"; }
-.ion-ios7-trash:before { content: "\f1ec"; }
+.ion-ios-toggle-outline:before { content: "\f4c2"; }
-.ion-ios7-trash-outline:before { content: "\f1eb"; }
+.ion-ios-trash:before { content: "\f4c5"; }
-.ion-ios7-undo:before { content: "\f1ee"; }
+.ion-ios-trash-outline:before { content: "\f4c4"; }
-.ion-ios7-undo-outline:before { content: "\f1ed"; }
+.ion-ios-undo:before { content: "\f4c7"; }
-.ion-ios7-unlocked:before { content: "\f1f0"; }
+.ion-ios-undo-outline:before { content: "\f4c6"; }
-.ion-ios7-unlocked-outline:before { content: "\f1ef"; }
+.ion-ios-unlocked:before { content: "\f4c9"; }
-.ion-ios7-upload:before { content: "\f1f2"; }
+.ion-ios-unlocked-outline:before { content: "\f4c8"; }
-.ion-ios7-upload-outline:before { content: "\f1f1"; }
+.ion-ios-upload:before { content: "\f4cb"; }
-.ion-ios7-videocam:before { content: "\f1f4"; }
+.ion-ios-upload-outline:before { content: "\f4ca"; }
-.ion-ios7-videocam-outline:before { content: "\f1f3"; }
+.ion-ios-videocam:before { content: "\f4cd"; }
-.ion-ios7-volume-high:before { content: "\f1f5"; }
+.ion-ios-videocam-outline:before { content: "\f4cc"; }
-.ion-ios7-volume-low:before { content: "\f1f6"; }
+.ion-ios-volume-high:before { content: "\f4ce"; }
-.ion-ios7-wineglass:before { content: "\f294"; }
+.ion-ios-volume-low:before { content: "\f4cf"; }
-.ion-ios7-wineglass-outline:before { content: "\f293"; }
+.ion-ios-wineglass:before { content: "\f4d1"; }
-.ion-ios7-world:before { content: "\f1f8"; }
+.ion-ios-wineglass-outline:before { content: "\f4d0"; }
-.ion-ios7-world-outline:before { content: "\f1f7"; }
+.ion-ios-world:before { content: "\f4d3"; }
+
+.ion-ios-world-outline:before { content: "\f4d2"; }
.ion-ipad:before { content: "\f1f9"; }
@@ -899,23 +1083,25 @@
.ion-link:before { content: "\f1fe"; }
-.ion-load-a:before, .ion-loading-a:before { content: "\f29a"; }
+.ion-load-a:before { content: "\f29a"; }
-.ion-load-b:before, .ion-loading-b:before { content: "\f29b"; }
+.ion-load-b:before { content: "\f29b"; }
-.ion-load-c:before, .ion-loading-c:before { content: "\f29c"; }
+.ion-load-c:before { content: "\f29c"; }
-.ion-load-d:before, .ion-loading-d:before { content: "\f29d"; }
+.ion-load-d:before { content: "\f29d"; }
.ion-location:before { content: "\f1ff"; }
+.ion-lock-combination:before { content: "\f4d4"; }
+
.ion-locked:before { content: "\f200"; }
.ion-log-in:before { content: "\f29e"; }
.ion-log-out:before { content: "\f29f"; }
-.ion-loop:before, .ion-looping:before { content: "\f201"; }
+.ion-loop:before { content: "\f201"; }
.ion-magnet:before { content: "\f2a0"; }
@@ -965,6 +1151,10 @@
.ion-outlet:before { content: "\f342"; }
+.ion-paintbrush:before { content: "\f4d5"; }
+
+.ion-paintbucket:before { content: "\f4d6"; }
+
.ion-paper-airplane:before { content: "\f2c3"; }
.ion-paperclip:before { content: "\f20f"; }
@@ -1021,7 +1211,7 @@
.ion-record:before { content: "\f21b"; }
-.ion-refresh:before, .ion-refreshing:before { content: "\f21c"; }
+.ion-refresh:before { content: "\f21c"; }
.ion-reply:before { content: "\f21e"; }
@@ -1033,6 +1223,8 @@
.ion-sad:before { content: "\f34a"; }
+.ion-sad-outline:before { content: "\f4d7"; }
+
.ion-scissors:before { content: "\f34b"; }
.ion-search:before { content: "\f21f"; }
@@ -1051,6 +1243,10 @@
.ion-social-android-outline:before { content: "\f224"; }
+.ion-social-angular:before { content: "\f4d9"; }
+
+.ion-social-angular-outline:before { content: "\f4d8"; }
+
.ion-social-apple:before { content: "\f227"; }
.ion-social-apple-outline:before { content: "\f226"; }
@@ -1063,6 +1259,18 @@
.ion-social-buffer-outline:before { content: "\f228"; }
+.ion-social-chrome:before { content: "\f4db"; }
+
+.ion-social-chrome-outline:before { content: "\f4da"; }
+
+.ion-social-codepen:before { content: "\f4dd"; }
+
+.ion-social-codepen-outline:before { content: "\f4dc"; }
+
+.ion-social-css3:before { content: "\f4df"; }
+
+.ion-social-css3-outline:before { content: "\f4de"; }
+
.ion-social-designernews:before { content: "\f22b"; }
.ion-social-designernews-outline:before { content: "\f22a"; }
@@ -1075,6 +1283,10 @@
.ion-social-dropbox-outline:before { content: "\f22e"; }
+.ion-social-euro:before { content: "\f4e1"; }
+
+.ion-social-euro-outline:before { content: "\f4e0"; }
+
.ion-social-facebook:before { content: "\f231"; }
.ion-social-facebook-outline:before { content: "\f230"; }
@@ -1101,18 +1313,34 @@
.ion-social-hackernews-outline:before { content: "\f236"; }
+.ion-social-html5:before { content: "\f4e3"; }
+
+.ion-social-html5-outline:before { content: "\f4e2"; }
+
.ion-social-instagram:before { content: "\f351"; }
.ion-social-instagram-outline:before { content: "\f350"; }
+.ion-social-javascript:before { content: "\f4e5"; }
+
+.ion-social-javascript-outline:before { content: "\f4e4"; }
+
.ion-social-linkedin:before { content: "\f239"; }
.ion-social-linkedin-outline:before { content: "\f238"; }
+.ion-social-markdown:before { content: "\f4e6"; }
+
+.ion-social-nodejs:before { content: "\f4e7"; }
+
+.ion-social-octocat:before { content: "\f4e8"; }
+
.ion-social-pinterest:before { content: "\f2b1"; }
.ion-social-pinterest-outline:before { content: "\f2b0"; }
+.ion-social-python:before { content: "\f4e9"; }
+
.ion-social-reddit:before { content: "\f23b"; }
.ion-social-reddit-outline:before { content: "\f23a"; }
@@ -1121,16 +1349,26 @@
.ion-social-rss-outline:before { content: "\f23c"; }
+.ion-social-sass:before { content: "\f4ea"; }
+
.ion-social-skype:before { content: "\f23f"; }
.ion-social-skype-outline:before { content: "\f23e"; }
+.ion-social-snapchat:before { content: "\f4ec"; }
+
+.ion-social-snapchat-outline:before { content: "\f4eb"; }
+
.ion-social-tumblr:before { content: "\f241"; }
.ion-social-tumblr-outline:before { content: "\f240"; }
.ion-social-tux:before { content: "\f2c5"; }
+.ion-social-twitch:before { content: "\f4ee"; }
+
+.ion-social-twitch-outline:before { content: "\f4ed"; }
+
.ion-social-twitter:before { content: "\f243"; }
.ion-social-twitter-outline:before { content: "\f242"; }
@@ -1143,6 +1381,10 @@
.ion-social-vimeo-outline:before { content: "\f244"; }
+.ion-social-whatsapp:before { content: "\f4f0"; }
+
+.ion-social-whatsapp-outline:before { content: "\f4ef"; }
+
.ion-social-windows:before { content: "\f247"; }
.ion-social-windows-outline:before { content: "\f246"; }
@@ -1155,10 +1397,18 @@
.ion-social-yahoo-outline:before { content: "\f24a"; }
+.ion-social-yen:before { content: "\f4f2"; }
+
+.ion-social-yen-outline:before { content: "\f4f1"; }
+
.ion-social-youtube:before { content: "\f24d"; }
.ion-social-youtube-outline:before { content: "\f24c"; }
+.ion-soup-can:before { content: "\f4f4"; }
+
+.ion-soup-can-outline:before { content: "\f4f3"; }
+
.ion-speakerphone:before { content: "\f2b2"; }
.ion-speedometer:before { content: "\f2b3"; }
@@ -1183,12 +1433,18 @@
.ion-toggle-filled:before { content: "\f354"; }
+.ion-transgender:before { content: "\f4f5"; }
+
.ion-trash-a:before { content: "\f252"; }
.ion-trash-b:before { content: "\f253"; }
.ion-trophy:before { content: "\f356"; }
+.ion-tshirt:before { content: "\f4f7"; }
+
+.ion-tshirt-outline:before { content: "\f4f6"; }
+
.ion-umbrella:before { content: "\f2b7"; }
.ion-university:before { content: "\f357"; }
diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css
index de31571..7ae4a1e 100644
--- a/public/assets/stylesheets/staff.css
+++ b/public/assets/stylesheets/staff.css
@@ -30,6 +30,23 @@ nav {
nav a {
margin-left: 10px;
}
+nav.subnav {
+ background: white;
+ padding: 10px;
+ font-weight: 200;
+ font-size: 12px;
+}
+.alphabet a {
+ margin-left: 5px;
+}
+.body .error {
+ color: #f00;
+ border: 1px solid #f00;
+ margin: 20px 5px 200px 5px;
+ padding: 10px;
+ width: 400px;
+ display: block;
+}
hr {
border: 1px solid #bbb;
margin: 10px auto 10px;
@@ -62,15 +79,36 @@ hr {
user-select: none;
}
.staff {
+ background: white;
font-size: 15px;
}
+.staff hr {
+ border: 1px solid black;
+ border-top: 0;
+}
.staff .body a {
border-bottom: 1px dotted;
}
-.staff .editLinks a {
+.staff .editLinks a, .staff a.bluelink {
color: #00f;
border-bottom: 1px solid;
}
+.staff form {
+ max-width: none;
+ width: 600px;
+ padding: 20px;
+}
+.staff form label {
+ float: none;
+}
+.staff form p {
+ width: 350px;
+ margin: 5px 0;
+ color: #444;
+}
+.staff form div li {
+ width: 180px;
+}
#iframe-embed, #iframe-embed tr, #iframe-embed td {
width: 79vw;
}
diff --git a/public/assets/test/bg.html b/public/assets/test/bg.html
index fecf811..65dd5d9 100644
--- a/public/assets/test/bg.html
+++ b/public/assets/test/bg.html
@@ -5,6 +5,7 @@
<div id="cursor" style="width:30px;height:30px;background:blue;display:inline-block;"></div>
</div>
<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
<script src="/assets/javascripts/vendor/tube.js"></script>
<script src="/assets/javascripts/vendor/loader.js"></script>
<script src="/assets/javascripts/rectangles/util/constants.js"></script>
diff --git a/public/assets/test/intersect.html b/public/assets/test/intersect.html
index 4e5b0bb..92f1d5d 100644
--- a/public/assets/test/intersect.html
+++ b/public/assets/test/intersect.html
@@ -2,6 +2,7 @@
<div id="hud"></div>
<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
<script src="/assets/javascripts/vendor/tube.js"></script>
<script src="/assets/javascripts/rectangles/util/constants.js"></script>
<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
@@ -10,11 +11,11 @@
<script src="/assets/javascripts/vendor/canvasutilities.js"></script>
<script>
-var ctx = canvas.getContext('2d')
-
var w = canvas.width = 600
var h = canvas.height = 400
+var ctx = canvas.getContext('2d')
+
var vec_a = new Rect( 100, 120, 50, 100 )
var vec_b = new Rect( 20, 200, 120, 120 )
var vecs = [ vec_a, vec_b ]
diff --git a/public/assets/test/intersect2.html b/public/assets/test/intersect2.html
index 3df9f30..553e2f7 100644
--- a/public/assets/test/intersect2.html
+++ b/public/assets/test/intersect2.html
@@ -6,9 +6,11 @@ body,html{margin:0;padding:0;}
<div id="hud"></div>
<script src="/assets/javascripts/util.js"></script>
-<script src="/assets/javascripts/vendor/tube.js"></script>
<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
-<script src="/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
<script src="/assets/javascripts/mx/mx.js"></script>
<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
<script src="/assets/javascripts/rectangles/util/constants.js"></script>
@@ -29,12 +31,12 @@ body,html{margin:0;padding:0;}
<script src="/assets/javascripts/vendor/canvasutilities.js"></script>
<script>
-var ctx = canvas.getContext('2d')
-var scene = new MX.Scene()
-
var w = canvas.width = window.innerWidth
var h = canvas.height = window.innerHeight
+var ctx = canvas.getContext('2d')
+var scene = new MX.Scene()
+
var cursor = new Rect( 150, 250, 150, 250 )
var wall_vec = new Rect ( 0, 0, 0, 0 )
var points = [ cursor.x, cursor.y ]
diff --git a/public/assets/test/intersect3.html b/public/assets/test/intersect3.html
index 5440a76..b8f9a0d 100644
--- a/public/assets/test/intersect3.html
+++ b/public/assets/test/intersect3.html
@@ -6,9 +6,11 @@ body,html{margin:0;padding:0;}
<div id="hud"></div>
<script src="/assets/javascripts/util.js"></script>
-<script src="/assets/javascripts/vendor/tube.js"></script>
<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
-<script src="/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
<script src="/assets/javascripts/mx/mx.js"></script>
<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
<script src="/assets/javascripts/rectangles/util/constants.js"></script>
@@ -29,12 +31,12 @@ body,html{margin:0;padding:0;}
<script src="/assets/javascripts/vendor/canvasutilities.js"></script>
<script>
-var ctx = canvas.getContext('2d')
-var scene = new MX.Scene()
-
var w = canvas.width = window.innerWidth
var h = canvas.height = window.innerHeight
+var ctx = canvas.getContext('2d')
+var scene = new MX.Scene()
+
var cursor = new Rect( new vec2(400, 200), new vec2(800, 500) )
var wall_vec = new Rect ( 0, 0, 0, 0 )
var points = [ cursor.x, cursor.y ]
diff --git a/public/assets/test/orbit.html b/public/assets/test/orbit.html
new file mode 100644
index 0000000..0416ff7
--- /dev/null
+++ b/public/assets/test/orbit.html
@@ -0,0 +1,154 @@
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ font-family: Menlo, monospace;
+ overflow: hidden;
+}
+#perspective {
+ position: absolute;
+ left:0%;
+ top:0px
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+#hud {
+ white-space: pre;
+}
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div id="hud"></div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+
+<script>
+
+Map.UI = Map.UI || {}
+Map.UI.Ortho = function(map){
+
+ var base = this
+
+ base.creating = base.dragging = base.resizing = false
+
+ base.mouse = new mouse({
+ el: map.el,
+ move: function(e, cursor){
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom).add(map.center.a)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b)
+ },
+ })
+}
+
+var scene, map, controls
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+})
+
+var ctx = map.draw.ctx
+
+document.addEventListener('DOMContentLoaded', build_circle)
+function add_mx_point (p, theta, i) {
+ var mx = new MX.Object3D()
+ mx.updateChildren = false
+ mx.move({
+ x: p.a,
+ y: i/2,
+ z: p.b,
+ rotationY: -theta,
+ width: 1,
+ height: i,
+ })
+ mx.el.style.backgroundColor = 'rgb(' + [abs(floor(p.a*30)), 0, abs(floor(p.b*30))] + ')'
+ mx.el.style.backfaceVisibility = "visible"
+ scene.add(mx)
+ mx.update()
+}
+function add_center () {
+ var mx = new MX.Object3D()
+ mx.width = 79
+ mx.height = 64
+ mx.y = 32 * 0.05
+ mx.scale = 0.05
+ mx.el.style.backgroundImage = "url(http://i.asdf.us/im/b8/_1400215546_frankhats_1400215573_frankhats.gif)"
+ scene.add(mx)
+}
+function build_circle () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.move({
+ "x": 0,
+ "y": 0,
+ "z": 0,
+ "rotationX": 0, // PI/2,
+ "rotationY": PI/2, // PI
+ })
+ scene.camera.radius = 20
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ var theta, rad = 16;
+ for (var i = 0; i < 100; i++) {
+ theta = (i/100 * TWO_PI)
+ add_mx_point({
+ a: sin(theta) * rad,
+ b: cos(theta) * rad,
+ }, theta, i)
+ }
+
+ add_center()
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({ el: document.querySelector("#perspective") })
+ controls.init()
+
+ console.log("ready..perhaps")
+ animate(0)
+}
+function animate(time){
+ requestAnimationFrame(animate)
+ map.update(time)
+
+ controls.update()
+ hud.innerHTML = scene.camera.toString()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ map.draw.coords()
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/ortho.html b/public/assets/test/ortho.html
new file mode 100644
index 0000000..2257006
--- /dev/null
+++ b/public/assets/test/ortho.html
@@ -0,0 +1,290 @@
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ font-family: Menlo, monospace;
+ overflow: hidden;
+}
+#perspective {
+ position: absolute;
+ left:0%;
+ top:0px
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+#hud {
+ white-space: pre;
+}
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div id="hud"></div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+
+<script>
+
+Map.UI = Map.UI || {}
+Map.UI.Ortho = function(map){
+
+ var base = this
+
+ base.creating = base.dragging = base.resizing = false
+
+ base.mouse = new mouse({
+ el: map.el,
+ down: function(e, cursor){
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom).add(map.center.a)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b)
+ // compare to initial point
+ var p = new vec2( cursor.x.a, cursor.y.a )
+ if (placing) {
+ if (points.length > 2 && points[0].distanceTo( p ) < 10/map.zoom) {
+ points.push( points[0].clone() )
+ placing = false
+ add_mx_polyline(points)
+ }
+ else {
+ points.push( p )
+ mx_points.push( add_mx_point(p) )
+ }
+ }
+ else {
+ placing = true
+ points = []
+ points.push( p )
+ mx_points.push( add_mx_point(p) )
+ }
+ },
+ move: function(e, cursor){
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom).add(map.center.a)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b)
+ last_point = new vec2( cursor.x.a, cursor.y.a )
+ if (placing && points.length > 1 && points[0].distanceTo( last_point ) < 10/map.zoom) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(points[0])
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b =last_point.b
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ },
+ drag: function(e, cursor){
+ cursor.x.b = ((cursor.x.b/map.dimensions.a)+0.5) * map.dimensions.a / map.zoom + map.center.a
+ cursor.y.b = ((cursor.y.b/map.dimensions.b)-0.5) * map.dimensions.b / map.zoom - map.center.b
+ },
+ up: function(e, cursor, new_cursor){
+ new_cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom).add(map.center.a)
+ new_cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b)
+ }
+ })
+
+ base.wheel = new wheel({
+ el: map.el,
+ update: mousewheel,
+ })
+
+ function mousewheel (e, deltaY, deltaX){
+ map.set_zoom(map.zoom_exponent - deltaY/20)
+ }
+}
+
+var scene, map, controls
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: 0,
+})
+
+var placing = false
+var points, mx_points = []
+var shapes = []
+var ctx = map.draw.ctx
+var last_point
+
+function polyline (points, finished) {
+ if (! points) return
+ if (points.length == 1) {
+ ctx.fillStyle = "#f80"
+ map.draw.dot_at(points[0].a, points[0].b, 5)
+ }
+ if (points.length > 1) {
+ ctx.fillStyle = "#ff0"
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[0].a, points[0].b)
+ points.forEach(function(point, i){
+ i && ctx.lineTo(point.a, point.b)
+ })
+ ctx.stroke()
+ if (! placing || finished) {
+ ctx.fill()
+ }
+ }
+}
+
+function add_mx_polyline (points) {
+ mx_points.forEach(function(mx){ scene.remove(mx) })
+ var faces = []
+ for (var i = 1; i < points.length; i++) {
+ var head = points[i-1]
+ var tail = points[i]
+ face = add_mx_polyline_face(head, tail)
+ faces.push(face)
+ }
+ shapes.push({
+ mx: faces,
+ points: points,
+ })
+ points = []
+}
+function add_mx_polyline_face(head, tail){
+ var mx = new MX.Object3D()
+ var mid_x = (head.a + tail.a)
+ var mid_z = (head.b + tail.b)
+ var len = head.distanceTo( tail )
+ var angle = atan2( head.b - tail.b, head.a - tail.a )
+ mx.move({
+ x: mid_x / 2,
+ y: 25 + 1,
+ z: mid_z / 2,
+ width: ceil(len),
+ height: 50,
+ rotationY: angle
+ })
+ var hue = abs(round( angle / PI * 90 + 300))
+ mx.el.style.backgroundColor = 'hsl(' + [hue, "100%", "50%"] + ')'
+ scene.add(mx)
+ return mx
+}
+
+function add_mx_point (p, i) {
+ var mx = new MX.Object3D()
+ mx.updateChildren = false
+ mx.move({
+ x: p.a,
+ y: 11,
+ z: p.b,
+ width: 20,
+ height: 20,
+ })
+ mx.el.style.backgroundColor = 'rgb(' + [abs(floor(p.a*30)), 0, abs(floor(p.b*30))] + ')'
+ mx.el.style.backfaceVisibility = "visible"
+ scene.add(mx)
+ return mx
+}
+function mx_grid () {
+ var space = 20, cells = 20, side = space*cells
+ var ctx, canvas = document.createElement("canvas")
+ canvas.width = canvas.height = side + 4
+ ctx = canvas.getContext('2d')
+
+ draw_grid(ctx, 20, 20)
+
+ var mx = new MX.Object3D(canvas)
+ mx.rotationX = PI/2
+ scene.add(mx)
+}
+function draw_grid (ctx, cells, space) {
+ var side = space * cells
+ ctx.strokeStyle = "#444"
+ ctx.lineWidth = 1
+ ctx.beginPath()
+ ctx.translate(1,1)
+ for (var i = 0; i <= cells; i++) {
+ ctx.moveTo(i*space, 0)
+ ctx.lineTo(i*space, side)
+ ctx.moveTo(0, i*space)
+ ctx.lineTo(side, i*space)
+ }
+ ctx.closePath()
+ ctx.stroke()
+}
+
+document.addEventListener('DOMContentLoaded', build)
+function build () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ mx_grid()
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ radius: 1000,
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+
+ animate(0)
+}
+function animate(time){
+ requestAnimationFrame(animate)
+ map.update(time)
+
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ map.draw.ctx.save()
+ map.draw.ctx.translate(-(20*20)/2, -(20*20)/2)
+ draw_grid(map.draw.ctx, 20, 20)
+ map.draw.ctx.restore()
+
+ map.draw.coords()
+
+ polyline(points)
+ if (placing && last_point) {
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[points.length-1].a, points[points.length-1].b)
+ ctx.lineTo(last_point.a, last_point.b)
+ ctx.stroke()
+ }
+
+ shapes.forEach(function(shape){
+ polyline(shape.points, true)
+ })
+
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/ortho2.html b/public/assets/test/ortho2.html
new file mode 100644
index 0000000..ef77256
--- /dev/null
+++ b/public/assets/test/ortho2.html
@@ -0,0 +1,374 @@
+<link href='/assets/stylesheets/ionicons.css' rel='stylesheet' type='text/css'>
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ font-family: Menlo, monospace;
+ overflow: hidden;
+}
+#perspective {
+ position: absolute;
+ left:0%;
+ top:0px
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+#hud {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: 10px;
+ background: white;
+}
+#url { width: 300px }
+#hud span { color: #888; cursor: pointer; }
+#hud span.active { color: #000; }
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div id="hud">
+ <input type="text" id="url" placeholder="paste an image URL here!">
+ <span class="ion-ionic active" data-role="orbit-mode"></span>
+ <span class="ion-archive" data-role="keyboard-mode"></span>
+</div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/defaults.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.movements.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.grid.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.image.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/coords.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/ui/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/_base.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/arrow.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+
+<script>
+var app = window.app || {}
+app.tube = new Tube ()
+app.on = function(){ app.tube.on.apply(app.tube, arguments) }
+app.off = function(){ app.tube.off.apply(app.tube, arguments) }
+
+var MapTool = Fiber.extend(function(base){
+ var exports = {
+ down: function(e, cursor){},
+ move: function(e, cursor){},
+ drag: function(e, cursor){},
+ up: function(e, cursor, new_cursor){},
+ cancel: function(){},
+ }
+ return exports
+})
+
+var PositionTool = MapTool.extend(function(base){
+ var exports = {
+ down: function(e, cursor){
+ cursor.quantize(1/map.zoom)
+ map.center.a = cursor.x.a
+ map.center.b = -cursor.y.a
+ cursor.x.b = cursor.x.a
+ cursor.y.b = cursor.y.a
+ map.ui.mouse.down = false
+ },
+ }
+ return exports
+})
+
+var PolylineTool = MapTool.extend(function (base) {
+ var exports = {}
+ exports.down = function(e, cursor){
+
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ e.preventDefault()
+ e.stopPropagation()
+ if (placing) {
+ // close polyline or cancel
+ placing = false
+ if (points.length > 2) {
+ add_mx_polyline(points)
+ }
+ else {
+ points.length = 0
+ }
+ return
+ }
+ map.ui.tools.position.down(e, cursor)
+ return
+ }
+
+ // compare to initial point
+ var p = new vec2( cursor.x.a, cursor.y.a )
+ if (placing) {
+ if (points.length > 2 && points[0].distanceTo( p ) < 10/map.zoom) {
+ points.push( points[0].clone() )
+ placing = false
+ add_mx_polyline(points)
+ }
+ else {
+ points.push( p )
+ mx_points.push( add_mx_point(p) )
+ }
+ }
+ else {
+ placing = true
+ points = []
+ points.push( p )
+ mx_points.push( add_mx_point(p) )
+ }
+ }
+ exports.move = function(e, cursor){
+ last_point = new vec2( cursor.x.a, cursor.y.a )
+ if (placing && points.length > 1 && points[0].distanceTo( last_point ) < 10/map.zoom) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(points[0])
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+ return exports
+})
+
+var scene, map, controls
+var last_point = new vec2(0,0)
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: -2,
+})
+map.ui.add_tool("arrow", new ArrowTool)
+map.ui.add_tool("polyline", new PolylineTool)
+map.ui.add_tool("position", new PositionTool)
+map.ui.set_tool("arrow")
+
+$(window).resize(function(){
+ scene.width = window.innerWidth/2
+ map.canvas.width = map.dimensions.a = window.innerWidth/2
+})
+
+var wallHeight = 180
+var placing = false
+var points, mx_points = []
+var shapes = []
+var ctx = map.draw.ctx
+var last_point
+
+shapes.findClosestPoint = function(){}
+
+function polyline (points, finished) {
+ if (! points) return
+ if (points.length == 1) {
+ ctx.fillStyle = "#f80"
+ map.draw.dot_at(points[0].a, points[0].b, 5)
+ }
+ if (points.length > 1) {
+ ctx.fillStyle = "rgba(255,255,0,0.1)"
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[0].a, points[0].b)
+ points.forEach(function(point, i){
+ i && ctx.lineTo(point.a, point.b)
+ })
+ ctx.stroke()
+ if (! placing || finished) {
+ ctx.fill()
+ }
+ }
+}
+
+function add_mx_polyline (points) {
+ mx_points.forEach(function(mx){ scene.remove(mx) })
+ var faces = []
+ for (var i = 1; i < points.length; i++) {
+ var head = points[i-1]
+ var tail = points[i]
+ face = add_mx_polyline_face(head, tail)
+ faces.push(face)
+ }
+ shapes.push({
+ mx: faces,
+ points: points,
+ })
+ points = []
+}
+function add_mx_polyline_face(head, tail){
+ var mx = new MX.Object3D()
+ var mid_x = (head.a + tail.a)
+ var mid_z = (head.b + tail.b)
+ var len = head.distanceTo( tail )
+ var angle = atan2( head.b - tail.b, head.a - tail.a )
+ mx.move({
+ x: mid_x / 2,
+ y: wallHeight/2 + 1,
+ z: mid_z / 2,
+ width: ceil(len),
+ height: wallHeight,
+ rotationY: angle
+ })
+ var hue = abs(round( angle / PI * 90 + 300))
+ mx.el.style.backgroundColor = 'hsl(' + [hue, "100%", "50%"] + ')'
+ scene.add(mx)
+ return mx
+}
+function add_mx_point (p, i) {
+ var mx = new MX.Object3D()
+ mx.updateChildren = false
+ mx.move({
+ x: p.a,
+ y: 11,
+ z: p.b,
+ width: 20,
+ height: 20,
+ rotationX: PI/2,
+ })
+ mx.el.style.backgroundColor = 'rgb(' + [abs(floor(p.a*30)), 0, abs(floor(p.b*30))] + ')'
+ mx.el.style.backfaceVisibility = "visible"
+ mx.el.style.borderRadius = "50%"
+ scene.add(mx)
+ return mx
+}
+
+$("#url").on("input", function(){
+ floorplan.load({ src: this.value })
+})
+$("[data-role=orbit-mode]").click(function(){
+ $("#hud .active").removeClass('active')
+ $(this).addClass('active')
+ controls.toggle(true)
+ movements.lock()
+})
+$("[data-role=keyboard-mode]").click(function(){
+ $("#hud .active").removeClass('active')
+ $(this).addClass('active')
+ controls.toggle(false)
+ movements.unlock()
+ movements.gravity(true)
+ cam.rotationX = 0
+ cam.rotationY = -cam.rotationY
+ cam.x = 0
+ cam.y = viewHeight + 100
+ cam.z = 0
+})
+
+document.addEventListener('DOMContentLoaded', build)
+function build () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+
+ viewHeight = 100
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ cam = scene.camera
+ movements = new MX.Movements(cam, viewHeight)
+ movements.init()
+ movements.lock()
+ movements.velocity(8)
+ app.on("move", function(pos){
+ cam.x = pos.x
+ cam.y = pos.y
+ cam.z = pos.z
+ })
+
+ floorplan = new MX.Image({
+ src: "https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg",
+ keepImage: true,
+ rotationX: -PI/2,
+ rotationY: PI,
+ })
+ scene.add(floorplan)
+ floorplan.el.addEventListener("contextmenu", function(e){
+ e.preventDefault()
+ var offset = offsetFromPoint(e, this)
+ var x = (offset.left - 0.5) * floorplan.width * floorplan.scale
+ var z = (offset.top - 0.5) * floorplan.height * floorplan.scale
+ controls.opt.center.x = -x
+ controls.opt.center.y = 0
+ controls.opt.center.z = -z
+ }, true)
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ el: scene.el,
+ radius: 3000,
+ radiusRange: [ 10, 10000 ],
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+
+ animate(0)
+}
+var last_t = 0
+function animate(t){
+ requestAnimationFrame(animate)
+
+ var dt = t - last_t
+ last_t = t
+
+ map.update(t)
+
+ movements.update(dt)
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ floorplan.draw(map.draw.ctx, true)
+
+ map.draw.coords()
+
+ polyline(points)
+ if (placing && last_point) {
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[points.length-1].a, points[points.length-1].b)
+ ctx.lineTo(last_point.a, last_point.b)
+ ctx.stroke()
+ }
+
+ shapes.forEach(function(shape){
+ polyline(shape.points, true)
+ })
+
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/ortho3.html b/public/assets/test/ortho3.html
new file mode 100644
index 0000000..71e43f1
--- /dev/null
+++ b/public/assets/test/ortho3.html
@@ -0,0 +1,258 @@
+<link href='/assets/stylesheets/ionicons.css' rel='stylesheet' type='text/css'>
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ font-family: Menlo, monospace;
+ overflow: hidden;
+}
+#perspective {
+ position: absolute;
+ left:0%;
+ top:0px
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+.hud {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: 10px;
+ background: white;
+}
+.ortho-hud {
+ left: 50%;
+ border-left: 1px solid black;
+}
+#url { width: 300px }
+.hud span { color: #888; cursor: pointer; }
+.hud span.active { color: #000; }
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div class="hud persp-hud">
+ <input type="text" id="url" placeholder="paste an image URL here!">
+ <span class="ion-ionic active" data-role="orbit-mode"></span>
+ <span class="ion-archive" data-role="keyboard-mode"></span>
+</div>
+
+<div class="hud ortho-hud">
+ <span class="ion-navigate" data-role="arrow-mode"></span>
+ <span class="ion-ios-pulse active" data-role="polyline-mode"></span>
+ <span class="ion-ios-grid-view-outline" data-role="ortho-polyline-mode"></span>
+ <span class="ion-scissors" data-role="eraser-mode"></span>
+</div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/defaults.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.movements.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.grid.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.image.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.point.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.polyline.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/coords.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/ui/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/_base.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/arrow.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/eraser.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/polyline.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/position.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/shapelist.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/polyline.js"></script>
+<script src="/assets/javascripts/ui/lib/Toolbar.js"></script>
+
+<script>
+var app = window.app || {}
+app.tube = new Tube ()
+app.on = function(){ app.tube.on.apply(app.tube, arguments) }
+app.off = function(){ app.tube.off.apply(app.tube, arguments) }
+
+var scene, map, controls
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: -2,
+ zoom_min: -6.2,
+ zoom_max: 1,
+})
+map.ui.add_tool("arrow", new ArrowTool)
+map.ui.add_tool("polyline", new PolylineTool)
+map.ui.add_tool("ortho-polyline", new OrthoPolylineTool)
+map.ui.add_tool("eraser", new EraserTool)
+map.ui.add_tool("position", new PositionTool)
+
+map.ui.placing = false
+
+$(window).resize(function(){
+ scene.width = window.innerWidth/2
+ map.canvas.width = map.dimensions.a = window.innerWidth/2
+})
+
+var wallHeight = 180
+var shapes = new ShapeList
+var ctx = map.draw.ctx
+var last_point = new vec2 (0,0)
+
+$("#url").on("input", function(){
+ floorplan.load({ src: this.value })
+})
+
+var PerspectiveToolbar = new Toolbar (".persp-hud")
+PerspectiveToolbar.add("orbit-mode", function(){
+ controls.toggle(true)
+ movements.lock()
+})
+PerspectiveToolbar.add("keyboard-mode", function(){
+ controls.toggle(false)
+ movements.unlock()
+ movements.gravity(true)
+ cam.rotationX = 0
+ cam.rotationY = -cam.rotationY
+ cam.x = 0
+ cam.y = viewHeight + 100
+ cam.z = 0
+})
+
+var OrthographicToolbar = new Toolbar (".ortho-hud")
+OrthographicToolbar.add("arrow-mode", function(){
+ map.ui.set_tool("arrow")
+})
+OrthographicToolbar.add("polyline-mode", function(){
+ map.ui.set_tool("polyline")
+})
+OrthographicToolbar.add("ortho-polyline-mode", function(){
+ map.ui.set_tool("ortho-polyline")
+})
+OrthographicToolbar.add("eraser-mode", function(){
+ map.ui.set_tool("eraser")
+})
+OrthographicToolbar.pick("ortho-polyline-mode")
+// OrthographicToolbar.pick("eraser-mode")
+
+
+document.addEventListener('DOMContentLoaded', build)
+function build () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+
+ viewHeight = 100
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ cam = scene.camera
+ movements = new MX.Movements(cam, viewHeight)
+ movements.init()
+ movements.lock()
+ movements.velocity(8)
+ app.on("move", function(pos){
+ cam.x = pos.x
+ cam.y = pos.y
+ cam.z = pos.z
+ })
+
+ floorplan = new MX.Image({
+ src: "https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg",
+ keepImage: true,
+ rotationX: -PI/2,
+ rotationY: PI,
+ })
+ scene.add(floorplan)
+
+ // recenter perspective view by rightclicking map
+ floorplan.el.addEventListener("contextmenu", function(e){
+ e.preventDefault()
+ var offset = offsetFromPoint(e, this)
+ var x = (offset.left - 0.5) * floorplan.width * floorplan.scale
+ var z = (offset.top - 0.5) * floorplan.height * floorplan.scale
+ controls.opt.center.x = -x
+ controls.opt.center.y = 0
+ controls.opt.center.z = -z
+ }, true)
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ el: scene.el,
+ radius: 3000,
+ radiusRange: [ 10, 10000 ],
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+
+ var line = new Polyline ()
+ line.add( new vec2(-100,100) )
+ line.add( new vec2(100,100) )
+ line.add( new vec2(100,-100) )
+ line.add( new vec2(-100,-100) )
+ line.close()
+ line.build()
+
+ animate(0)
+}
+var last_t = 0
+function animate(t){
+ requestAnimationFrame(animate)
+
+ var dt = t - last_t
+ last_t = t
+
+ map.update(t)
+
+ movements.update(dt)
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ floorplan.draw(map.draw.ctx, true)
+
+ map.draw.coords()
+
+ if (shapes.workline) {
+ shapes.workline.draw(map.draw.ctx)
+ if (map.ui.placing && last_point) {
+ shapes.workline.draw_line( map.draw.ctx, last_point )
+ }
+ }
+
+ shapes.forEach(function(shape){
+ shape.draw(map.draw.ctx)
+ })
+
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/ortho4.html b/public/assets/test/ortho4.html
new file mode 100644
index 0000000..8db7ead
--- /dev/null
+++ b/public/assets/test/ortho4.html
@@ -0,0 +1,303 @@
+<link href='/assets/stylesheets/app.css' rel='stylesheet' type='text/css'>
+<link href='/assets/stylesheets/ionicons.css' rel='stylesheet' type='text/css'>
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ overflow: hidden;
+}
+#perspective,
+#perspective .mx-scene {
+ position: absolute;
+ left:0%;
+ top:0px;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+}
+
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+.hud {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: 10px;
+ background: white;
+}
+.ortho-hud {
+ left: 50%;
+ border-left: 1px solid black;
+}
+#url { width: 300px }
+.hud span { color: #888; cursor: pointer; }
+.hud span.active { color: #000; }
+
+#blueprintForm {
+ width: 240px;
+}
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div class="hud persp-hud">
+ <input type="text" id="url" placeholder="paste an image URL here!">
+ <span class="ion-ionic active" data-role="orbit-mode"></span>
+ <span class="ion-archive" data-role="keyboard-mode"></span>
+</div>
+
+<div class="hud ortho-hud">
+ <span class="ion-navigate" data-role="arrow-mode"></span>
+ <span class="ion-ios-pulse active" data-role="polyline-mode"></span>
+ <span class="ion-ios-grid-view-outline" data-role="ortho-polyline-mode"></span>
+ <span class="ion-scissors" data-role="eraser-mode"></span>
+</div>
+
+<div class="mediaDrawer fixed animate blueprintUpload active">
+ <span class="close">X</span>
+ <div class="box">
+
+ <h2>Upload A Room Image</h2>
+
+ <div id="blueprintForm">
+ <div class="wallpaperUpload toolButton">
+ <form>
+ <span class="ion-ios-upload-outline upload-icon"></span>
+ <label>Upload</label>
+ <input type="file" accept="image/*" multiple>
+ </form>
+ </div>
+ <input type="text" class="url" placeholder="Enter an image URL or...">
+ </div>
+
+ Please tell us the scale of your map.
+ Click both corners of a wall, and then enter how long the wall is.
+
+ <div id="blueprintMap">
+ </div>
+
+ <div id="blueprintDimensions">
+ <input type="text" name="blueprint-dimensions">
+ <select id="blueprint-units" name="blueprint-units">
+ <option value="ft">foot</option>
+ <option value="m">meter</option>
+ </select>
+
+ <button id="saveBlueprint">Save</button>
+ </div>
+
+ </div>
+</div>
+
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/defaults.js"></script>
+
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.movements.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.grid.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.image.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.point.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.polyline.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/coords.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/ui/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/_base.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/arrow.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/eraser.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/polyline.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/position.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/shapelist.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/polyline.js"></script>
+<script src="/assets/javascripts/ui/lib/View.js"></script>
+<script src="/assets/javascripts/ui/lib/ModalView.js"></script>
+<script src="/assets/javascripts/ui/lib/UploadView.js"></script>
+<script src="/assets/javascripts/ui/lib/Parser.js"></script>
+<script src="/assets/javascripts/ui/lib/Toolbar.js"></script>
+<script src="/assets/javascripts/ui/builder/BlueprintUpload.js"></script>
+
+<script>
+var app = window.app || {}
+app.tube = new Tube ()
+app.on = function(){ app.tube.on.apply(app.tube, arguments) }
+app.off = function(){ app.tube.off.apply(app.tube, arguments) }
+
+var scene, map, controls
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: -2,
+ zoom_min: -6.2,
+ zoom_max: 1,
+})
+map.ui.add_tool("arrow", new ArrowTool)
+map.ui.add_tool("polyline", new PolylineTool)
+map.ui.add_tool("ortho-polyline", new OrthoPolylineTool)
+map.ui.add_tool("eraser", new EraserTool)
+map.ui.add_tool("position", new PositionTool)
+
+map.ui.placing = false
+
+$(window).resize(function(){
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ map.canvas.width = map.dimensions.a = window.innerWidth/2
+ map.canvas.height = map.dimensions.b = window.innerHeight/2
+})
+
+var wallHeight = 180
+var shapes = new ShapeList
+var ctx = map.draw.ctx
+var last_point = new vec2 (0,0)
+
+$("#url").on("input", function(){
+ floorplan.load({ src: this.value })
+})
+
+var PerspectiveToolbar = new Toolbar (".persp-hud")
+PerspectiveToolbar.add("orbit-mode", function(){
+ controls.toggle(true)
+ movements.lock()
+})
+PerspectiveToolbar.add("keyboard-mode", function(){
+ controls.toggle(false)
+ movements.unlock()
+ movements.gravity(true)
+ cam.rotationX = 0
+ cam.rotationY = -cam.rotationY
+ cam.x = 0
+ cam.y = viewHeight + 100
+ cam.z = 0
+})
+
+var OrthographicToolbar = new Toolbar (".ortho-hud")
+OrthographicToolbar.add("arrow-mode", function(){
+ map.ui.set_tool("arrow")
+})
+OrthographicToolbar.add("polyline-mode", function(){
+ map.ui.set_tool("polyline")
+})
+OrthographicToolbar.add("ortho-polyline-mode", function(){
+ map.ui.set_tool("ortho-polyline")
+})
+OrthographicToolbar.add("eraser-mode", function(){
+ map.ui.set_tool("eraser")
+})
+OrthographicToolbar.pick("ortho-polyline-mode")
+
+var BlueprintUpload = new BlueprintUploadView ({})
+
+document.addEventListener('DOMContentLoaded', build)
+function build () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+
+ viewHeight = 100
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ cam = scene.camera
+ movements = new MX.Movements(cam, viewHeight)
+ movements.init()
+ movements.lock()
+ movements.velocity(8)
+ app.on("move", function(pos){
+ cam.x = pos.x
+ cam.y = pos.y
+ cam.z = pos.z
+ })
+
+ floorplan = new MX.Image({
+ src: "https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg",
+ keepImage: true,
+ rotationX: -PI/2,
+ rotationY: PI,
+ })
+ scene.add(floorplan)
+
+ // recenter perspective view by rightclicking map
+ floorplan.el.addEventListener("contextmenu", function(e){
+ e.preventDefault()
+ var offset = offsetFromPoint(e, this)
+ var x = (offset.left - 0.5) * floorplan.width * floorplan.scale
+ var z = (offset.top - 0.5) * floorplan.height * floorplan.scale
+ controls.opt.center.x = -x
+ controls.opt.center.y = 0
+ controls.opt.center.z = -z
+ }, true)
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ el: scene.el,
+ radius: 3000,
+ radiusRange: [ 10, 10000 ],
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+
+ animate(0)
+}
+var last_t = 0
+function animate(t){
+ requestAnimationFrame(animate)
+
+ var dt = t - last_t
+ last_t = t
+
+ map.update(t)
+
+ movements.update(dt)
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ floorplan.draw(map.draw.ctx, true)
+
+ map.draw.coords()
+
+ if (shapes.workline) {
+ shapes.workline.draw(map.draw.ctx)
+ if (map.ui.placing && last_point) {
+ shapes.workline.draw_line( map.draw.ctx, last_point )
+ }
+ }
+
+ shapes.forEach(function(shape){
+ shape.draw(map.draw.ctx)
+ })
+
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/static.html b/public/assets/test/static.html
new file mode 100644
index 0000000..dc098de
--- /dev/null
+++ b/public/assets/test/static.html
@@ -0,0 +1,152 @@
+<!doctype html>
+<html>
+<head>
+ <title>VValls</title>
+
+<!-----+ +------+ +------+ +------+ +------+
+|`. `. |\ \ | | / /| .' .'|
+| `+------+ | +------+ +------+ +------+ | +------+' |
+| | | | | | | | | | | | | |
++ | | + | | | | | | + | | +
+ `. | | \| | | | | |/ | | .'
+ `+------+ +------+ +------+ +------+ +------+'
+ VVALLS - developed by okfoc.us
+ .+------+ +------+ +------+ +------+ +------+.
+ .' .'| / /| | | |\ \ |`. `.
++------+' | +------+ | +------+ | +------+ | `+------+
+| | | | | | | | | | | | | |
+| | + | | + | | + | | + | |
+| | .' | |/ | | \| | `. | |
++------+' +------+ +------+ +------+ `+------->
+
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable = no">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+ <meta name="description" content="3D gallery space, fully customizable" />
+ <meta name="author" content="VValls" />
+ <link rel="shortcut icon" href="/favicon.ico" />
+ <meta property="og:title" content="Leaves and such" />
+ <meta property="og:type" content="website" />
+ <meta property="og:image" content="http://www.sport-fitness-advisor.com/images/plyometric_drills_overhead_throws.gif" />
+ <meta property="og:url" content="http://vvalls.com/project/leaves-and-such-1429563199123/" />
+ <meta property="og:site_name" content="vvalls" />
+ <link rel="icon" href="/favicon.ico" type="image/x-icon">
+ <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+ <link href='http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900,100italic,300italic,400italic,700italic,900italic' rel='stylesheet' type='text/css'>
+ <link href='/assets/stylesheets/ionicons.css' rel='stylesheet' type='text/css'>
+ <link href='/assets/stylesheets/app.css' rel='stylesheet' type='text/css'>
+</head>
+<body class="loading reader">
+
+<div id="scene"></div>
+
+<div class="rapper">
+ <div id="header">
+ <a href="/" class="logo">
+ <svg version="1.1"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ x="0px" y="0px" width="117px" height="44px" viewBox="-0.896 -0.441 117 44"
+ overflow="visible" enable-background="new -0.896 -0.441 117 44" xml:space="preserve">
+ <defs>
+ </defs>
+ <path d="M0.54,38.759c0-1.44,0.66-3.72,1.56-6.18c1.38-3.84,3.42-8.22,4.5-11.16c0.48-1.32,0.78-2.34,0.78-2.88
+ c0-0.72-0.24-1.02-0.72-1.02c-1.38,0-4.74,5.16-5.4,6.24c-0.36,0.6-0.48,0.78-0.78,0.78c-0.3,0-0.48-0.06-0.48-0.36
+ c0-0.18,0.18-0.84,0.66-1.62c0.9-1.44,2.22-3.6,3.9-5.28c1.44-1.5,3.12-2.64,4.74-2.64c1.38,0,1.92,1.32,1.92,2.7
+ c0,1.02-0.42,2.58-1.02,4.32c-1.26,3.72-3.359,8.521-4.68,12.18c-0.66,1.92-1.14,3.54-1.14,4.62c0,1.38,0.48,2.459,1.979,2.459
+ c6.48,0,13.56-14.639,13.56-17.759c0-1.2-0.3-1.92-0.6-2.58c-0.42-0.9-0.9-1.62-0.9-3.18c0-1.86,0.84-2.76,1.8-2.76
+ c0.9,0,1.98,1.08,1.98,3.66c0,9.179-9.6,24.66-17.58,24.66c-2.82,0-4.08-1.561-4.08-4.141V38.759z"/>
+ <path d="M23.879,38.759c0-1.44,0.66-3.72,1.56-6.18c1.38-3.84,3.42-8.22,4.5-11.16c0.48-1.32,0.78-2.34,0.78-2.88
+ c0-0.72-0.24-1.02-0.72-1.02c-1.38,0-4.74,5.16-5.4,6.24c-0.36,0.6-0.48,0.78-0.78,0.78c-0.3,0-0.48-0.06-0.48-0.36
+ c0-0.18,0.18-0.84,0.66-1.62c0.9-1.44,2.22-3.6,3.9-5.28c1.44-1.5,3.12-2.64,4.74-2.64c1.38,0,1.92,1.32,1.92,2.7
+ c0,1.02-0.42,2.58-1.02,4.32c-1.26,3.72-3.36,8.521-4.68,12.18c-0.66,1.92-1.14,3.54-1.14,4.62c0,1.38,0.48,2.459,1.98,2.459
+ c6.479,0,13.559-14.639,13.559-17.759c0-1.2-0.3-1.92-0.6-2.58c-0.42-0.9-0.9-1.62-0.9-3.18c0-1.86,0.84-2.76,1.8-2.76
+ c0.9,0,1.979,1.08,1.979,3.66c0,9.179-9.6,24.66-17.579,24.66c-2.82,0-4.08-1.561-4.08-4.141V38.759z"/>
+ <path d="M44.339,37.799c0-5.22,2.76-10.92,6.36-15.299c3.66-4.44,8.159-7.5,11.759-7.5c2.7,0,3.78,1.44,3.9,1.44
+ s0.48-0.96,0.66-1.44c0.18-0.48,0.3-0.6,1.02-0.6h1.74c0.359,0,0.6,0.06,0.6,0.42c0,0.18-0.119,0.6-0.24,0.9
+ c-1.919,5.82-3.839,11.64-5.819,17.519c-1.14,3.48-1.26,4.381-1.26,5.041c0,0.659,0.3,0.84,0.66,0.84c0.54,0,1.68-1.141,3.72-4.26
+ c1.5-2.28,1.26-2.94,1.86-2.94c0.3,0,0.42,0.181,0.42,0.479c0,0.84-1.38,3.541-3.24,6c-1.8,2.52-4.14,4.8-6.12,4.8
+ c-1.38,0-1.62-0.96-1.62-2.159c0-0.961,0.24-2.101,0.72-3.66c0.54-1.98,1.5-4.62,2.82-8.52l-0.12-0.12
+ c-2.16,3.3-9.36,14.459-14.1,14.459c-2.76,0-3.72-2.159-3.72-5.339V37.799z M65.338,18.839c0-1.8-1.08-2.76-2.76-2.76
+ c-3,0-6.6,3.72-9.48,8.22c-2.82,4.5-4.919,9.839-4.919,13.019c0,1.561,0.54,2.641,1.86,2.641c2.22,0,6.06-4.26,9.3-9
+ c3.3-4.74,6-10.02,6-12.06V18.839z"/>
+ <path d="M72.178,39.839c0-1.08,0.479-3.479,1.2-6.479c1.74-7.02,4.979-17.52,6.6-23.64c0.66-2.46,1.08-4.2,1.08-4.8
+ c0-0.78-0.24-1.32-1.62-1.44c-1.14-0.12-1.38-0.3-1.38-0.78c0.061-0.42,0.779-0.66,1.8-0.66c2.58,0,4.2-0.78,5.16-1.38
+ c0.6-0.36,0.96-0.66,1.14-0.66c0.3,0,0.42,0.12,0.42,0.48c0,0.3-0.6,1.56-1.14,3.479c-5.04,17.759-7.38,25.799-8.46,29.698
+ c-0.84,3.061-0.96,3.84-0.96,4.681c0,0.6,0.3,1.02,0.78,1.02c0.84,0,1.619-0.659,3.479-3.72c1.08-1.74,1.92-4.199,2.46-4.199
+ c0.301,0,0.42,0.239,0.42,0.539c0,0.42-0.84,2.521-2.16,4.74c-1.739,3-4.319,6.24-6.719,6.24c-1.681,0-2.101-1.32-2.101-3.061
+ V39.839z"/>
+ <path d="M85.497,39.839c0-1.08,0.48-3.479,1.2-6.479c1.739-7.02,4.979-17.52,6.6-23.64c0.66-2.46,1.08-4.2,1.08-4.8
+ c0-0.78-0.24-1.32-1.62-1.44c-1.14-0.12-1.38-0.3-1.38-0.78c0.06-0.42,0.78-0.66,1.8-0.66c2.58,0,4.2-0.78,5.16-1.38
+ c0.6-0.36,0.96-0.66,1.14-0.66c0.3,0,0.42,0.12,0.42,0.48c0,0.3-0.6,1.56-1.14,3.479c-5.04,17.759-7.38,25.799-8.46,29.698
+ c-0.84,3.061-0.96,3.84-0.96,4.681c0,0.6,0.301,1.02,0.78,1.02c0.84,0,1.62-0.659,3.479-3.72c1.08-1.74,1.92-4.199,2.46-4.199
+ c0.3,0,0.42,0.239,0.42,0.539c0,0.42-0.84,2.521-2.159,4.74c-1.74,3-4.32,6.24-6.721,6.24c-1.68,0-2.1-1.32-2.1-3.061V39.839z"/>
+ <path d="M111.416,34.619c0,2.34-0.96,4.439-2.46,5.939c-1.68,1.68-4.02,2.64-6.479,2.64c-1.86,0-3.84-0.78-5.04-1.56
+ c-0.6-0.42-1.02-0.84-1.02-1.2c0-0.96,0.359-3.12,0.959-5.819c0.42-1.98,0.48-2.34,1.08-2.34c0.541,0,0.601,0.359,0.601,2.16
+ c0,3.84,1.2,7.319,4.92,7.319c2.34,0,4.2-2.46,4.2-4.74c0-2.819-1.561-4.979-3.24-6.96c-1.68-1.979-3.24-4.08-3.24-6.899
+ c0-4.38,3.24-8.76,7.859-8.76c3,0,5.82,1.38,5.82,2.1c0,1.14-0.301,2.4-0.66,3.9c-0.72,2.76-0.779,3.06-1.38,3.06
+ c-0.899,0-0.78-1.92-1.08-3.84c-0.3-1.86-1.08-3.78-3.6-3.78c-2.34,0-4.08,2.04-4.08,4.439s1.62,4.44,3.24,6.6
+ c1.8,2.34,3.6,4.68,3.6,7.68V34.619z"/>
+ </svg>
+ </a>
+
+ <div id="minotaur">
+ <span class="label"></span>
+ </div>
+
+ <span class="topLinks">
+ </span>
+ </div>
+
+ <div id="editorView">
+ <div class="aboutRoom vvbox">
+ <h1>
+ <span class="roomName">Leaves and such</span>
+ <br>
+ <a href="/profile/asdf" class="authorName"><div class="profilePic" style="background-image:url(https://vvalls.s3.amazonaws.com/images/avatars/20141010/1412971714922-Screen-Shot-2014-10-09-at-12.png)"></div></a>
+ <a href="/profile/asdf" class="authorName">asdf</a>
+ </h1>
+ <span class="txt">Last modified 4/20/2015</span>
+ <!--
+ <div class="share">
+ <h2>Share on–</h2>
+ <a id="share_facebook">Facebook</a>
+ <a id="share_twitter">Twitter</a>
+ </div>
+ -->
+ </div>
+
+ <div class="vvbox settings" id="mediaPlayer">
+ <span class="playButton video audio" data-role="play-media">
+ <span class="on ion-play"></span>
+ <span class="off ion-pause"></span>
+ </span>
+
+ <span class="muteButton video" data-role="mute-media">
+ <span class="on ion-volume-high"></span>
+ <span class="off ion-volume-mute"></span>
+ </span>
+
+ <span class="name"></span>
+
+ <div class="author"></div>
+ <div class="txt description"></div>
+ <div class="dimensions"></div>
+ </div>
+ </div>
+
+ <div id="minimap" class="vvbox" data-intro="Mini-map shows your position and orientation in a room. Navigate with WASD keys or drag here." data-position="top">
+ <span class="el"></span>
+ </div>
+</div>
+
+ <img src="/assets/img/keys.png" id="keyhint">
+ <img src="/assets/img/360.png" id="threesixty">
+</body>
+<script type="text/javascript">
+vvalls_data={"name":"Leaves and such","viewHeight":186,"colors":{"wall":[255,255,255],"outline":[0,0,0],"floor":[246,246,246],"ceiling":[255,255,255]},"startPosition":false,"lastPosition":{"x":-224,"y":186,"z":300.756,"rotationX":0,"rotationY":1.665},"user_id":"54383cb3b45a88b2a64dc240","slug":"leaves-and-such-1429563199123","created_at":"2015-04-01T19:08:10.150Z","photo":"https://vvalls.s3.amazonaws.com/images/projects/20150401/1427920106818-blob.png","updated_at":"2015-04-20T21:27:41.909Z","featured":false,"sculpture":[{"media":{"url":"http://www.sport-fitness-advisor.com/images/soccer_circuit_dips.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2014-11-17T16:53:21.043Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":200,"width":200,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":2.513,"rotationX":0,"z":-470.285,"y":180,"x":-1541.305},"dimensions":[200,200],"id":"sculpture1"},{"backface":true,"billboard":true,"media":{"url":"http://dumpfm.s3.amazonaws.com/images/20120519/1337401400140-dumpfm-FAUXreal-Greek_Marble_Statue.png","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-03T22:49:00.855Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":380,"width":280,"thumbnail":"","token":""},"scale":0.501,"position":{"scale":0.501,"rotationY":1.665,"rotationX":0,"z":370.922,"y":144.466,"x":-1111.901},"dimensions":[141,191],"id":"sculpture5"},{"backface":true,"billboard":false,"media":{"token":"","thumbnail":"","width":238,"height":210,"title":"","description":"","autoplay":false,"loop":false,"mute":true,"keyframe":0,"tag":"","created_at":"2014-11-17T16:53:38.690Z","user_id":"54383cb3b45a88b2a64dc240","type":"image","url":"http://www.sport-fitness-advisor.com/images/plyometric_drills_overhead_throws.gif"},"scale":0.715,"position":{"scale":0.715,"rotationY":2.911,"rotationX":0,"z":-504.672,"y":480.528,"x":-1015.969},"dimensions":[170,150],"id":"sculpture0"},{"backface":true,"billboard":false,"media":{"url":"http://dump.fm/images/20100825/1282780054021-dumpfm-timb-statue.eyez.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-03T22:48:39.613Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":409,"width":295,"thumbnail":"","token":""},"scale":0.800,"position":{"scale":0.800,"rotationY":0.827,"rotationX":0,"z":457.221,"y":250.467,"x":-1331.614},"dimensions":[236,327],"id":"sculpture2"},{"backface":true,"billboard":true,"media":{"url":"http://simpleascension.com/wp-content/uploads/2009/05/leaves.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-20T20:52:13.261Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":300,"width":300,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":1.665,"rotationX":0,"z":500.971,"y":535.5,"x":-919.926},"dimensions":[300,300],"id":"sculpture3"},{"backface":true,"billboard":false,"media":{"url":"http://simpleascension.com/wp-content/uploads/2009/05/leaves.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-20T20:52:13.261Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":300,"width":300,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":2.358,"rotationX":0,"z":-402.875,"y":493.5,"x":-1341.121},"dimensions":[300,300],"id":"sculpture4"},{"backface":true,"billboard":false,"media":{"url":"http://simpleascension.com/wp-content/uploads/2009/05/leaves.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-20T20:52:13.261Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":300,"width":300,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":2.264,"rotationX":0,"z":-310.913,"y":492,"x":-718.718},"dimensions":[300,300],"id":"sculpture6"}],"media":[{"media":{"url":"http://www.sport-fitness-advisor.com/images/plyometric_drills_overhead_throws.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2014-11-17T16:53:38.690Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":210,"width":238,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":1.570,"rotationX":0,"z":137.5,"y":350,"x":-1721},"dimensions":[238,210],"side":4,"wall_id":"4_-1731_-636","id":"scenery0"}],"walls":[{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"1_-636_-1731"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"1_-168_-204"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"2_156_-204"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"2_652_-1731"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"4_-1731_-636"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"8_726_-168"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"8_-204_-636"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"8_-204_156"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"floor"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"ceiling"}],"rooms":[{"height":681,"rect":{"y":[-168,156],"x":[-284,726]},"id":"room_0"},{"height":681,"rect":{"y":[-636,652],"x":[-1731,-204]},"id":"room_1"}],"privacy":false,"description":""}
+</script>
+<script type="text/javascript" src="/assets/javascripts/static.min.js"></script>
+<script type="text/javascript" src="http://www.youtube.com/player_api"></script>
+<script type="text/javascript" src="https://w.soundcloud.com/player/api.js"></script>
+</html>
diff --git a/public/assets/test/surface.html b/public/assets/test/surface.html
index 85e3a7b..9e6abe8 100644
--- a/public/assets/test/surface.html
+++ b/public/assets/test/surface.html
@@ -1,6 +1,7 @@
<canvas id="canvas"></canvas>
<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
<script src="/assets/javascripts/vendor/tube.js"></script>
<script src="/assets/javascripts/rectangles/util/constants.js"></script>
<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
@@ -9,11 +10,11 @@
<script src="/assets/javascripts/rectangles/models/surface.js"></script>
<script>
-var ctx = canvas.getContext('2d')
-
var w = canvas.width = 600
var h = canvas.height = 400
+var ctx = canvas.getContext('2d')
+
var surface = new Surface ()
surface.add( new Rect( new vec2(10, 100), new vec2(0, 400) ) )
surface.add( new Rect( new vec2(100, 300), new vec2(200, 400) ) )
diff --git a/server/fetch.js b/server/fetch.js
new file mode 100644
index 0000000..b76eeff
--- /dev/null
+++ b/server/fetch.js
@@ -0,0 +1,41 @@
+var DB_HOST = 'localhost'
+var mongoose = require('mongoose')
+var _ = require('lodash')
+var Project = require("./lib/schemas/Project")
+
+if (process.argv.length != 3) {
+ console.error("usage: node fetch.js [project-slug] > project.json")
+ process.exit()
+}
+var slug = process.argv[2]
+
+mongoose.connect('mongodb://' + DB_HOST + '/vvalls', {}, function(){
+ // console.error("vvalls: connected to", DB_HOST)
+ Project.findOne({ slug: slug }).exec(function(err, data){
+ if (err || ! data) {
+ console.error("Project " + slug + " not found!")
+ }
+ else {
+ console.error("Exporting " + data.name + " (" + slug + ") as JSON")
+ var str = JSON.stringify( simplify(data.toObject()) ).replace(/(\.\d\d\d)\d+/g, "$1")
+ console.log( "vvalls_data=" + str )
+ }
+ process.exit()
+ })
+})
+
+function simplify (data) {
+ delete data._id
+ delete data.__v
+ _(data).keys().forEach(function(key){
+ var val = data[key]
+ if (typeof val != "object") return;
+ if (val.hasOwnProperty('length')) {
+ data[key].forEach(simplify)
+ }
+ else {
+ data[key] = simplify(val)
+ }
+ })
+ return data
+}
diff --git a/server/index.js b/server/index.js
index 9a9323c..ccc1c26 100644
--- a/server/index.js
+++ b/server/index.js
@@ -1,4 +1,6 @@
/* jshint node: true */
+require('dotenv').config();
+
var ejs = require('ejs');
ejs.open = '[[';
ejs.close = ']]';
@@ -37,8 +39,9 @@ site.ready = function(){
}
site.setup = function(){
- var SessionStore = new MongoStore({ mongoose_connection: mongoose.connection })
+ // var SessionStore = new MongoStore({ mongoose_connection: mongoose.connection })
+ // auth.initBasicAuth(app)
app.set('port', config.port);
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'ejs');
@@ -51,20 +54,25 @@ site.setup = function(){
key: 'vvalls.sid',
secret: 'flibbertigibbet',
cookie: { domain: '.' + config.hostName, maxAge: 43200000000 },
- store: SessionStore
+ // store: SessionStore
}));
app.use(bodyParser());
app.use(multer());
+ app.use(passport.initialize());
+ app.use(passport.session());
app.use(express.query());
app.use(express.csrf());
app.use(express.methodOverride());
- app.use(passport.initialize());
- app.use(passport.session());
+
app.use(app.router);
app.set('trust proxy', true)
app.set('env', config.env.production ? "production" : "development")
app.get('env') === 'development' && app.use(express.errorHandler());
+ if (config.env.production) {
+ app.set('json spaces', 0)
+ }
+
// Essential middleware
// app.all('*', middleware.enableCORS);
app.all('*', middleware.ensureLocals);
@@ -72,11 +80,13 @@ site.setup = function(){
server = http.createServer(app)
server.listen(app.get('port'), function () {
- console.log('Express server listening on port ' + app.get('port'));
+ console.log('VValls server listening on port ' + app.get('port'));
});
// var io = websocket.listen(server)
// auth.initSockets(io, SessionStore)
+
+ middleware.updatePlans()
}
site.route = function () {
@@ -102,6 +112,7 @@ site.route = function () {
app.get('/profile', views.profile)
app.get('/profile/edit', views.profile)
+ app.get('/profile/billing', views.profile)
app.get('/profile/:username', views.profile)
app.get('/about', views.docs);
@@ -119,6 +130,9 @@ site.route = function () {
app.get('/layout', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.modal)
app.get('/layout/:name', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.builder)
+ app.get('/blueprint', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.blueprint)
+ app.get('/blueprint/:name', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.blueprint)
+
app.get('/join/:nonce', middleware.ensureAuthenticated, api.collaborator.join)
app.get('/api/collaborator/:slug/index', middleware.ensureAuthenticated, middleware.ensureProject, api.collaborator.index)
app.post('/api/collaborator/:slug/create', middleware.ensureAuthenticated, middleware.ensureProject, api.collaborator.create)
@@ -127,11 +141,12 @@ site.route = function () {
app.get('/project', middleware.ensureAuthenticated, views.modal)
app.get('/project/new', middleware.ensureAuthenticated, views.modal)
app.get('/project/new/:layout', middleware.ensureAuthenticated, views.editor_new)
+ app.get('/project/blueprint/:layout', middleware.ensureAuthenticated, views.editor_new)
app.get('/project/:slug', middleware.ensureProject, middleware.ensureIsCollaborator, views.reader)
app.get('/project/:slug/view', middleware.ensureProject, middleware.ensureIsCollaborator, views.reader)
app.get('/project/:slug/edit', middleware.ensureProject, middleware.ensureIsCollaborator, views.editor)
- app.get('/api/layout', middleware.ensureAuthenticated, api.layouts.index)
+ app.get('/api/layout', middleware.ensureAuthenticated, middleware.ensureUserProjectsCount, middleware.ensureUserLayoutsCount, api.layouts.index)
app.get('/api/layout/:slug', middleware.ensureAuthenticated, api.layouts.show)
app.post('/api/layout/new', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.create)
app.post('/api/layout/edit', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.update)
@@ -150,6 +165,21 @@ site.route = function () {
app.post('/api/media/upload', middleware.ensureAuthenticated, api.media.upload)
app.delete('/api/media/destroy', middleware.ensureAuthenticated, api.media.destroy)
+ app.post('/api/blueprint/new', middleware.ensureAuthenticated, api.blueprint.create)
+ app.post('/api/blueprint/upload', middleware.ensureAuthenticated, api.blueprint.upload)
+ app.get('/api/blueprint/user/:slug', middleware.ensureAuthenticated, api.blueprint.show)
+ app.get('/api/blueprint/user', middleware.ensureAuthenticated, api.blueprint.user)
+ app.post('/api/blueprint/scale', middleware.ensureAuthenticated, api.blueprint.scale)
+ app.post('/api/blueprint/edit', middleware.ensureAuthenticated, api.blueprint.update)
+ app.delete('/api/blueprint/destroy', middleware.ensureAuthenticated, api.blueprint.destroy)
+
+ app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show)
+ app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.update)
+ app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.sync)
+ app.delete('/api/subscription/destroy', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy)
+
+ app.get('/partials/plans', views.partials.plans)
+
app.get('/test/*', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.modal)
views.staff.route(app)
diff --git a/server/lib/api/blueprint.js b/server/lib/api/blueprint.js
new file mode 100644
index 0000000..e780b92
--- /dev/null
+++ b/server/lib/api/blueprint.js
@@ -0,0 +1,142 @@
+/* jshint node: true */
+
+var _ = require('lodash'),
+ crypto = require('crypto'),
+ util = require('../util'),
+ upload = require('../upload'),
+ config = require('../../../config.json'),
+ Blueprint = require('../schemas/Blueprint');
+
+var blueprint = {
+
+ user: function(req, res){
+ var offset = Number(req.query.offset) || 0
+ var limit = Math.min( Number(req.query.limit), 50 ) || 20
+ var query = { user_id: req.user._id }
+ if (req.query.tag) {
+ query.tag = req.query.tag
+ }
+ Blueprint.find(query)
+ .sort({'created_at': -1})
+ .skip(offset)
+ .limit(limit)
+ .exec(function(err, media){
+ res.json(media || [])
+ })
+ },
+
+ show: function(req, res){
+ Blueprint.findOne({ slug: req.params.slug }, function(err, doc){
+ if (doc) {
+ res.json(doc)
+ return
+ }
+ else {
+ Project.count({}, function(err, count){
+ var name = "Project #" + (count || 0)
+ res.json({ _id: "new", name: name, isNew: true })
+ })
+ }
+ })
+ },
+
+ create: function(req, res){
+ var data = util.cleanQuery(req.body)
+ data.user_id = req.user._id
+ data.created_at = new Date ()
+
+ if (data.tag) {
+ data.tag = util.sanitize(data.tag)
+ }
+
+ new Blueprint(data).save(function(err, rec){
+ if (err || ! rec) { return res.json({ error: err }) }
+ return res.json(rec)
+ })
+ },
+
+ upload: function(req, res){
+ var data = util.cleanQuery(req.body)
+ data.user_id = req.user._id
+ data.created_at = new Date ()
+ data.type = "image"
+
+ upload.put("media", req.files.image, {
+ username: req.user.username,
+ unacceptable: function(err){
+ res.json({ error: { errors: { media: { message: "Problem saving image: " + err } } } })
+ },
+ success: function(url){
+ data.url = url
+ done()
+ }
+ })
+
+ function done () {
+ new Blueprint(data).save(function(err, rec) {
+ if (err || ! rec) { return res.json({ error: err }) }
+ res.json(rec)
+ })
+ }
+ },
+
+ scale: function(req, res){
+ var _id = req.body._id
+ var data = util.cleanQuery(req.body)
+ if (! _id) { return res.json({ error: 404 }) }
+ Blueprint.findOne({ _id: _id }, function(err, doc){
+ if (! doc) { return res.json({ error: 404 }) }
+ if (String(doc.user_id) !== String(req.user._id)) { return res.json({ error: 404 }) }
+ doc.scale = data.scale
+ doc.units = data.units
+ doc.line = data.line
+ doc.save(function(err, rec){
+ if (err || ! rec) { return res.json({ error: err }) }
+ res.json(rec)
+ })
+ })
+ },
+
+ update: function(req, res){
+ var _id = req.body._id
+ var data = util.cleanQuery(req.body)
+ if (! _id) { return res.json({ error: 404 }) }
+ Blueprint.findOne({ _id: _id }, function(err, doc){
+ if (! doc) { return res.json({ error: 404 }) }
+ if (String(doc.user_id) !== String(req.user._id)) { return res.json({ error: 404 }) }
+
+ doc.name = util.sanitize(data.name)
+ doc.slug = util.slugify(data.name)
+ doc.units = util.sanitize(data.units)
+ doc.viewHeight = util.sanitizeNumber(data.viewHeight)
+ doc.wallHeight = util.sanitizeNumber(data.wallHeight)
+ doc.shapes = JSON.parse(data.shapes)
+ doc.startPosition = JSON.parse(data.startPosition)
+
+ doc.save(function(err, rec){
+ if (err || ! rec) { return res.json({ error: err }) }
+ res.json(rec)
+ })
+ })
+ },
+
+ destroy: function(req, res){
+ var _id = util.sanitize(req.body._id)
+ if (! _id || ! _id.length) {
+ res.json({ error: 404 })
+ return
+ }
+ Blueprint.findOne({ _id: _id }, function(err, doc){
+ if (! doc) { return res.json({ error: 404 }) }
+ if (String(doc.user_id) !== String(req.user._id)) {
+ return res.json({ error: "access denied" })
+ }
+ Blueprint.remove({ _id: _id }, function(err){
+ res.json({ status: "OK" })
+ })
+ })
+ }
+
+}
+
+module.exports = blueprint
diff --git a/server/lib/api/index.js b/server/lib/api/index.js
index 11e13fc..8254232 100644
--- a/server/lib/api/index.js
+++ b/server/lib/api/index.js
@@ -1,6 +1,7 @@
/* jshint node: true */
var api = {
+ blueprint: require('./blueprint'),
docs: require('./docs'),
layouts: require('./layouts'),
media: require('./media'),
@@ -8,6 +9,7 @@ var api = {
projects: require('./projects'),
rooms: require('./rooms'),
collaborator: require('./collaborator'),
+ subscription: require('./subscription'),
}
module.exports = api
diff --git a/server/lib/api/layouts.js b/server/lib/api/layouts.js
index 641e9e2..c04f926 100644
--- a/server/lib/api/layouts.js
+++ b/server/lib/api/layouts.js
@@ -3,13 +3,26 @@
var _ = require('lodash'),
util = require('../util'),
upload = require('../upload'),
+ middleware = require('../middleware'),
config = require('../../../config.json'),
+ Blueprint = require('../schemas/Blueprint'),
Layout = require('../schemas/Layout');
var layouts = {
index: function(req, res){
- Layout.find({}, function(err, docs){
- res.json(docs)
+ Layout.find({ is_stock: true }, function(err, stock_layouts){
+ Layout.find({ user_id: req.user._id, is_stock: false }, function(err, user_layouts){
+ Blueprint.find({ user_id: req.user._id }, function(err, blueprints){
+ res.json({
+ layouts: stock_layouts,
+ user_layouts: user_layouts,
+ blueprints: blueprints,
+ user: res.locals.user,
+ layoutCount: res.locals.layoutCount,
+ projectCount: res.locals.projectCount,
+ })
+ })
+ })
})
},
diff --git a/server/lib/api/profile.js b/server/lib/api/profile.js
index 996505f..d72a2c3 100644
--- a/server/lib/api/profile.js
+++ b/server/lib/api/profile.js
@@ -32,6 +32,7 @@ var profile = {
delete data.old_password
delete data.new_password
delete data.isStaff
+ delete data.plan_level
data.updated_at = new Date ()
if (req.files.avatar) {
diff --git a/server/lib/api/projects.js b/server/lib/api/projects.js
index 1bf046f..50d3b49 100644
--- a/server/lib/api/projects.js
+++ b/server/lib/api/projects.js
@@ -37,9 +37,15 @@ var projects = {
data.slug = util.slugify(data.name) + "-" + (+new Date)
data.description = util.sanitize(data.description)
data.viewHeight = Number(data.viewHeight || 0)
- data.rooms = JSON.parse(data.rooms)
+ if (data.shapes) {
+ data.shapes = JSON.parse(data.shapes)
+ }
+ else {
+ data.rooms = JSON.parse(data.rooms)
+ }
data.walls = JSON.parse(data.walls)
data.media = JSON.parse(data.media)
+ data.sculpture = JSON.parse(data.sculpture)
data.colors = JSON.parse(data.colors)
data.startPosition = JSON.parse(data.startPosition)
data.lastPosition = JSON.parse(data.lastPosition)
@@ -100,11 +106,17 @@ var projects = {
data.updated_at = new Date ()
_.extend(doc, data)
-
- doc.rooms = JSON.parse(data.rooms)
+
+ if (data.shapes) {
+ doc.shapes = JSON.parse(data.shapes)
+ }
+ else {
+ doc.rooms = JSON.parse(data.rooms)
+ }
doc.walls = JSON.parse(data.walls)
doc.colors = JSON.parse(data.colors)
doc.media = JSON.parse(data.media)
+ doc.sculpture = JSON.parse(data.sculpture)
doc.startPosition = JSON.parse(data.startPosition)
doc.lastPosition = JSON.parse(data.lastPosition)
diff --git a/server/lib/api/rooms.js b/server/lib/api/rooms.js
index c044309..2a1d2fe 100644
--- a/server/lib/api/rooms.js
+++ b/server/lib/api/rooms.js
@@ -6,6 +6,8 @@ var Clipper = require("../../../public/assets/javascripts/rectangles/engine/room
var Builder = require("../../../public/assets/javascripts/rectangles/engine/rooms/builder.js")
var Grouper = require("../../../public/assets/javascripts/rectangles/engine/rooms/grouper.js")
var Walls = require("../../../public/assets/javascripts/rectangles/engine/rooms/_walls.js")
+var shapes = require("../../../public/assets/javascripts/rectangles/engine/shapes/shapelist.js")
+var RegionList = require("../../../public/assets/javascripts/rectangles/engine/shapes/regionlist.js")
/* jshint node: true */
@@ -21,47 +23,106 @@ var rooms = module.exports = {
if (! doc) { res.json({ status: 404 }); return }
doc = doc.toObject()
- doc.rooms.forEach(function(data){
- var rect = new Rect(data.rect.x[0], data.rect.y[0], data.rect.x[1], data.rect.y[1])
- var room = new Room({
- id: data.id,
- rect: rect,
- height: data.height
- })
- Rooms.add(room)
- })
- Rooms.clipper.solve_rects()
- Rooms.builder.build()
-
- var walls = [], mx_walls = [], mx_floor = [], mx_ceiling = []
- var collections = Rooms.grouper.collect()
- Rooms.grouper.cull(collections)
- Rooms.grouper.group(walls, collections, FRONT)
- Rooms.grouper.group(walls, collections, BACK)
- Rooms.grouper.group(walls, collections, LEFT)
- Rooms.grouper.group(walls, collections, RIGHT)
- walls.forEach(function(wall){
- wall.mx.forEach(function(mx){
- var data = mx.report()
- data.id = wall.id
- mx_walls.push(data)
- })
- })
-
- doc.mx_walls = mx_walls
- doc.mx_floor = mx_floor
- doc.mx_ceiling = mx_ceiling
-
- Rooms.forEach(function(room){
- room.mx_floor.forEach(function(mx){
- mx_floor.push( mx.report() )
- })
- room.mx_ceiling.forEach(function(mx){
- mx_ceiling.push( mx.report() )
- })
- })
+ if (doc.shapes.length) {
+ parseMxShapes(doc)
+ }
+ else {
+ parseMxRooms(doc)
+ }
res.json(doc)
})
}
}
+
+function parseMxShapes (doc) {
+ var viewHeight = doc.viewHeight
+ var wallHeight = doc.wallHeight
+
+ shapes.deserialize( doc.shapes )
+
+ var walls = [], mx_walls = [], mx_floor = [], mx_ceiling = []
+ var regions = RegionList.build()
+
+ regions.forEach(function(region){
+ var room = new Room({
+ rect: region,
+ regions: [region],
+ height: wallHeight,
+ })
+
+ room.sides = region.sides
+ region.id = Rooms.uid("room_")
+ Rooms.list[ region.id ] = room
+ Rooms.builder.build_walls(region)
+ mx_floor.push( Rooms.builder.make_floor(room, region) )
+ mx_ceiling.push( Rooms.builder.make_ceiling(room, region) )
+ })
+
+ var collections = Rooms.grouper.collect()
+ Rooms.grouper.cull(collections)
+ Rooms.grouper.group(walls, collections, FRONT)
+ Rooms.grouper.group(walls, collections, BACK)
+ Rooms.grouper.group(walls, collections, LEFT)
+ Rooms.grouper.group(walls, collections, RIGHT)
+ walls.forEach(function(wall){
+ wall.mx.forEach(function(mx){
+ var data = mx.report()
+ data.id = wall.id
+ mx_walls.push(data)
+ })
+ })
+
+ doc.mx_walls = mx_walls
+ doc.mx_floor = mx_floor
+ doc.mx_ceiling = mx_ceiling
+
+ Rooms.forEach(function(room){
+ mx_floor.push( room.mx_floor )
+ room.mx_ceiling.forEach(function(mx){
+ mx_ceiling.push( mx.report() )
+ })
+ })
+}
+
+function parseMxRooms (doc) {
+ doc.rooms.forEach(function(data){
+ var rect = new Rect(data.rect.x[0], data.rect.y[0], data.rect.x[1], data.rect.y[1])
+ var room = new Room({
+ id: data.id,
+ rect: rect,
+ height: data.height
+ })
+ Rooms.add(room)
+ })
+ Rooms.clipper.solve_rects()
+ Rooms.builder.build()
+
+ var walls = [], mx_walls = [], mx_floor = [], mx_ceiling = []
+ var collections = Rooms.grouper.collect()
+ Rooms.grouper.cull(collections)
+ Rooms.grouper.group(walls, collections, FRONT)
+ Rooms.grouper.group(walls, collections, BACK)
+ Rooms.grouper.group(walls, collections, LEFT)
+ Rooms.grouper.group(walls, collections, RIGHT)
+ walls.forEach(function(wall){
+ wall.mx.forEach(function(mx){
+ var data = mx.report()
+ data.id = wall.id
+ mx_walls.push(data)
+ })
+ })
+
+ doc.mx_walls = mx_walls
+ doc.mx_floor = mx_floor
+ doc.mx_ceiling = mx_ceiling
+
+ Rooms.forEach(function(room){
+ room.mx_floor.forEach(function(mx){
+ mx_floor.push( mx.report() )
+ })
+ room.mx_ceiling.forEach(function(mx){
+ mx_ceiling.push( mx.report() )
+ })
+ })
+} \ No newline at end of file
diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js
new file mode 100644
index 0000000..c1e2d33
--- /dev/null
+++ b/server/lib/api/subscription.js
@@ -0,0 +1,206 @@
+/* jshint node: true */
+
+var _ = require('lodash'),
+ util = require('../util'),
+ upload = require('../upload'),
+ config = require('../../../config.json'),
+ User = require('../schemas/User'),
+ Project = require('../schemas/Project'),
+ Layout = require('../schemas/Layout'),
+ Plan = require('../schemas/Plan');
+ Subscription = require('../schemas/Subscription');
+// Recurly = require('node-recurly'),
+// recurly = new Recurly(require('../webhook/recurly-config'));
+
+var plan_levels = {
+ free: 0,
+ basic: 1,
+ pro: 2,
+ custom: 3,
+}
+
+var subscription = module.exports = {
+ middleware: {
+ ensureSubscription: function(req, res, next){
+ Subscription.findOne({ user_id: req.user._id }, function(err, data){
+ if (err) { return next() }
+ req.subscription = data
+ next()
+ })
+ },
+ ensurePlans: function(req, res, next){
+ Plan.find({}).sort({ 'level': 1 }).exec(function (err, plans) {
+ res.locals.plans = (plans || [])
+ next()
+ })
+ },
+ },
+
+ // synchronise an account with recurly..
+ // useful when testing locally (where webhooks cannot be received)
+ // parses the XML from the subscription API into something usable
+ sync: function(req, res){
+ var subscriber = req.subscription || new Subscription ()
+ var user = req.user
+ recurly.subscriptions.listByAccount(req.user._id, function(recurlyRes){
+ var data = recurlyRes.data
+ if (recurlyRes.description !== 200) {
+ res.json({ error: "no account" })
+ return
+ }
+ var subscriptions = data.subscriptions.subscription.length ? data.subscriptions.subscription : [data.subscriptions.subscription]
+ var is_active = subscriptions.some(function(subscription_data){
+ if (subscription_data.state == "active") {
+ set_active(subscription_data)
+ return true
+ }
+ return false
+ })
+ if (! is_active) {
+ set_cancelled()
+ }
+ })
+ function set_cancelled(){
+ user.plan_type = "free"
+ user.plan_level = plan_levels["free"]
+
+ return subscriber.remove(function(){
+ user.save(function(){
+ res.json({ error: "account cancelled" })
+ })
+ })
+ }
+ function set_active(data){
+ var plan = data.plan.plan_code.split("-")
+ var plan_type = plan[0]
+ var plan_period = plan[1]
+
+ user.plan_type = plan_type
+ user.plan_level = plan_levels[plan_type]
+
+ subscriber.uuid = data.uuid
+ subscriber.user_id = user._id
+ subscriber.plan_type = plan_type
+ subscriber.plan_period = plan_period
+ subscriber.plan_level = plan_levels[plan_type]
+
+ var add_ons = data.subscription_add_ons.subscription_add_on
+ if (add_ons) {
+ if (add_ons.add_on_code) {
+ add_ons = [ add_ons ]
+ }
+ // TODO: handle multiple add-ons.. presumably this will work
+ add_ons.forEach(function(add_on){
+ var add_on_type = add_on.add_on_code.split("-")[1]
+ if (add_on_type == "basic") {
+ subscriber.basic_layouts = parseInt( add_on.quantity._ )
+ }
+ if (add_on_type == "pro") {
+ subscriber.pro_layouts = parseInt( add_on.quantity._ )
+ }
+ })
+ }
+ else {
+ subscriber.basic_layouts = 0
+ subscriber.pro_layouts = 0
+ }
+ subscriber.save(function(){
+ user.save(function(){
+ res.json({
+ subscription: subscriber,
+ plans: res.locals.plans
+ })
+ })
+ })
+ }
+ },
+
+ show: function(req, res){
+ if (req.subscription) {
+ res.json({
+ subscription: req.subscription,
+ plans: res.locals.plans
+ })
+ }
+ else {
+ res.json({
+ error: "no subscription",
+ plans: res.locals.plans,
+ })
+ }
+ },
+
+ update: function(req, res){
+ if (! req.subscription ) {
+ return res.json({ error: "no subscription" })
+ }
+ if (! (req.body.plan_type in plan_levels)) {
+ return res.json({ error: "bad input" })
+ }
+ var subscriber = req.subscription
+ var user = req.user
+
+ var plan_type = req.body.plan_type
+ var basic_layouts = Math.max(0, parseInt(req.body.basic_layouts || 0, 10))
+ var pro_layouts = Math.max(0, parseInt(req.body.pro_layouts || 0, 10))
+ if (plan_type != "pro") { pro_layouts = 0 }
+
+ if (plan_type == subscription.plan_type
+ && basic_layouts == subscriber.basic_layouts
+ && pro_layouts == subscriber.pro_layouts) {
+ return res.json(subscriber)
+ }
+
+ var data = { subscription_add_ons: [] }
+ data.plan_code = plan_type + "-monthly"
+
+ if (plan_levels[plan_type] > 0 && basic_layouts > 0) {
+ data.subscription_add_ons.push({ add_on_code: "extra-basic-layout", quantity: basic_layouts })
+ }
+
+ if (plan_type == "pro" && pro_layouts > 0) {
+ data.subscription_add_ons.push({ add_on_code: "extra-pro-layout", quantity: pro_layouts })
+ }
+
+ // data.plan_code
+ // data.subscription_add_ons = []
+ // add_on.add_on_code
+ // add_on.quantity
+ console.log(data)
+ recurly.subscriptions.update(subscriber.uuid, data, function(err, data){
+ console.log("got response from RECURLY ...")
+ if (err) {
+ console.log("error updating recurly subscription", err)
+ return res.json({ error: err })
+ }
+ subscriber.plan_type = plan_type
+ subscriber.basic_layouts = basic_layouts
+ subscriber.pro_layouts = pro_layouts
+ subscriber.save(function(){
+ user.plan_level = plan_levels[plan_type]
+ user.plan_type = plan_type
+ user.save(function(){
+ return res.json(subscriber)
+ })
+ })
+ })
+ },
+
+ destroy: function(req, res){
+ if (! req.subscription ) {
+ return res.json({ error: "no subscription" })
+ }
+ var subscriber = req.subscription
+
+ recurly.subscriptions.terminate(subscriber.uuid, "partial", function(err, data){
+ subscriber.remove(function(){
+ req.user.plan_code = 0
+ req.user.plan_type = "free"
+ req.user.save(function(){
+ res.json({ status: "OK" })
+ })
+ })
+ })
+ },
+
+};
diff --git a/server/lib/auth/index.js b/server/lib/auth/index.js
index a9a2400..46bff21 100644
--- a/server/lib/auth/index.js
+++ b/server/lib/auth/index.js
@@ -39,7 +39,14 @@ var auth = {
auth.mail.init()
},
-
+ initBasicAuth: function(app){
+ if (config.basicAuth) {
+ app.use(express.basicAuth(function(user, pass) {
+ return user === config.basicAuth.user &&
+ pass === config.basicAuth.pass
+ }))
+ }
+ },
initSockets: function (io, SessionStore) {
io.set('authorization', passportSocketIo.authorize({
cookieParser: express.cookieParser,
@@ -135,12 +142,12 @@ var auth = {
deserializeUser: function (id, done) {
try {
var _id = mongoose.Types.ObjectId(id)
- User.findOne({ _id: _id }, "_id displayName username photo isStaff", function (err, user) {
+ User.findOne({ _id: _id }, "_id displayName username photo isStaff plan_level", function (err, user) {
done(err, user);
});
}
catch (e) {
- User.findOne({ twitter_id: id }, "_id displayName username photo isStaff", function (err, user) {
+ User.findOne({ twitter_id: id }, "_id displayName username photo isStaff plan_level", function (err, user) {
done(err, user);
});
}
@@ -240,7 +247,7 @@ var auth = {
facebookUrl: profile.username ? "https://facebook.com/" + profile.username : ""
};
- User.findOne({twitter_id: profile.id}, function(err, data){
+ User.findOne({facebook_id: profile.id}, function(err, data){
if (! err && data) {
return done(err, data);
}
diff --git a/server/lib/auth/mail.js b/server/lib/auth/mail.js
index eac4007..990b53f 100644
--- a/server/lib/auth/mail.js
+++ b/server/lib/auth/mail.js
@@ -6,7 +6,7 @@ var email = require("emailjs"),
var mail = {
- from: 'VValls <info@vvalls.com>',
+ from: 'VValls <hello@vvalls.com>',
templates: {},
init: function(){
diff --git a/server/lib/middleware.js b/server/lib/middleware.js
index 4848ab0..0a0a9ce 100644
--- a/server/lib/middleware.js
+++ b/server/lib/middleware.js
@@ -6,11 +6,16 @@ var passport = require('passport'),
config = require('../../config.json'),
User = require('./schemas/User'),
Collaborator = require('./schemas/Collaborator'),
- Project = require('./schemas/Project');
+ Project = require('./schemas/Project'),
+ Layout = require('./schemas/Layout'),
+ Blueprint = require('./schemas/Blueprint'),
+ Plan = require('./schemas/Plan');
var middleware = {
+ plans: [],
+
enableCORS: function (req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
// TODO Check https vs. http
@@ -46,7 +51,7 @@ var middleware = {
},
ensureLocals: function (req, res, next) {
- res.locals.token = req.csrfToken();
+ res.locals.token = req.csrfToken()
res.locals.logged_in = req.isAuthenticated()
res.locals.user = req.user || { _id: undefined }
res.locals.config = config
@@ -56,10 +61,31 @@ var middleware = {
res.locals.ogUrl = "http://vvalls.com/"
res.locals.ogDescription = "3D gallery space, fully customizable"
res.locals.ogAuthor = "VValls"
+ res.locals.plans = middleware.plans
res.locals.opt = {}
next()
},
-
+
+ ensureUserProjectsCount: function(req, res, next){
+ var counts = { stock: 0, basic: 0, pro: 0 }
+ res.locals.projectCounts = counts
+ Project.count({ user_id: req.user._id }, function(err, count){
+ res.locals.projectCount = count || 0
+ next()
+ })
+ },
+
+ ensureUserLayoutsCount: function(req, res, next){
+ var counts = { basic: 0, pro: 0 }
+ res.locals.layoutCounts = counts
+ if (req.user.plan_level == 0) { return next() }
+
+ Layout.count({ user_id: req.user._id }, function(err, count){
+ res.locals.layoutCount = count || 0
+ next()
+ })
+ },
+
ensureProject: function (req, res, next) {
if (req.params.slug) {
Project.findOne({ slug: req.params.slug }, function(err, project){
@@ -75,13 +101,57 @@ var middleware = {
}
next()
})
- }
+ }
else {
req.project = null
next()
}
},
+ ensureLayout: function (req, res, next) {
+ if (req.params.slug) {
+ Layout.findOne({ slug: req.params.slug }, function(err, layout){
+ if (err) {
+ console.error(err)
+ req.layout = null
+ }
+ else if (! layout) {
+ req.layout = null
+ }
+ else {
+ req.layout = layout
+ }
+ next()
+ })
+ }
+ else {
+ req.layout = null
+ next()
+ }
+ },
+
+ ensureBlueprint: function (req, res, next) {
+ if (req.params.slug) {
+ Blueprint.findOne({ slug: req.params.slug }, function(err, blueprint){
+ if (err) {
+ console.error(err)
+ req.blueprint = null
+ }
+ else if (! blueprint) {
+ req.blueprint = null
+ }
+ else {
+ req.blueprint = blueprint
+ }
+ next()
+ })
+ }
+ else {
+ req.blueprint = null
+ next()
+ }
+ },
+
ensureIsCollaborator: function(req, res, next) {
req.isCollaborator = false
req.isOwner = false
@@ -106,6 +176,12 @@ var middleware = {
})
}
},
+
+ updatePlans: function(){
+ Plan.find({}).sort({ 'level': -1 }).exec(function (err, plans) {
+ middleware.plans = plans.map(function(plan){ return plan.toObject() })
+ })
+ },
}
diff --git a/server/lib/schemas/Blueprint.js b/server/lib/schemas/Blueprint.js
new file mode 100644
index 0000000..3c3b0cc
--- /dev/null
+++ b/server/lib/schemas/Blueprint.js
@@ -0,0 +1,66 @@
+/* jshint node: true */
+
+var mongoose = require('mongoose'),
+ _ = require('lodash'),
+ util = require('../util');
+
+var BlueprintSchema = new mongoose.Schema({
+ type: {
+ type: String,
+ required: true
+ },
+ url: {
+ type: String,
+ required: true,
+ },
+ token: {
+ type: String,
+ default: ""
+ },
+ thumbnail: {
+ type: String,
+ default: ""
+ },
+ width: {
+ type: Number,
+ default: 0
+ },
+ height: {
+ type: Number,
+ default: 0
+ },
+ name: {
+ type: String,
+ default: ""
+ },
+ slug: {
+ type: String,
+// required: true,
+ validate: [function (val){
+ val = util.sanitize(val || this.displayName || "")
+// if (! val.length) return false
+ return true
+ },"{PATH} name is required"]
+ },
+ description: {
+ type: String,
+ default: ""
+ },
+ tag: { type: String, default: "" },
+ scale: { type: Number, default: 1.0 },
+
+ widthDimension: { type: Number },
+ heightDimension: { type: Number },
+ wallHeight: { type: Number },
+ units: { type: String },
+ line: { type: String },
+
+ shapes: [mongoose.Schema.Types.Mixed],
+ startPosition: mongoose.Schema.Types.Mixed,
+
+ user_id: { type: mongoose.Schema.ObjectId, index: true },
+ created_at: { type: Date },
+});
+
+module.exports = exports = mongoose.model('blueprint', BlueprintSchema)
+exports.schema = BlueprintSchema;
diff --git a/server/lib/schemas/Layout.js b/server/lib/schemas/Layout.js
index e3f2616..e15e188 100644
--- a/server/lib/schemas/Layout.js
+++ b/server/lib/schemas/Layout.js
@@ -23,9 +23,12 @@ var LayoutSchema = new mongoose.Schema({
photo: {
type: String,
},
+ media: mongoose.Schema.Types.Mixed,
rooms: [mongoose.Schema.Types.Mixed],
startPosition: mongoose.Schema.Types.Mixed,
viewHeight: { type: Number },
+ is_stock: { type: Boolean, default: false },
+ is_pro: { type: Boolean, default: false },
user_id: { type: mongoose.Schema.ObjectId, index: true },
created_at: { type: Date },
updated_at: { type: Date },
diff --git a/server/lib/schemas/Media.js b/server/lib/schemas/Media.js
index 1de354d..f37fb12 100644
--- a/server/lib/schemas/Media.js
+++ b/server/lib/schemas/Media.js
@@ -37,11 +37,12 @@ var MediaSchema = new mongoose.Schema({
type: String,
default: ""
},
- autoplay: { type: Boolean, default: false },
- loop: { type: Boolean, default: false },
- mute: { type: Boolean, default: true },
+ autoplay: { type: Boolean, default: true },
+ loop: { type: Boolean, default: true },
+ mute: { type: Boolean, default: false },
keyframe: { type: Number, default: 0.0 },
tag: { type: String, default: "" },
+ scale: { type: Number, default: 1.0 },
widthDimension: { type: Number },
heightDimension: { type: Number },
diff --git a/server/lib/schemas/Plan.js b/server/lib/schemas/Plan.js
new file mode 100644
index 0000000..388ce69
--- /dev/null
+++ b/server/lib/schemas/Plan.js
@@ -0,0 +1,44 @@
+/* jshint node: true */
+
+var mongoose = require('mongoose'),
+ _ = require('lodash'),
+ crypto = require('crypto'),
+ config = require('../../../config.json'),
+ util = require('../util');
+
+var PlanSchema = new mongoose.Schema({
+ name: { type: String },
+ slug: { type: String },
+
+ level: { type: Number },
+
+ monthly_price: { type: Number },
+ yearly_price: { type: Number },
+
+ basic_layout_monthly_price: { type: Number },
+ basic_layout_yearly_price: { type: Number },
+
+ pro_layout_monthly_price: { type: Number },
+ pro_layout_yearly_price: { type: Number },
+
+ basic_layout_limit: { type: Number },
+ pro_layout_limit: { type: Number },
+
+ stock_project_limit: { type: Number },
+ basic_project_limit: { type: Number },
+ pro_project_limit: { type: Number },
+
+ permissions: {
+ basic_editor: { type: Boolean, default: false },
+ pro_editor: { type: Boolean, default: false },
+ sculpture: { type: Boolean, default: false },
+ collaborators: { type: Boolean, default: false },
+ no_logo: { type: Boolean, default: false },
+ },
+
+ created_at: { type: Date, default: Date.now },
+ updated_at: { type: Date, default: Date.now },
+})
+
+module.exports = exports = mongoose.model('plan', PlanSchema);
+exports.schema = PlanSchema;
diff --git a/server/lib/schemas/Project.js b/server/lib/schemas/Project.js
index a923d85..687555d 100644
--- a/server/lib/schemas/Project.js
+++ b/server/lib/schemas/Project.js
@@ -28,16 +28,20 @@ var ProjectSchema = new mongoose.Schema({
type: String,
},
rooms: [mongoose.Schema.Types.Mixed],
+ shapes: [mongoose.Schema.Types.Mixed],
walls: [mongoose.Schema.Types.Mixed],
media: [mongoose.Schema.Types.Mixed],
+ sculpture: [mongoose.Schema.Types.Mixed],
colors: mongoose.Schema.Types.Mixed,
startPosition: mongoose.Schema.Types.Mixed,
lastPosition: mongoose.Schema.Types.Mixed,
viewHeight: { type: Number },
+ units: { type: String, default: "ft" },
user_id: { type: mongoose.Schema.ObjectId, index: true },
created_at: { type: Date },
updated_at: { type: Date },
featured: { type: Boolean, default: false },
+ layout_type: { type: Number, default: 0 },
});
module.exports = exports = mongoose.model('project', ProjectSchema);
diff --git a/server/lib/schemas/Subscription.js b/server/lib/schemas/Subscription.js
new file mode 100644
index 0000000..bf43e8b
--- /dev/null
+++ b/server/lib/schemas/Subscription.js
@@ -0,0 +1,31 @@
+/* jshint node: true */
+
+var mongoose = require('mongoose'),
+ _ = require('lodash'),
+ crypto = require('crypto'),
+ config = require('../../../config.json'),
+ util = require('../util');
+
+var SubscriptionSchema = new mongoose.Schema({
+ user_id: { type: mongoose.Schema.ObjectId, index: true },
+
+ plan_code: { type: String, default: "" },
+ plan_type: { type: String, default: "free" },
+ plan_period: { type: String, default: "monthly" },
+
+ uuid: { type: String },
+ basic_layouts: { type: Number, default: 0 },
+ pro_layouts: { type: Number, default: 0 },
+
+ history: [{
+ action: { type: String },
+ data: { type: String },
+ created_at: { type: Date, default: Date.now },
+ }],
+
+ created_at: { type: Date, default: Date.now },
+ updated_at: { type: Date, default: Date.now },
+})
+
+module.exports = exports = mongoose.model('subscription', SubscriptionSchema);
+exports.schema = SubscriptionSchema;
diff --git a/server/lib/schemas/User.js b/server/lib/schemas/User.js
index 180a140..829b360 100644
--- a/server/lib/schemas/User.js
+++ b/server/lib/schemas/User.js
@@ -54,7 +54,12 @@ var UserSchema = new mongoose.Schema({
type: String,
default: "",
},
-
+
+ plan_code: { type: String, default: "" },
+ plan_level: { type: Number, default: 0 },
+ plan_type: { type: String, default: "free" },
+ last_charged: { type: Date, default: null },
+
location: { type: String, default: "" },
photo: { type: String, default: "" },
bio: { type: String, default: "" },
@@ -62,6 +67,8 @@ var UserSchema = new mongoose.Schema({
twitterName: { type: String, default: "" },
facebookUrl: { type: String, default: "" },
isStaff: { type: Boolean, default: false },
+ isArtist: { type: Boolean, default: false },
+ subscription_id: { type: mongoose.Schema.ObjectId },
created_at: { type: Date },
updated_at: { type: Date },
last_seen: { type: Date },
diff --git a/server/lib/upload.js b/server/lib/upload.js
index f6e22da..ebb1249 100644
--- a/server/lib/upload.js
+++ b/server/lib/upload.js
@@ -5,9 +5,9 @@ var config = require('../../config.json'),
moment = require('moment');
var s3 = module.exports.s3 = knox.createClient({
- key: process.env.OKFOCUS_S3_KEY,
- secret: process.env.OKFOCUS_S3_SECRET,
- bucket: 'vvalls'
+ key: process.env.S3_KEY,
+ secret: process.env.S3_SECRET,
+ bucket: process.env.S3_BUCKET,
});
var acceptableuploadTypes = {
@@ -32,7 +32,7 @@ module.exports.put = function (key, file, opt) {
.substr(-128)
+ "." + extension;
- var remote_path = "/images/" + key + "/" + ts + "/" + filename
+ var remote_path = "/vvalls/images/" + key + "/" + ts + "/" + filename
if (! extension) {
err = "unacceptable filetype"
@@ -59,7 +59,8 @@ module.exports.put = function (key, file, opt) {
'x-amz-acl': 'public-read'
}, function(err, s3res) {
if (err || s3res.statusCode !== 200) {
- console.error(err);
+ console.log(s3res.statusCode)
+ console.error('s3 error:', err);
if (s3res && s3res.resume) {
s3res.resume()
}
diff --git a/server/lib/util.js b/server/lib/util.js
index e3fd1ed..86fbdcc 100644
--- a/server/lib/util.js
+++ b/server/lib/util.js
@@ -5,6 +5,7 @@ var whitespace = new RegExp('\\s', 'g')
var whitespaceHead = /^\s+/
var whitespaceTail = /\s+$/
var nonAlphanumerics = new RegExp('[^-_a-zA-Z0-9]', 'g')
+var nonNumerics = new RegExp('[^0-9]', 'g')
var consecutiveDashes = new RegExp("-+", 'g')
var entities = new RegExp("[<>&]", 'g')
@@ -19,6 +20,9 @@ util.slugify = function (s){
util.sanitize = function (s){
return (s || "").replace(entities, "")
}
+util.sanitizeNumber = function (s){
+ return (s || "").replace(nonNumerics, "")
+}
util.escape = function (s){
return (s || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
}
diff --git a/server/lib/views/index.js b/server/lib/views/index.js
index 8c3e63d..5d82979 100644
--- a/server/lib/views/index.js
+++ b/server/lib/views/index.js
@@ -4,6 +4,7 @@ var User = require('../schemas/User'),
Project = require('../schemas/Project'),
Documentation = require('../schemas/Documentation'),
Collaborator = require('../schemas/Collaborator'),
+ Plan = require('../schemas/Plan'),
config = require('../../../config'),
marked = require('marked'),
util = require('../util'),
@@ -83,33 +84,42 @@ var views = module.exports = {
res.render('builder')
},
+ blueprint: function (req, res) {
+ res.render('blueprint')
+ },
+
modal: function (req, res) {
res.render('modal');
},
home: function (req, res) {
- // while in development, blank homepage if not logged in
-/*
- if (! req.user) {
- res.send("<html></html>")
- return
- }
-*/
- views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){
- res.render('home', {
- projects: projects || []
+ views_middleware.ensurePlans(req, res, function(err){
+ views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){
+ res.render('home', {
+ projects: projects || [],
+ })
})
})
},
demoHome: function (req, res) {
- views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){
- res.render('home', {
- projects: projects || []
+ views_middleware.ensurePlans(req, res, function(err){
+ views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){
+ res.render('home', {
+ projects: projects || [],
+ })
})
})
},
+ partials: {
+ plans: function (req, res){
+ views_middleware.ensurePlans(req, res, function(){
+ res.render('about/_plans', { logged_in: res.locals.logged_in || false })
+ })
+ },
+ },
+
docs: function (req, res){
var name = req.params.name || "about"
@@ -117,10 +127,17 @@ var views = module.exports = {
res.render('about/' + name)
return
}
- if (name == "about" || name == "index") {
- res.render('about/' + name)
+ if (name == "brochure" || name == "plans") {
+ // TODO: fetch plans
+ views_middleware.ensurePlans(req, res, function(){
+ res.render('about/' + name)
+ })
return
}
+ if (name == "about" || name == "index" || name == "terms" || name == "privacy") {
+ res.render('about/' + name)
+ return
+ }
if (name === "new") {
res.render('docs', {
@@ -225,6 +242,19 @@ var views = module.exports = {
}
var views_middleware = {
+ ensurePlans: function(req, res, next){
+ Plan.find(function (err, plans) {
+ res.locals.plans = {}
+ plans.forEach(function(plan){
+ res.locals.plans[ plan.slug ] = plan
+ "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price pro_layout_monthly_price pro_layout_yearly_price".split(" ").forEach(function(key){
+ plan[key] = (plan[key]/100).toFixed(2)+""
+ })
+ })
+ next()
+ })
+ },
+
fetchProjects: function (criteria, limit, offset, next) {
limit = limit || 7
offset = offset || 0
diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js
deleted file mode 100644
index 49f492b..0000000
--- a/server/lib/views/staff.js
+++ /dev/null
@@ -1,545 +0,0 @@
-/* jshint node: true */
-
-var User = require('../schemas/User'),
- Project = require('../schemas/Project'),
- Media = require('../schemas/Media'),
- Collaborator = require('../schemas/Collaborator'),
- config = require('../../../config'),
- middleware = require('../middleware'),
- util = require('../util'),
- _ = require('lodash'),
- moment = require('moment');
-
-
-var staff = module.exports = {
-
- fields: {
- user: "_id username displayName photo created_at updated_at last_seen created_ip last_ip",
- project: "_id name slug user_id privacy created_at updated_at",
- },
-
- defaults: {
- user: {
- _id: "", username: "", displayName: "",
- created_at: "", updated_at: "", created_ip: "", last_ip: "",
- },
- },
-
- middleware: {
-
- ensureUsers: function(req, res, next){
- var paginationInfo = res.locals.pagination = {}
- var criteria = req.criteria || {}
- var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
- var offset = paginationInfo.offset = Number(req.query.offset) || 0
- var sort
- paginationInfo.sort = req.query.sort
- paginationInfo.sortOptions = ["date", "last_seen", "username"]
- switch (req.query.sort) {
- case 'date':
- sort = {'created_at': -1}
- break
- case 'last_seen':
- sort = {'last_seen': -1}
- break
- case 'username':
- default:
- sort = {'username': 1}
- paginationInfo.sort = "username"
- break
- }
- User.find(criteria)
- .select(staff.fields.user)
- .sort(sort)
- .skip(offset)
- .limit(limit)
- .exec(function (err, users) {
- res.locals.users = users.map(staff.helpers.user)
- next()
- })
- },
-
- ensureRecentUsers: function(req, res, next){
- var dreq = { query: { sort: 'last_seen', limit: 20, offset: 0 } }
- staff.middleware.ensureUsers(dreq, res, next)
- },
-
- ensureProjects: function(req, res, next){
- var paginationInfo = res.locals.pagination = {}
- var criteria = req.criteria || {}
- var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
- var offset = paginationInfo.offset = Number(req.query.offset) || 0
- var sort
- paginationInfo.sort = req.query.sort
- paginationInfo.sortOptions = ["date", "name"]
- switch (req.query.sort) {
- default:
- case 'date':
- sort = {'updated_at': -1}
- break
- case 'name':
- paginationInfo.sort = "name"
- sort = {'slug': 1}
- break
- }
- Project.find(criteria)
- .select(staff.fields.project)
- .sort(sort)
- .skip(offset)
- .limit(limit)
- .exec(function (err, projects) {
- res.locals.projects = projects.map(staff.helpers.project)
- next()
- })
- },
-
- ensureMedia: function(req, res, next){
- var paginationInfo = res.locals.pagination = {}
- var criteria = req.criteria || {}
- var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
- var offset = paginationInfo.offset = Number(req.query.offset) || 0
- var sort
- paginationInfo.sort = req.query.sort
- paginationInfo.sortOptions = ["date"]
- switch (req.query.sort) {
- default:
- case 'date':
- paginationInfo.sort = "date"
- sort = {'created_at': -1}
- break
- }
- Media.find(criteria)
- // .select(staff.fields.media)
- .sort(sort)
- .skip(offset)
- .limit(limit)
- .exec(function (err, media) {
- res.locals.media = media.map(staff.helpers.media)
- next()
- })
- },
-
- ensureRecentProjects: function(req, res, next){
- var dreq = { params: { sort: 'created_at', limit: 20, offset: 0 } }
- staff.middleware.ensureProjects(dreq, res, next)
- },
-
- ensureProjectsUsers: function(req, res, next){
- if (! res.locals.projects || ! res.locals.projects.length) { return next() }
- staff.middleware.ensureObjectsUsers(res.locals.projects, next)
- },
-
- ensureMediaUsers: function(req, res, next){
- if (! res.locals.media || ! res.locals.media.length) { return next() }
- staff.middleware.ensureObjectsUsers(res.locals.media, next)
- },
-
- ensureMediaUser: function(req, res, next){
- if (! res.locals.media) { return next() }
- staff.middleware.ensureObjectsUsers([ res.locals.media ], function(){
- res.locals.mediaUser = res.locals.media.User
- next()
- })
- },
-
- ensureObjectsUsers: function(objects, next){
- if (! objects) { return next () }
- var dedupe = {}, user_ids
- objects.forEach(function(obj){
- dedupe[ obj.user_id ] = dedupe[ obj.user_id ] || []
- dedupe[ obj.user_id ].push(obj)
- })
- user_ids = _.keys(dedupe)
- User.find({ _id: { $in: user_ids } })
- .select(staff.fields.user)
- .exec(function (err, users) {
- if (! users) { return next () }
- users.forEach(function(user){
- dedupe[user._id].forEach(function(obj){
- obj.user = user
- })
- })
- next()
- })
- },
-
- ensureProfile: function(req, res, next){
- var username = req.params.username
- if (username) {
- User.findOne({ username: username }, function (err, user) {
- if (user) {
- res.locals.profile = req.method == "GET" ? staff.helpers.user(user) : user
- }
- else {
- res.locals.profile = null
- }
- next()
- })
- }
- else {
- res.locals.profile = null
- next()
- }
- },
-
- ensureSingleMedia: function(req, res, next){
- var id = req.params.id
- if (id) {
- Media.findOne({ _id: id }, function (err, media) {
- if (media) {
- res.locals.media = req.method == "GET" ? staff.helpers.media(media) : media
- }
- else {
- res.locals.media = null
- }
- next()
- })
- }
- else {
- res.locals.media = null
- next()
- }
- },
-
- ensureUsersCount: function(req, res, next){
- User.count({}, function(err, count){
- res.locals.userCount = count || 0
- next()
- })
- },
-
- ensureProjectsCount: function(req, res, next){
- Project.count({}, function(err, count){
- res.locals.projectCount = count || 0
- next()
- })
- },
-
- ensureMediaCount: function(req, res, next){
- Media.count({}, function(err, count){
- res.locals.mediaCount = count || 0
- next()
- })
- },
-
- ensureProfileProjectCount: function(req, res, next){
- if (! res.locals.profile) { return next() }
- Project.count({ user_id: res.locals.profile._id}, function(err, count){
- res.locals.profile.projectCount = count || 0
- next()
- })
- },
-
- ensureProfileMediaCount: function(req, res, next){
- if (! res.locals.profile) { return next() }
- Media.count({ user_id: res.locals.profile._id}, function(err, count){
- res.locals.profile.mediaCount = count || 0
- next()
- })
- },
-
- ensureProfileProjects: function(req, res, next){
- if (! res.locals.profile) { return next() }
- Project.find({ user_id: res.locals.profile._id }, staff.fields.project, function(err, projects){
- res.locals.projects = projects.map(staff.helpers.project)
- next()
- })
- },
-
- ensureProfileMedia: function(req, res, next){
- if (! res.locals.profile) { return next() }
- req.criteria = { user_id: res.locals.profile._id }
- staff.middleware.ensureMedia(req, res, next)
- },
-
- ensureProject: function(req, res, next){
- res.locals.project = req.project
- next()
- },
-
- ensureProjectUser: function(req, res, next){
- if (! res.locals.project) { return next() }
- User.findOne({ _id: res.locals.project.user_id }, staff.fields.user, function(err, user){
- res.locals.projectUser = staff.helpers.user(user) || staff.defaults.user
- next()
- })
- },
-
- ensureProjectCollaborators: function(req, res, next){
- if (! res.locals.project) {
- res.locals.collaborators = []
- return next()
- }
- Collaborator.find({ project_id: res.locals.project._id}, function(err, collaborators){
- res.locals.collaborators = collaborators || []
- next()
- })
- },
- },
-
- helpers: {
- user: function(user){
- user = user.toObject()
- user.last_seen = moment( user.last_seen || user.updated_at || user.created_at ).fromNow()
- user.created_ip = util.num2ip( user.created_ip )
- user.last_ip = util.num2ip( user.last_ip )
- return user
- },
-
- project: function(project){
- project = project.toObject()
- project.date = moment( project.updated_at || project.created_at ).format("M/DD/YYYY hh:mm a")
- project.user = {}
- return project
- },
-
- media: function(media){
- media = media.toObject()
- media.date = moment( media.updated_at || media.created_at ).format("M/DD/YYYY hh:mm a")
- media.user = {}
- media.shortUrl = media.url.replace(/^http.:\/\//,"")
- return media
- }
- },
-
- route: function(app){
- app.get('/staff',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureRecentUsers,
- staff.middleware.ensureUsersCount,
- staff.middleware.ensureProjectsCount,
- staff.middleware.ensureMediaCount,
-
- staff.index
- );
-
- //
- // users
-
- app.get('/staff/users',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureUsersCount,
- staff.middleware.ensureUsers,
-
- staff.users.index
- );
- app.get('/staff/users/:username',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureProfile,
- staff.middleware.ensureProfileProjectCount,
- staff.middleware.ensureProfileMediaCount,
- staff.middleware.ensureProfileProjects,
-
- staff.users.show
- );
- app.get('/staff/users/:username/media',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureProfile,
- staff.middleware.ensureProfileMedia,
- staff.middleware.ensureProfileMediaCount,
-
- staff.users.media
- );
- app.put('/staff/users/:username/bless',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureProfile,
-
- staff.users.bless
- );
-
- if (app.get('env') === 'development') {
- app.get('/staff/authorize',
- middleware.ensureAuthenticated,
- staff.users.blessSelf
- );
- }
-
- //
- // projects
-
- app.get('/staff/projects',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureProjectsCount,
-
- staff.middleware.ensureProjects,
- staff.middleware.ensureProjectsUsers,
-
- staff.projects.index
- );
- app.get('/staff/projects/:slug',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- middleware.ensureProject,
- staff.middleware.ensureProject,
- staff.middleware.ensureProjectUser,
- staff.middleware.ensureProjectCollaborators,
-
- staff.projects.show
- );
- app.put('/staff/projects/:slug/feature',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- middleware.ensureProject,
- staff.middleware.ensureProject,
-
- staff.projects.feature
- );
-
- //
- // media
-
- app.get('/staff/media',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureMediaCount,
-
- staff.middleware.ensureMedia,
- staff.middleware.ensureMediaUsers,
-
- staff.media.index
- );
- app.get('/staff/media/:id',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureSingleMedia,
- staff.middleware.ensureMediaUser,
-
- staff.media.show
- );
-
- },
-
- paginate: function(req, res){
- var info = res.locals.pagination
- info.query = "sort=" + info.sort + "&limit=" + info.limit
- info.first_page = 0
- info.last_page = Math.max(0, info.max - info.limit)
- info.sortOptions = info.sortOptions
- if (info.offset > 0) {
- info.prev_page = Math.max(0, info.offset - info.limit)
- }
- else {
- info.prev_page = -1
- }
- if (info.count == info.limit && info.offset + info.limit < info.max) {
- info.next_page = info.offset + info.limit
- }
- else {
- info.next_page = -1
- }
- },
-
- index: function(req, res){
- res.render('staff/index')
- },
-
- // /staff/users/
- // /staff/users/:username
- users: {
- index: function(req, res){
- res.locals.pagination.count = res.locals.users.length
- res.locals.pagination.max = res.locals.userCount
- staff.paginate(req, res)
- res.render('staff/users/index')
- },
- show: function(req, res){
- if (res.locals.profile) {
- res.render('staff/users/show', {
- profileJSON: util.escape( JSON.stringify( res.locals.profile ) )
- })
- }
- else {
- res.render('staff/users/show_404')
- }
- },
- media: function(req, res){
- if (res.locals.profile) {
- res.locals.pagination.count = res.locals.media.length
- res.locals.pagination.max = res.locals.profile.mediaCount
- staff.paginate(req, res)
- res.render('staff/users/media')
- }
- else {
- res.render('staff/users/show_404')
- }
- },
- blessSelf: function(req, res){
- req.user.isStaff = true
- req.user.save(function(err, user){
- res.json({ state: user.isStaff })
- })
- },
- bless: function(req, res){
- res.locals.profile.isStaff = req.body.state == "true"
- res.locals.profile.save(function(err, user){
- res.json({ state: user.isStaff })
- })
- },
- },
-
- // /staff/projects/
- // /staff/projects/:name
- projects: {
- index: function(req, res){
- res.locals.pagination.count = res.locals.projects.length
- res.locals.pagination.max = res.locals.projectCount
- staff.paginate(req, res)
- res.render('staff/projects/index')
- },
- show: function(req, res){
- if (res.locals.project) {
- res.render('staff/projects/show', {
- projectJSON: util.escape( JSON.stringify( res.locals.project ) ),
- projectUserJSON: util.escape( JSON.stringify( res.locals.projectUser ) ),
- collaboratorsJSON: util.escape( JSON.stringify( res.locals.collaborators ) ),
- })
- }
- else {
- res.render('staff/projects/show_404')
- }
- },
- feature: function(req, res){
- res.locals.project.featured = req.body.state == "true"
- res.locals.project.save(function(err, project){
- res.json({ state: project.featured })
- })
- },
- },
-
- media: {
- index: function(req, res){
- res.locals.pagination.count = res.locals.media.length
- res.locals.pagination.max = res.locals.mediaCount
- staff.paginate(req, res)
- res.render('staff/media/index')
- },
- show: function(req, res){
- if (res.locals.media) {
- res.render('staff/media/show', {
- mediaJSON: util.escape( JSON.stringify( res.locals.media ) ),
- mediaUserJSON: util.escape( JSON.stringify( res.locals.mediaUser ) ),
- })
- }
- else {
- res.render('staff/media/show_404')
- }
- },
- }
-
-}
diff --git a/server/lib/views/staff/defaults.js b/server/lib/views/staff/defaults.js
new file mode 100644
index 0000000..4d86c41
--- /dev/null
+++ b/server/lib/views/staff/defaults.js
@@ -0,0 +1,6 @@
+module.exports = {
+ user: {
+ _id: "", username: "", displayName: "",
+ created_at: "", updated_at: "", created_ip: "", last_ip: "",
+ },
+}
diff --git a/server/lib/views/staff/fields.js b/server/lib/views/staff/fields.js
new file mode 100644
index 0000000..84c1efa
--- /dev/null
+++ b/server/lib/views/staff/fields.js
@@ -0,0 +1,10 @@
+module.exports = {
+ user: "_id username displayName photo created_at updated_at last_seen created_ip last_ip",
+ project: "_id name slug user_id privacy layout_type created_at updated_at",
+ layout: "_id name slug user_id layout_type is_stock created_at updated_at",
+ blueprint: "_id name slug user_id created_at updated_at",
+ plans: "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price " +
+ "pro_layout_monthly_price pro_layout_yearly_price " +
+ "basic_layout_limit pro_layout_limit stock_project_limit basic_project_limit pro_project_limit",
+ plans_permissions: "basic_editor pro_editor sculpture collaborators no_logo",
+}
diff --git a/server/lib/views/staff/helpers.js b/server/lib/views/staff/helpers.js
new file mode 100644
index 0000000..ff4065a
--- /dev/null
+++ b/server/lib/views/staff/helpers.js
@@ -0,0 +1,59 @@
+
+var util = require('../../util'),
+ _ = require('lodash'),
+ moment = require('moment');
+
+module.exports = {
+ user: function(user){
+ var last_seen = moment( user.last_seen || user.updated_at || user.created_at )
+ user = user.toObject()
+ user.last_seen = last_seen.format("YYYY/MM/DD HH:MM") + " " + last_seen.fromNow()
+ user.last_charged = user.last_charged && moment( user.last_charged ).format("YYYY/MM/DD HH:MM")
+ user.created_ip = util.num2ip( user.created_ip )
+ user.last_ip = util.num2ip( user.last_ip )
+ return user
+ },
+
+ project: function(project){
+ project = project.toObject()
+ project.date = moment( project.updated_at || project.created_at ).format("M/DD/YYYY hh:mm a")
+ project.user = {}
+ return project
+ },
+
+ layout: function(layout){
+ layout = layout.toObject()
+ layout.date = moment( layout.updated_at || layout.created_at ).format("M/DD/YYYY hh:mm a")
+ layout.user = {}
+ return layout
+ },
+
+ blueprint: function(blueprint){
+ blueprint = blueprint.toObject()
+ blueprint.date = moment( blueprint.updated_at || blueprint.created_at ).format("M/DD/YYYY hh:mm a")
+ blueprint.user = {}
+ return blueprint
+ },
+
+ media: function(media){
+ media = media.toObject()
+ media.date = moment( media.updated_at || media.created_at ).format("M/DD/YYYY hh:mm a")
+ media.user = {}
+ media.shortUrl = media.url.replace(/^http.?:\/\//,"")
+ return media
+ },
+
+ plan: function(plan){
+ plan = plan.toObject()
+ plan.date = moment( plan.updated_at || plan.created_at ).format("M/DD/YYYY hh:mm a")
+ plan.user = {}
+ return plan
+ },
+
+ subscription: function(subscription){
+ subscription = subscription.toObject()
+ subscription.date = moment( subscription.updated_at || subscription.created_at ).format("M/DD/YYYY hh:mm a")
+ subscription.user = {}
+ return subscription
+ },
+}
diff --git a/server/lib/views/staff/index.js b/server/lib/views/staff/index.js
new file mode 100644
index 0000000..49a0384
--- /dev/null
+++ b/server/lib/views/staff/index.js
@@ -0,0 +1,511 @@
+/* jshint node: true */
+
+var User = require('../../schemas/User'),
+ Project = require('../../schemas/Project'),
+ Media = require('../../schemas/Media'),
+ Collaborator = require('../../schemas/Collaborator'),
+ Plan = require('../../schemas/Plan'),
+ Subscription = require('../../schemas/Subscription'),
+ Layout = require('../../schemas/Layout'),
+ Blueprint = require('../../schemas/Blueprint'),
+ config = require('../../../../config'),
+ middleware = require('../../middleware'),
+ util = require('../../util'),
+ _ = require('lodash'),
+ moment = require('moment');
+
+
+var staff = module.exports = {
+
+ fields: require('./fields'),
+ defaults: require('./defaults'),
+ middleware: require('./middleware'),
+ helpers: require('./helpers'),
+
+ route: function(app){
+ app.get('/staff',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureRecentUsers,
+ staff.middleware.ensureUsersCount,
+ staff.middleware.ensureProjectsCount,
+ staff.middleware.ensureMediaCount,
+
+ staff.index
+ );
+
+ //
+ // users
+
+ app.get('/staff/users',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureUsersCount,
+ staff.middleware.ensureUsers,
+
+ staff.users.index
+ );
+ app.get('/staff/users/:username',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProfile,
+ staff.middleware.ensureProfileProjectCount,
+ staff.middleware.ensureProfileMediaCount,
+ staff.middleware.ensureProfileProjects,
+
+ staff.users.show
+ );
+ app.get('/staff/users/:username/media',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProfile,
+ staff.middleware.ensureProfileMedia,
+ staff.middleware.ensureProfileMediaCount,
+
+ staff.users.media
+ );
+ app.put('/staff/users/:username/bless',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProfile,
+
+ staff.users.bless
+ );
+ app.put('/staff/users/:username/artist',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProfile,
+
+ staff.users.make_artist
+ );
+
+ if (app.get('env') === 'development') {
+ app.get('/staff/authorize',
+ middleware.ensureAuthenticated,
+ staff.users.blessSelf
+ );
+ }
+
+ //
+ // projects
+
+ app.get('/staff/projects',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProjectsCount,
+
+ staff.middleware.ensureProjects,
+ staff.middleware.ensureProjectsUsers,
+
+ staff.projects.index
+ );
+ app.get('/staff/projects/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureProject,
+ staff.middleware.ensureProject,
+ staff.middleware.ensureProjectUser,
+ staff.middleware.ensureProjectCollaborators,
+
+ staff.projects.show
+ );
+ app.put('/staff/projects/:slug/feature',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureProject,
+ staff.middleware.ensureProject,
+
+ staff.projects.feature
+ );
+
+ //
+ // layouts
+
+ app.get('/staff/layouts',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureLayoutsCount,
+
+ staff.middleware.ensureLayouts,
+ staff.middleware.ensureLayoutsUsers,
+
+ staff.layouts.index
+ );
+ app.get('/staff/layouts/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureLayout,
+ staff.middleware.ensureLayout,
+ staff.middleware.ensureLayoutUser,
+
+ staff.layouts.show
+ );
+ app.put('/staff/layouts/:slug/stock',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureLayout,
+ staff.middleware.ensureLayout,
+
+ staff.layouts.make_stock
+ );
+
+ //
+ // blueprints
+
+ app.get('/staff/blueprints',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureBlueprintsCount,
+
+ staff.middleware.ensureBlueprints,
+ staff.middleware.ensureBlueprintsUsers,
+
+ staff.blueprints.index
+ );
+ app.get('/staff/blueprints/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureBlueprint,
+ staff.middleware.ensureBlueprint,
+ staff.middleware.ensureBlueprintUser,
+
+ staff.blueprints.show
+ );
+
+ //
+ // media
+
+ app.get('/staff/media',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureMediaCount,
+
+ staff.middleware.ensureMedia,
+ staff.middleware.ensureMediaUsers,
+
+ staff.media.index
+ );
+ app.get('/staff/media/:id',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureSingleMedia,
+ staff.middleware.ensureMediaUser,
+
+ staff.media.show
+ );
+
+ //
+ // plans
+
+ app.get('/staff/plans',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensurePlans,
+
+ staff.plans.index
+ );
+ app.get('/staff/plans/new',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.plans.new
+ );
+ app.post('/staff/plans/new',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.plans.create
+ );
+ app.get('/staff/plans/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensurePlan,
+
+ staff.plans.edit
+ );
+ app.post('/staff/plans/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensurePlan,
+
+ staff.plans.update
+ );
+
+ //
+ // subscriptions
+ app.get('/staff/subscriptions',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureSubscriptions,
+ staff.middleware.ensureSubscriptionsUsers,
+
+ staff.subscriptions.index
+ );
+ app.get('/staff/subscriptions/:id',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureSubscription,
+ staff.middleware.ensureSubscriptionUser,
+
+ staff.subscriptions.show
+ );
+ },
+
+ paginate: function(req, res){
+ var info = res.locals.pagination
+ info.query = "sort=" + info.sort + "&limit=" + info.limit
+ info.first_page = 0
+ info.last_page = Math.max(0, info.max - info.limit)
+ info.sortOptions = info.sortOptions
+ if (info.offset > 0) {
+ info.prev_page = Math.max(0, info.offset - info.limit)
+ }
+ else {
+ info.prev_page = -1
+ }
+ if (info.count == info.limit && info.offset + info.limit < info.max) {
+ info.next_page = info.offset + info.limit
+ }
+ else {
+ info.next_page = -1
+ }
+ },
+
+ index: function(req, res){
+ res.render('staff/index')
+ },
+
+ // /staff/users/
+ // /staff/users/:username
+ users: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.users.length
+ res.locals.pagination.max = res.locals.userCount
+ staff.paginate(req, res)
+ res.render('staff/users/index')
+ },
+ show: function(req, res){
+ if (res.locals.profile) {
+ res.render('staff/users/show', {
+ profileJSON: util.escape( JSON.stringify( res.locals.profile ) )
+ })
+ }
+ else {
+ res.render('staff/users/show_404')
+ }
+ },
+ media: function(req, res){
+ if (res.locals.profile) {
+ res.locals.pagination.count = res.locals.media.length
+ res.locals.pagination.max = res.locals.profile.mediaCount
+ staff.paginate(req, res)
+ res.render('staff/users/media')
+ }
+ else {
+ res.render('staff/users/show_404')
+ }
+ },
+ blessSelf: function(req, res){
+ req.user.isStaff = true
+ req.user.save(function(err, user){
+ res.json({ state: user.isStaff })
+ })
+ },
+ bless: function(req, res){
+ res.locals.profile.isStaff = req.body.state == "true"
+ res.locals.profile.save(function(err, user){
+ res.json({ state: user.isStaff })
+ })
+ },
+ make_artist: function(req, res){
+ res.locals.profile.isArtist = req.body.state == "true"
+ res.locals.profile.save(function(err, user){
+ res.json({ state: user.isArtist })
+ })
+ },
+ },
+
+ // /staff/projects/
+ // /staff/projects/:slug
+ projects: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.projects.length
+ res.locals.pagination.max = res.locals.projectCount
+ staff.paginate(req, res)
+ res.render('staff/projects/index')
+ },
+ show: function(req, res){
+ if (res.locals.project) {
+ res.render('staff/projects/show', {
+ projectJSON: util.escape( JSON.stringify( res.locals.project ) ),
+ projectUserJSON: util.escape( JSON.stringify( res.locals.projectUser ) ),
+ collaboratorsJSON: util.escape( JSON.stringify( res.locals.collaborators ) ),
+ })
+ }
+ else {
+ res.render('staff/projects/show_404')
+ }
+ },
+ feature: function(req, res){
+ res.locals.project.featured = req.body.state == "true"
+ res.locals.project.save(function(err, project){
+ res.json({ state: project.featured })
+ })
+ },
+ },
+
+ // /staff/layouts/
+ // /staff/layouts/:slug
+ layouts: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.layouts.length
+ res.locals.pagination.max = res.locals.layoutCount
+ staff.paginate(req, res)
+ res.render('staff/layouts/index')
+ },
+ show: function(req, res){
+ if (res.locals.layout) {
+ res.render('staff/layouts/show', {
+ })
+ }
+ else {
+ res.render('staff/layouts/show_404')
+ }
+ },
+ make_stock: function(req, res){
+ res.locals.layout.is_stock = req.body.state == "true"
+ res.locals.layout.save(function(err, layout){
+ res.json({ state: layout.is_stock })
+ })
+ },
+ },
+
+ // /staff/blueprints/
+ // /staff/blueprints/:slug
+ blueprints: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.blueprints.length
+ res.locals.pagination.max = res.locals.blueprintCount
+ staff.paginate(req, res)
+ res.render('staff/blueprints/index')
+ },
+ show: function(req, res){
+ if (res.locals.blueprint) {
+ res.render('staff/blueprints/show', {
+ })
+ }
+ else {
+ res.render('staff/blueprints/show_404')
+ }
+ },
+ },
+
+ media: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.media.length
+ res.locals.pagination.max = res.locals.mediaCount
+ staff.paginate(req, res)
+ res.render('staff/media/index')
+ },
+ show: function(req, res){
+ if (res.locals.media) {
+ res.render('staff/media/show', {
+ mediaJSON: util.escape( JSON.stringify( res.locals.media ) ),
+ mediaUserJSON: util.escape( JSON.stringify( res.locals.mediaUser ) ),
+ })
+ }
+ else {
+ res.render('staff/media/show_404')
+ }
+ },
+ },
+
+ plans: {
+ index: function(req, res){
+ res.locals.fields = staff.fields.plans.split(" ")
+ res.locals.permissions = staff.fields.plans_permissions.split(" ")
+ res.render('staff/plans/index')
+ },
+ new: function(req, res){
+ res.locals.plan = new Plan ()
+ res.render('staff/plans/new')
+ },
+ edit: function(req, res){
+ res.locals.plan = req.plan
+ res.render('staff/plans/edit')
+ },
+ create: function(req, res){
+ var plan = new Plan ()
+ var fields = staff.fields.plans.split(" ")
+ var permissions = staff.fields.plans_permissions.split(" ")
+
+ var data = util.cleanQuery(req.body)
+ data.name = util.sanitize(data.name)
+ data.slug = util.sanitize(data.slug.toLowerCase())
+
+ data.permissions = {}
+ permissions.forEach(function(field){
+ data.permissions[field] = data["permissions_" + field].length == 2
+ })
+
+ new Plan (data).save(function(err, doc){
+ if (err || ! doc) { return res.json({ error: err }) }
+ middleware.updatePlans()
+ res.redirect("/staff/plans/")
+ })
+ },
+ update: function(req, res){
+ var fields = staff.fields.plans.split(" ")
+ var permissions = staff.fields.plans_permissions.split(" ")
+
+ var data = util.cleanQuery(req.body)
+ data.name = util.sanitize(data.name)
+ data.slug = util.sanitize(data.slug.toLowerCase())
+
+ _.extend(req.plan, data)
+ permissions.forEach(function(field){
+ req.plan.permissions[field] = data["permissions_" + field].length == 2
+ })
+
+ req.plan.save(function(err, doc){
+ if (err || ! doc) { return res.json({ error: err }) }
+ middleware.updatePlans()
+ res.redirect("/staff/plans/")
+ })
+ },
+ },
+
+ subscriptions: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.subscriptions.length
+ res.locals.pagination.max = res.locals.subscriptionCount
+ staff.paginate(req, res)
+ res.render('staff/subscriptions/index')
+ },
+ show: function(req, res){
+ res.render('staff/subscriptions/show')
+ },
+ },
+
+}
diff --git a/server/lib/views/staff/middleware.js b/server/lib/views/staff/middleware.js
new file mode 100644
index 0000000..03fda2e
--- /dev/null
+++ b/server/lib/views/staff/middleware.js
@@ -0,0 +1,476 @@
+
+var User = require('../../schemas/User'),
+ Project = require('../../schemas/Project'),
+ Media = require('../../schemas/Media'),
+ Collaborator = require('../../schemas/Collaborator'),
+ Plan = require('../../schemas/Plan'),
+ Subscription = require('../../schemas/Subscription'),
+ Layout = require('../../schemas/Layout'),
+ Blueprint = require('../../schemas/Blueprint'),
+ util = require('../../util'),
+ fields = require('./fields'),
+ helpers = require('./helpers'),
+ defaults = require('./defaults'),
+ _ = require('lodash'),
+ moment = require('moment');
+
+
+var middleware = module.exports = {
+
+ ensureUsers: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var initial = util.sanitize(req.query.initial)
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "last_seen", "username"]
+ switch (req.query.sort) {
+ case 'date':
+ sort = {'created_at': -1}
+ break
+ case 'last_seen':
+ sort = {'last_seen': -1}
+ break
+ case 'username':
+ default:
+ sort = {'username': 1}
+ paginationInfo.sort = "username"
+ break
+ }
+ if (initial) {
+ if (initial == "?") {
+ criteria.username = new RegExp('^[^a-zA-Z]', "i")
+ }
+ else {
+ criteria.username = new RegExp('^' + initial, "i")
+ }
+ }
+ User.find(criteria)
+ .select(fields.user)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, users) {
+ res.locals.users = users.map(helpers.user)
+ if (! res.locals.users.length) {
+ if (initial) {
+ res.locals.opt.error = "No users found starting with <b>" + initial.toUpperCase() + "</b>"
+ }
+ else {
+ res.locals.opt.error = "No users found"
+ }
+ }
+ next()
+ })
+ },
+
+ ensureRecentUsers: function(req, res, next){
+ var dreq = { query: { sort: 'last_seen', limit: 20, offset: 0 } }
+ middleware.ensureUsers(dreq, res, next)
+ },
+
+ ensureProjects: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "name"]
+ switch (req.query.sort) {
+ default:
+ case 'date':
+ sort = {'updated_at': -1}
+ break
+ case 'name':
+ paginationInfo.sort = "name"
+ sort = {'slug': 1}
+ break
+ }
+ Project.find(criteria)
+ .select(fields.project)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, projects) {
+ res.locals.projects = projects.map(helpers.project)
+ next()
+ })
+ },
+
+ ensureLayouts: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "name"]
+ switch (req.query.sort) {
+ default:
+ case 'date':
+ sort = {'updated_at': -1}
+ break
+ case 'name':
+ paginationInfo.sort = "name"
+ sort = {'slug': 1}
+ break
+ }
+ Layout.find(criteria)
+ .select(fields.layout)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, layouts) {
+ res.locals.layouts = layouts.map(helpers.layout)
+ next()
+ })
+ },
+
+ ensureBlueprints: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "name"]
+ switch (req.query.sort) {
+ default:
+ case 'date':
+ sort = {'updated_at': -1}
+ break
+ case 'name':
+ paginationInfo.sort = "name"
+ sort = {'slug': 1}
+ break
+ }
+ Blueprint.find(criteria)
+ .select(fields.blueprint)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, blueprints) {
+ res.locals.blueprints = blueprints.map(helpers.blueprint)
+ next()
+ })
+ },
+
+ ensureMedia: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date"]
+ switch (req.query.sort) {
+ default:
+ case 'date':
+ paginationInfo.sort = "date"
+ sort = {'created_at': -1}
+ break
+ }
+ Media.find(criteria)
+ // .select(fields.media)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, media) {
+ res.locals.media = media.map(helpers.media)
+ next()
+ })
+ },
+
+ ensureSubscriptions: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "name"]
+ switch (req.query.sort) {
+ case 'created':
+ sort = {'created_at': -1}
+ break
+ default:
+ case 'date':
+ sort = {'updated_at': -1}
+ break
+ }
+ Subscription.find(criteria)
+ .select(fields.project)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, subscriptions) {
+ res.locals.subscriptions = subscriptions.map(helpers.subscription)
+ next()
+ })
+ },
+
+ ensurePlans: function(req, res, next){
+ Plan.find({}).sort({ 'level': -1 }).exec(function (err, plans) {
+ res.locals.plans = (plans || []).map(helpers.plan)
+ res.locals.plans.sort(function(a,b){ return a.monthly_price })
+ next()
+ })
+ },
+ ensurePlan: function (req, res, next) {
+ if (req.params.slug) {
+ Plan.findOne({ slug: req.params.slug }, function(err, plan){
+ if (err || ! plan) {
+ console.error(err)
+ res.redirect("/staff/plans/")
+ }
+ else {
+ req.plan = plan
+ next()
+ }
+ })
+ }
+ else {
+ res.redirect("/staff/plans/")
+ }
+ },
+
+ ensureSubscription: function (req, res, next) {
+ if (req.params.id) {
+ Subscription.findOne({ _id: req.params.id }, function(err, subscription){
+ if (err || ! subscription) {
+ console.error(err)
+ res.redirect("/staff/subscriptions/")
+ }
+ else {
+ req.subscription = subscription
+ next()
+ }
+ })
+ }
+ else {
+ res.redirect("/staff/subscriptions/")
+ }
+ },
+
+ ensureRecentProjects: function(req, res, next){
+ var dreq = { params: { sort: 'created_at', limit: 20, offset: 0 } }
+ middleware.ensureProjects(dreq, res, next)
+ },
+
+ ensureProjectsUsers: function(req, res, next){
+ if (! res.locals.projects || ! res.locals.projects.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.projects, next)
+ },
+
+ ensureLayoutsUsers: function(req, res, next){
+ if (! res.locals.layouts || ! res.locals.layouts.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.layouts, next)
+ },
+
+ ensureBlueprintsUsers: function(req, res, next){
+ if (! res.locals.blueprints || ! res.locals.blueprints.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.blueprints, next)
+ },
+
+ ensureSubscriptionsUsers: function(req, res, next){
+ if (! res.locals.subscriptions || ! res.locals.subscriptions.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.subscriptions, next)
+ },
+
+ ensureMediaUsers: function(req, res, next){
+ if (! res.locals.media || ! res.locals.media.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.media, next)
+ },
+
+ ensureSubscriptionUser: function(req, res, next){
+ if (! res.locals.subscription) { return next() }
+ middleware.ensureObjectsUsers([ res.locals.subscription ], function(){
+ next()
+ })
+ },
+
+ ensureMediaUser: function(req, res, next){
+ if (! res.locals.media) { return next() }
+ middleware.ensureObjectsUsers([ res.locals.media ], function(){
+ res.locals.mediaUser = res.locals.media.User
+ next()
+ })
+ },
+
+ ensureObjectsUsers: function(objects, next){
+ if (! objects) { return next () }
+ var dedupe = {}, user_ids
+ objects.forEach(function(obj){
+ dedupe[ obj.user_id ] = dedupe[ obj.user_id ] || []
+ dedupe[ obj.user_id ].push(obj)
+ })
+ user_ids = _.keys(dedupe)
+ User.find({ _id: { $in: user_ids } })
+ .select(fields.user)
+ .exec(function (err, users) {
+ if (! users) { return next () }
+ users.forEach(function(user){
+ dedupe[user._id].forEach(function(obj){
+ obj.user = user
+ })
+ })
+ next()
+ })
+ },
+
+ ensureProfile: function(req, res, next){
+ var username = req.params.username
+ if (username) {
+ User.findOne({ username: username }, function (err, user) {
+ if (user) {
+ res.locals.profile = req.method == "GET" ? helpers.user(user) : user
+ }
+ else {
+ res.locals.profile = null
+ }
+ next()
+ })
+ }
+ else {
+ res.locals.profile = null
+ next()
+ }
+ },
+
+ ensureSingleMedia: function(req, res, next){
+ var id = req.params.id
+ if (id) {
+ Media.findOne({ _id: id }, function (err, media) {
+ if (media) {
+ res.locals.media = req.method == "GET" ? helpers.media(media) : media
+ }
+ else {
+ res.locals.media = null
+ }
+ next()
+ })
+ }
+ else {
+ res.locals.media = null
+ next()
+ }
+ },
+
+ ensureUsersCount: function(req, res, next){
+ User.count({}, function(err, count){
+ res.locals.userCount = count || 0
+ next()
+ })
+ },
+
+ ensureProjectsCount: function(req, res, next){
+ Project.count({}, function(err, count){
+ res.locals.projectCount = count || 0
+ next()
+ })
+ },
+
+ ensureLayoutsCount: function(req, res, next){
+ Layout.count({}, function(err, count){
+ res.locals.layoutCount = count || 0
+ next()
+ })
+ },
+
+ ensureBlueprintsCount: function(req, res, next){
+ Blueprint.count({}, function(err, count){
+ res.locals.blueprintCount = count || 0
+ next()
+ })
+ },
+
+ ensureMediaCount: function(req, res, next){
+ Media.count({}, function(err, count){
+ res.locals.mediaCount = count || 0
+ next()
+ })
+ },
+
+ ensureProfileProjectCount: function(req, res, next){
+ if (! res.locals.profile) { return next() }
+ Project.count({ user_id: res.locals.profile._id}, function(err, count){
+ res.locals.profile.projectCount = count || 0
+ next()
+ })
+ },
+
+ ensureProfileMediaCount: function(req, res, next){
+ if (! res.locals.profile) { return next() }
+ Media.count({ user_id: res.locals.profile._id}, function(err, count){
+ res.locals.profile.mediaCount = count || 0
+ next()
+ })
+ },
+
+ ensureProfileProjects: function(req, res, next){
+ if (! res.locals.profile) { return next() }
+ Project.find({ user_id: res.locals.profile._id }, fields.project, function(err, projects){
+ res.locals.projects = projects.map(helpers.project)
+ next()
+ })
+ },
+
+ ensureProfileMedia: function(req, res, next){
+ if (! res.locals.profile) { return next() }
+ req.criteria = { user_id: res.locals.profile._id }
+ middleware.ensureMedia(req, res, next)
+ },
+
+ ensureProject: function(req, res, next){
+ res.locals.project = req.project
+ next()
+ },
+
+ ensureProjectUser: function(req, res, next){
+ if (! res.locals.project) { return next() }
+ User.findOne({ _id: res.locals.project.user_id }, fields.user, function(err, user){
+ res.locals.projectUser = helpers.user(user) || defaults.user
+ next()
+ })
+ },
+
+ ensureProjectCollaborators: function(req, res, next){
+ if (! res.locals.project) {
+ res.locals.collaborators = []
+ return next()
+ }
+ Collaborator.find({ project_id: res.locals.project._id}, function(err, collaborators){
+ res.locals.collaborators = collaborators || []
+ next()
+ })
+ },
+
+ ensureLayout: function(req, res, next){
+ res.locals.layout = req.layout
+ next()
+ },
+ ensureLayoutUser: function(req, res, next){
+ if (! res.locals.layout) { return next() }
+ User.findOne({ _id: res.locals.layout.user_id }, fields.user, function(err, user){
+ res.locals.layoutUser = helpers.user(user) || defaults.user
+ next()
+ })
+ },
+
+ ensureBlueprint: function(req, res, next){
+ res.locals.blueprint = req.blueprint
+ next()
+ },
+ ensureBlueprintUser: function(req, res, next){
+ if (! res.locals.blueprint) { return next() }
+ User.findOne({ _id: res.locals.blueprint.user_id }, fields.user, function(err, user){
+ res.locals.blueprintUser = helpers.user(user) || defaults.user
+ next()
+ })
+ },
+
+
+} \ No newline at end of file
diff --git a/server/lib/webhook/index.js b/server/lib/webhook/index.js
new file mode 100644
index 0000000..a5f23ac
--- /dev/null
+++ b/server/lib/webhook/index.js
@@ -0,0 +1,44 @@
+var config = require('../../../config.json'),
+ http = require('http'),
+ express = require('express'),
+ bodyParser = require('body-parser'),
+ mongoose = require('mongoose');
+
+var http = require('http'),
+ express = require('express'),
+ bodyParser = require('body-parser'),
+ multer = require('multer'),
+ MongoStore = require('connect-mongo')(express),
+ passport = require('passport'),
+ path = require('path'),
+ mongoose = require('mongoose');
+
+var webhook = require('./webhook');
+
+var app = express()
+var server
+var DATABASE_URI = process.env.MONGOLAB_URI || ('mongodb://' + config.databaseHost + '/vvalls')
+
+var site = {}
+
+site.init = function(){
+ mongoose.connect(DATABASE_URI, {}, site.ready);
+}
+
+site.ready = function(){
+ app.set('port', config.webhookPort);
+ // app.use(bodyParser());
+ app.use(express.query());
+ app.set('env', config.env.production ? "production" : "development")
+ app.get('env') === 'development' && app.use(express.errorHandler());
+
+ server = http.createServer(app)
+ server.listen(app.get('port'), function () {
+ console.log('Webhook server listening on port ' + app.get('port'));
+ });
+
+ app.get('/', function(req,res){ res.send('hello@vvalls.com') })
+ webhook.route(app)
+}
+
+site.init()
diff --git a/server/lib/webhook/recurly-config.js b/server/lib/webhook/recurly-config.js
new file mode 100644
index 0000000..3d7e1c5
--- /dev/null
+++ b/server/lib/webhook/recurly-config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ API_KEY: process.env['VVALLS_RECURLY_SECRET'],
+ SUBDOMAIN: 'vvalls',
+ ENVIRONMENT: 'sandbox',
+ DEBUG: true,
+};
diff --git a/server/lib/webhook/webhook.js b/server/lib/webhook/webhook.js
new file mode 100644
index 0000000..9501f86
--- /dev/null
+++ b/server/lib/webhook/webhook.js
@@ -0,0 +1,175 @@
+// // where should this live?
+
+/*
+app.use(express.basicAuth(function(user, pass, callback) {
+ var result = (user === 'testUser' && pass === 'testPass');
+ callback(null, result);
+}));
+*/
+
+
+/* jshint node: true */
+
+var User = require('../schemas/User'),
+ Subscription = require('../schemas/Subscription'),
+ config = require('../../../config'),
+ middleware = require('../middleware'),
+ util = require('../util'),
+ _ = require('lodash'),
+ moment = require('moment'),
+ Recurly = require('node-recurly'),
+ recurly = new Recurly(require('./recurly-config'));
+
+var xml_bodyparser = require('express-xml-bodyparser');
+
+var subscribe = module.exports = {
+ plan_levels: {
+ free: 0,
+ basic: 1,
+ pro: 2,
+ custom: 3,
+ artist: 4,
+ },
+
+ callbacks: {
+/*
+ // accounts
+ new_account_notification: function(data, user){
+ // fires on successful signup
+ },
+ canceled_account_notification: function(data, user){
+ },
+ billing_info_updated_notification: function(data, user){
+ },
+ reactivated_account_notification: function(data, user){
+ },
+
+ // invoices
+ new_invoice_notification: function(data, user){
+ },
+ closed_invoice_notification: function(data, user){
+ },
+ past_due_invoice_notification: function(data, user){
+ },
+*/
+
+ // subscriptions
+ new_subscription_notification: function(data, user){
+ var account = data.account[0].account_code[0]
+ var subscrip = data.subscription[0]
+ var uuid = subscrip.uuid[0]
+ Subscription.findOne({ "uuid": uuid }, function(err, old_subscriber){
+ // if (err) return;
+
+ var plan, plan_type, plan_code
+ var plan_code = subscrip.plan[0].plan_code[0]
+
+ if (plan_code.indexOf("-") !== -1) {
+ plan = plan_code.split("-")
+ plan_type = plan[0]
+ plan_period = plan[1]
+ }
+ else {
+ plan_type = "custom"
+ plan_period = "monthly"
+ }
+
+ user.plan_code = plan_code
+ user.plan_type = plan_type
+ user.plan_level = subscribe.plan_levels[plan_type]
+
+ var subscriber = old_subscriber || new Subscription ()
+ subscriber.uuid = uuid
+ subscriber.user_id = user._id
+ subscriber.plan_code = plan_code
+ subscriber.plan_type = plan_type
+ subscriber.plan_period = plan_period
+ subscriber.plan_level = subscribe.plan_levels[plan_type]
+ subscriber.add_ons = []
+ var add_ons = subscrip.subscription_add_ons[0].subscription_add_on
+ if (add_ons) {
+ add_ons.forEach(function(add_on){
+ switch (add_on.add_on_code[0]) {
+ case 'extra-basic-layout':
+ subscriber.basic_layouts = parseInt(add_on.quantity[0]._, 10) || 0
+ break
+ case 'extra-pro-layout':
+ subscriber.pro_layouts = parseInt(add_on.quantity[0]._, 10) || 0
+ break
+ }
+ })
+ }
+ subscriber.save(function(err, data){
+ if (err) return;
+ user.save(function(err){
+ // saved!
+ })
+ })
+ })
+ },
+
+/*
+ updated_subscription_notification: function(data, user){
+ },
+ canceled_subscription_notification: function(data, user){
+ },
+ expired_subscription_notification: function(data, user){
+ },
+ renewed_subscription_notification: function(data, user){
+ },
+*/
+ // payments
+ successful_payment_notification: function(data, user){
+ var account = data.account[0]
+ user.last_charged = new Date(data.transaction[0].date[0]._)
+ user.save(function(){
+ })
+ },
+/*
+ failed_payment_notification: function(data, user){
+ },
+ successful_refund_notification: function(data, user){
+ },
+ void_payment_notification: function(data, user){
+ },
+*/
+ },
+
+ execute: function(action, data){
+ User.findOne({ _id: data.account[0].account_code[0] }, function(err, user){
+ if (err) { return }
+ subscribe.callbacks[action](data, user)
+ })
+ },
+
+ // then calls to get appropriate info from the recurly api
+ handle: function(req, res){
+ console.log(req.body)
+ // parser.parseString(req.body, function (err, result) {
+ var result = req.body
+ for (var action in result) {
+ if (subscribe.callbacks[action]) {
+ subscribe.execute(action, result[action]);
+ }
+ }
+ return res.status(200).end()
+ },
+
+ list: function(req, res){
+ recurly.subscriptions.listByAccount(req.params.id, function(data){
+ if (data.data != 404) {
+ res.json(data)
+ return
+ }
+ else {
+ res.json(data)
+ return
+ }
+ })
+ },
+
+ route: function(app){
+ app.post('/subscribe/webhook', xml_bodyparser(), subscribe.handle);
+ app.get('/subscribe/list/:id', subscribe.list);
+ },
+}
diff --git a/server/repl.js b/server/repl.js
index ba94d45..353d8c5 100644
--- a/server/repl.js
+++ b/server/repl.js
@@ -9,6 +9,8 @@ mongoose.connect('mongodb://' + DB_HOST + '/vvalls', {}, function(){
"./lib/schemas/Layout",
"./lib/schemas/Media",
"./lib/schemas/Project",
+ "./lib/schemas/Plan",
+ "./lib/schemas/Subscription",
].forEach(function(modName){
// console.log(name, modName)
var namez = modName.split("/"), name = namez[namez.length-1];
diff --git a/views/about/_blank.ejs b/views/about/_blank.ejs
index 0e9ea7e..732ea3f 100644
--- a/views/about/_blank.ejs
+++ b/views/about/_blank.ejs
@@ -1,14 +1,14 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include ../partials/meta ]]
</head>
<body class="loading">
<div class="rapper page home">
[[ include ../partials/header ]]
-
+ <h1 class="leader">Hallo</h1>
<!-- put stuff here -->
diff --git a/views/about/_old_plans.ejs b/views/about/_old_plans.ejs
new file mode 100644
index 0000000..e4b07be
--- /dev/null
+++ b/views/about/_old_plans.ejs
@@ -0,0 +1,63 @@
+ <div class="about_plan planbox free_plan_info">
+ <h3>[[- plans.free.name ]]</h3>
+ <ul>
+ <li> [[- plans.free.stock_project_limit ]] exhibition with pre-designed template floor plan
+ </ul>
+ </div>
+
+ <div class="about_plan planbox">
+ <h3>[[- plans.basic.name ]]</h3>
+ <ul>
+ <li> $[[- plans.basic.monthly_price ]]/mo or $[[- plans.basic.yearly_price ]]/year
+ <li> Comes with [[- plans.basic.basic_layout_limit ]] basic floor plan and [[- plans.basic.basic_project_limit ]] exhibitions
+ <li> Each new basic floor plan costs $[[- plans.basic.basic_layout_monthly_price ]]/mo
+ or $[[- plans.basic.basic_layout_yearly_price ]]/year, minimum 3 months
+ <li> Each new floor plan can have up to [[- plans.basic.basic_project_limit ]] exhibitions
+ <li> VValls logo appears when embedding an exhibition on a web page
+ <li>
+ [[ if (! logged_in) { ]]
+ <button data-role="show-signup-modal">Sign Up</button>
+ [[ } else if (! user.plan_level) { ]]
+ <a href="https://vvalls.recurly.com/subscribe/basic-monthly/[[- user._id ]]/[[- user.username ]]"><button>Buy Now</button></a>
+ [[ } else if (user.plan_level == plans.basic.level) { ]]
+ Current Level
+ [[ } ]]
+ </ul>
+ </div>
+
+ <div class="about_plan planbox">
+ <h3>[[- plans.pro.name ]]</h3>
+ <ul>
+ <li> $[[- plans.pro.monthly_price ]]/mo or $[[- plans.pro.yearly_price ]]/year
+ <li> Comes with [[- plans.pro.pro_layout_limit ]] pro floor plan and [[- plans.pro.pro_project_limit ]] exhibitions
+ <li> Each new pro floor plan costs $[[- plans.pro.pro_layout_monthly_price ]]/mo
+ or $[[- plans.pro.pro_layout_yearly_price ]]/year, minimum 3 months
+ <li> Each new pro floor plan can have up to [[- plans.pro.pro_project_limit ]] exhibitions
+ <li> Includes planning for 3D objects in the room
+ <li> No VValls logo on embed
+ <li>
+ [[ if (! logged_in) { ]]
+ <button data-role="show-signup-modal">Sign Up</button>
+ [[ } else if (! user.plan_level) { ]]
+ <a href="https://vvalls.recurly.com/subscribe/pro-monthly/[[- user._id ]]/[[- user.username ]]"><button>Buy Now</button></a>
+ [[ } else if (user.plan_level == plans.pro.level) { ]]
+ Current Level
+ [[ } else if (user.plan_level < plans.pro.level) { ]]
+ <a href="/profile/billing"><button>Upgrade Now</button></a>
+ [[ } ]]
+ </ul>
+ </div>
+
+ <div class="about_custom planbox miscbox">
+ <ul>
+ <li> Buying any extra floor plan unlocks collaboration.<br>Invite an artist or curator to work on the exhibition with you.
+ <li> Basic Floor plan: Rectangle-based design of any dimension.
+ <li> Pro Floor plan: Trace an arbitrary floor plan from image.
+ </ul>
+ </div>
+
+ <div class="about_custom custombox planbox">
+ <h3>Want Something Custom?</h3>
+ <li> We offer customized white-label options for business and educational uses.
+ <li> <a href="mailto:hello@vvalls.com">Contact us</a> for more information.
+ </div>
diff --git a/views/about/_plans.ejs b/views/about/_plans.ejs
new file mode 100644
index 0000000..95b8d2f
--- /dev/null
+++ b/views/about/_plans.ejs
@@ -0,0 +1,121 @@
+<ul id="plans">
+ <li class="most-popular">
+ <div class="top">
+ <h2>[[- plans.pro.name ]]</h2>
+ <h3><span class="dollar">$</span><span class="price large">[[- plans.pro.monthly_price ]]</span> <span class="month large">/ mo </span></h3>
+ <h4>Ideal for large galleries<br>and small businesses.</h4>
+ </div>
+ <ul>
+ <li>
+ [[- plans.pro.pro_layout_limit ]] Pro Floor Plans and [[- plans.pro.pro_project_limit ]] Exhibitions
+ </li>
+ <li>
+ Trace a Floor Plan from a Drawing
+ </li>
+ <li>
+ Image Hosting For Artworks
+ </li>
+ <li>
+ Planning for 3D Objects
+ </li>
+ <li>
+ Everything the Medium Plan Contains
+ </li>
+ <li>
+ No Branding!
+ </li>
+ </ul>
+ <div class="signup">
+ [[ if (! logged_in) { ]]
+ <a class="button" href="#" data-role="show-signup-modal">Sign Up for [[- plans.pro.name ]]</a>
+ [[ } else if (! user.plan_level || user.plan_level < plans.pro.level) { ]]
+ <a class="button" href="https://vvalls.recurly.com/subscribe/pro-monthly/[[- user._id ]]/[[- user.username ]]">Sign Up for [[- plans.pro.name ]]</a>
+ [[ } else if (user.plan_level == plans.pro.level) { ]]
+ <div class="current">Current Level</div>
+ [[ } ]]
+ </div>
+ </li>
+ <li>
+ <div class="top">
+ <h2>[[- plans.basic.name ]]</h2>
+ <h3><span class="dollar">$</span><span class="price medium">[[- plans.basic.monthly_price ]]</span> <span class="month medium">/ mo </span></h3>
+ <h4>Great for small galleries<br>and art projects.</h4>
+ </div>
+ <ul>
+ <li>
+ [[- plans.basic.basic_layout_limit ]] Basic Floor Plan and [[- plans.basic.basic_project_limit ]] Exhibitions
+ </li>
+ <li>
+ Add More Basic Floor Plans for $[[- plans.basic.basic_layout_monthly_price ]]/mo
+ </li>
+ <li>
+ Invite Artists to Collaborate
+ </li>
+ <li>
+ Prepay a Year and Get Two Months Free
+ </li>
+ <li>
+ Everything the Small Plan Contains
+ </li>
+ <li>
+ VValls Branding
+ </li>
+ </ul>
+ <div class="signup">
+ [[ if (! logged_in) { ]]
+ <a class="button" href="#" data-role="show-signup-modal">Sign Up for [[- plans.basic.name ]]</a>
+ [[ } else if (! user.plan_level || user.plan_level < plans.basic.level) { ]]
+ <a class="button" href="https://vvalls.recurly.com/subscribe/basic-monthly/[[- user._id ]]/[[- user.username ]]">Sign Up for [[- plans.basic.name ]]</a>
+ [[ } else if (user.plan_level == plans.basic.level) { ]]
+ <div class="current">Current Level</div>
+ [[ } else { ]]
+ <div class="current">&nbsp;</div>
+ [[ } ]]
+ </div>
+ </li>
+ <li>
+ <div class="top">
+ <h2>[[- plans.free.name ]]</h2>
+ <h3><span class="dollar">$</span><span class="price small">0</span> <span class="month small">/ mo </span></h3>
+ <h4>Free forever.</h4>
+ </div>
+ <ul>
+ <li>
+ [[- plans.free.stock_project_limit ]] Basic Exhibition
+ </li>
+ <li>
+ Use Any of our Built-In Floor Plans
+ </li>
+ <li>
+ Embed Images and Videos in your Room
+ </li>
+ <li>
+ Custom Color and Wallpaper
+ </li>
+ <li>
+ Embed Room on Your Website
+ </li>
+ <li>
+ VValls Branding
+ </li>
+ </ul>
+
+ <div class="signup">
+ [[ if (! logged_in) { ]]
+ <a class="button" href="#" data-role="show-signup-modal">Sign Up for Small</a>
+ [[ } else if (! user.plan_level || user.plan_level == plans.free.level) { ]]
+ <div class="current">Current Level</div>
+ [[ } else { ]]
+ <div class="current">&nbsp;</div>
+ [[ } ]]
+ </div>
+ </li>
+</ul>
+
+<br>
+<div class="about_custom custombox planbox">
+ <h3>Want Something Custom?</h3>
+ <li> We offer customized white-label options for business and educational uses.
+ <br>
+ <a href="mailto:hello@vvalls.com">Contact us</a> for more information.
+</div>
diff --git a/views/about/about.ejs b/views/about/about.ejs
index dd536be..a1d04a1 100644
--- a/views/about/about.ejs
+++ b/views/about/about.ejs
@@ -1,46 +1,21 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>About VValls</title>
[[ include ../partials/meta ]]
</head>
<body class="loading">
<div class="rapper page">
[[ include ../partials/header ]]
- <h1>About VValls</h1>
+ <h1 class="leader">About VValls</h1>
<div class="projectList about aboutintro">
<div class="inner">
VValls is a platform for creating and sharing immersive web based 3D exhibitions. With VValls users can draw floor plans, and then apply media to the surfaces of the virtual space. VValls is the ideal solution for anyone creating immersive presentations of content, curators looking to plan shows, and artists looking to visualize their work in 3D space. VValls is completely HTML5 based – mobile and desktop compatible.
- <br><br>
- Contact us with inquiries at <a href="mailto:hello@vvalls.com">hello@vvalls.com</a>.<br>
- We are based in New York City.
- </div>
-
- <div class="item">
- <div class="rap">
- <span style="background-image:url(http://vvalls.s3.amazonaws.com/static/larisa.jpg)">
- </span>
- <span>
- <h3>Dot Dash 3</h3>
- <words>VValls was conceived and prototyped by Larisa Leventon, Ph.D., MBA, founder of Dot Dash 3 and an M.I.T. + Brown University-trained visualization algorithm specialist.</words>
- </span>
- </div>
- </div>
-
- <div class="item">
- <div class="rap">
- <span style="background-image:url(http://vvalls.s3.amazonaws.com/static/okf.jpg)">
- </span>
- <span>
- <h3>OKFocus</h3>
- <words>VValls was developed and designed by OKFocus, a forward thinking NYC based creative agency. The technology was spearheaded by Jules LaPlace, CTO, and the design by Ryder Ripps, ECD.</words>
- </span>
- </div>
</div>
</div>
-
+
[[ include ../partials/confirm-modal ]]
[[ include ../projects/layouts-modal ]]
[[ include ../partials/sign-in ]]
@@ -50,17 +25,3 @@
</body>
[[ include ../partials/scripts ]]
</html>
-<style>
-.aboutintro {
- text-align: center;
- line-height: 43px;
- font-size: 24px;
- padding: 5% 0;
- font-weight: 300;
-}
-.aboutintro .inner {
- max-width: 800px;
- margin: 0 auto;
- text-align: center;
-}
-</style> \ No newline at end of file
diff --git a/views/about/brochure.ejs b/views/about/brochure.ejs
new file mode 100644
index 0000000..e34d3d3
--- /dev/null
+++ b/views/about/brochure.ejs
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+<head>
+ <title>VValls Subscriptions</title>
+ [[ include ../partials/meta ]]
+</head>
+<body class="loading">
+ <div class="rapper page">
+ [[ include ../partials/header ]]
+
+ <h1 class="leader">Subscriptions</h1>
+
+ <div class="projectList about aboutintro">
+ [[ include _plans ]]
+ </div>
+
+ [[ include ../partials/confirm-modal ]]
+ [[ include ../projects/layouts-modal ]]
+ [[ include ../partials/sign-in ]]
+ [[ include ../partials/footer ]]
+
+ </div>
+</body>
+[[ include ../partials/scripts ]]
+</html>
diff --git a/views/about/howto.ejs b/views/about/howto.ejs
index 5278a40..7d9c594 100644
--- a/views/about/howto.ejs
+++ b/views/about/howto.ejs
@@ -1,14 +1,14 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>How to Use VValls</title>
[[ include ../partials/meta ]]
</head>
<body class="loading">
<div class="rapper page">
[[ include ../partials/header ]]
- <div class="hero" style="background-image:url(http://okfocus.s3.amazonaws.com/images/vvalls/construction.jpg);">
+ <div class="hero" style="">
<div class="holder">
</div>
</div>
diff --git a/views/about/privacy.ejs b/views/about/privacy.ejs
new file mode 100644
index 0000000..3b748bf
--- /dev/null
+++ b/views/about/privacy.ejs
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+<head>
+ <title>About VValls</title>
+ [[ include ../partials/meta ]]
+</head>
+<body class="loading">
+ <div class="rapper page">
+ [[ include ../partials/header ]]
+
+ <h1 class="leader">Privacy Policy</h1>
+
+ <div class="projectList about aboutintro">
+ <div class="inner">
+ When you log into VValls we store cookies to make sure we know you're logged in. If you sign up, we store your email address, but you can always sign up with a fictitious email address. We will never sell your data. We are not responsible for third party privacy policies, e.g. embedding a Youtube video, but we encourage you to run an ad blocker.
+ </div>
+ </div>
+
+ [[ include ../partials/confirm-modal ]]
+ [[ include ../projects/layouts-modal ]]
+ [[ include ../partials/sign-in ]]
+ [[ include ../partials/footer ]]
+
+ </div>
+</body>
+[[ include ../partials/scripts ]]
+</html>
diff --git a/views/about/terms.ejs b/views/about/terms.ejs
new file mode 100644
index 0000000..46a7c69
--- /dev/null
+++ b/views/about/terms.ejs
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+<head>
+ <title>Terms</title>
+ [[ include ../partials/meta ]]
+</head>
+<body class="loading">
+ <div class="rapper page">
+ [[ include ../partials/header ]]
+
+ <h1 class="leader">Terms</h1>
+
+ <div class="projectList about aboutintro">
+ <div class="inner">
+ This website is ALPHA software! Use at your own risk. We are not responsible for how VValls is used. Have fun!
+ </div>
+ </div>
+
+ [[ include ../partials/confirm-modal ]]
+ [[ include ../projects/layouts-modal ]]
+ [[ include ../partials/sign-in ]]
+ [[ include ../partials/footer ]]
+
+ </div>
+</body>
+[[ include ../partials/scripts ]]
+</html>
diff --git a/views/blueprint.ejs b/views/blueprint.ejs
new file mode 100644
index 0000000..13e8182
--- /dev/null
+++ b/views/blueprint.ejs
@@ -0,0 +1,30 @@
+<!doctype html>
+<html>
+<head>
+ <title>VValls</title>
+ [[ include partials/meta ]]
+</head>
+<body class="editing loading">
+
+ <div id="scene"></div>
+
+ <div class="rapper">
+ [[ include partials/header ]]
+
+ <div id="builderView">
+ [[ include controls/blueprint/info ]]
+ [[ include controls/blueprint/toolbar ]]
+ [[ include controls/blueprint/settings ]]
+ [[ include controls/blueprint/editor ]]
+ [[ include controls/blueprint/scaler ]]
+ [[ include controls/blueprint/notice ]]
+ </div>
+ </div>
+
+ [[ include partials/confirm-modal ]]
+ [[ include projects/layouts-modal ]]
+ [[ include partials/sign-in ]]
+
+</body>
+[[ include partials/scripts ]]
+</html>
diff --git a/views/builder.ejs b/views/builder.ejs
index afb8c66..6a31e22 100644
--- a/views/builder.ejs
+++ b/views/builder.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="editing loading">
@@ -17,22 +17,6 @@
[[ include controls/builder/settings ]]
</div>
- <!--
- <div id="minimap" class="vvbox">
- <span class="el"></span>
- </div>
-
- <select id="palette">
- <option>colors</option>
- <option>redblue</option>
- <option>gray</option>
- <option selected>bone</option>
- <option>alpha</option>
- <option>white</option>
- <option>black</option>
- </select>
- -->
-
<div id="hud">
<div id="map" style="display: block">
</div>
diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs
new file mode 100644
index 0000000..0dbac8e
--- /dev/null
+++ b/views/controls/blueprint/editor.ejs
@@ -0,0 +1,36 @@
+<style type="text/css">
+#perspective,
+#perspective .mx-scene {
+ position: absolute;
+ left:0%;
+ top:0px;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+.blueprintInfo {
+ bottom: 14px;
+ left: 10px;
+ width: 270px;
+ font-size: 13px;
+ font-weight: 300;
+ padding: 10px;
+}
+.blueprintInfo .setting {
+ margin-bottom: 20px;
+}
+.blueprintInfo .setting.number input[type=text] {
+ width: 100px;
+ font-size: 16px;
+}
+</style>
+
+<div id="blueprintView">
+ <div id="perspective"></div>
+ <div id="orthographic"></div>
+</div>
+
diff --git a/views/controls/blueprint/info.ejs b/views/controls/blueprint/info.ejs
new file mode 100644
index 0000000..a86481b
--- /dev/null
+++ b/views/controls/blueprint/info.ejs
@@ -0,0 +1,30 @@
+<div class="vvbox settings info" id="blueprintInfo">
+ <h4>Blueprint Editor</h4>
+
+ <div class="setting number twoline">
+ <label for="room-height">ceiling height</label>
+ <input type="text" class="units" name="height" id="room-height">
+ </div>
+
+ <div class="setting number twoline">
+ <label for="viewHeight">camera height</label>
+ <input type="text" class="units" name="viewHeight" id="viewHeight">
+ </div>
+
+ <div class="setting number twoline">
+ <label for="builder-units">units</label>
+ <select id="builder-units" name="units">
+ <option value="px">pixels</option>
+ <option value="ft">feet</option>
+ <option value="m">meters</option>
+ </select>
+ </div>
+
+ <div class="setting number scale">
+ <label>scale</label>
+ <span id="blueprintScaleDisplay"></span>
+ px/<span class="units"></span>
+ <span class="openScaler">[edit scale]</span>
+ </div>
+
+</div>
diff --git a/views/controls/blueprint/notice.ejs b/views/controls/blueprint/notice.ejs
new file mode 100644
index 0000000..bf1a310
--- /dev/null
+++ b/views/controls/blueprint/notice.ejs
@@ -0,0 +1,4 @@
+<div class="vvbox settings" id="blueprintNotice">
+ <div class="notice"></div>
+ <span class="next">Next</span>
+</div>
diff --git a/views/controls/blueprint/scaler.ejs b/views/controls/blueprint/scaler.ejs
new file mode 100644
index 0000000..82fd2b2
--- /dev/null
+++ b/views/controls/blueprint/scaler.ejs
@@ -0,0 +1,48 @@
+<div class="mediaDrawer fixed animate active blueprintScaler">
+ <div class="box">
+
+ <div class="blueprintUploader">
+ <h2>Upload your Blueprint</h2>
+ <p>
+ Upload an image which you will trace to make a floor plan.
+ Images should be at least 1000x1000.
+ </p>
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <input type="text" class="url" placeholder="Enter an image URL or...">
+ <div class="wallpaperUpload toolButton">
+ <form>
+ <span class="ion-ios-upload-outline upload-icon"></span>
+ <label>Upload a File</label>
+ <input type="file" accept="image/*" multiple>
+ </form>
+ </div>
+ <div class="blueprints">
+ <h5>Your uploaded blueprints</h5>
+ </div>
+ </div>
+
+ <div class="blueprintInfo vvbox">
+ Please tell us the scale of your blueprint.
+ Click two corners of a wall, and then enter how long the wall is.
+ <br><br>
+ You can also <span class="uploadNewBlueprint">upload another blueprint</span>.
+ <br><br>
+
+ <form>
+ <div class="setting number">
+ <label for="blueprint-dimensions">length</label>
+ <input type="text" class="units" name="blueprint-dimensions" id="blueprint-dimensions">
+ <select id="blueprint-units" name="blueprint-units">
+ <option value="ft">feet</option>
+ <option value="m">meters</option>
+ </select>
+ </div>
+ <button id="saveBlueprint">Save</button>
+ </form>
+ </div>
+
+ <div id="blueprintMap">
+ </div>
+
+ </div>
+</div> \ No newline at end of file
diff --git a/views/controls/blueprint/settings.ejs b/views/controls/blueprint/settings.ejs
new file mode 100644
index 0000000..9c615ea
--- /dev/null
+++ b/views/controls/blueprint/settings.ejs
@@ -0,0 +1,18 @@
+<div class="vvbox settings active" id="blueprintSettings">
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <input type="hidden" name="_id" value="new">
+
+ <div class="setting">
+ <input type="text" name="name" placeholder="Blueprint name">
+ </div>
+
+ <div class="setting">
+ <button data-role="save-layout">Save</button>
+ </div>
+
+ <div class="setting subButtons">
+ <a href="#" data-role="clear-layout">Clear</a>
+ <a href="#" data-role="destroy-layout">Delete</a>
+ </div>
+
+</div>
diff --git a/views/controls/blueprint/toolbar.ejs b/views/controls/blueprint/toolbar.ejs
new file mode 100644
index 0000000..c499262
--- /dev/null
+++ b/views/controls/blueprint/toolbar.ejs
@@ -0,0 +1,42 @@
+<div class="edit menu vvbox" id="blueprintToolbar">
+
+ <span
+ data-role='upload-floorplan'
+ data-info="upload a new floorplan"
+ class="ion-ios-upload-outline"></span>
+
+ <span
+ data-role='toggle-orbit-mode'
+ data-info="toggle 3D mode"
+ class="ion-ios-photos-outline"></span>
+
+ <span
+ data-role="arrow-mode"
+ data-info="move endpoints"
+ class="ion-navigate mode"></span>
+
+ <span
+ data-role="polyline-mode"
+ data-info="draw walls"
+ class="ion-ios-pulse mode"></span>
+
+ <span
+ data-role="ortho-polyline-mode"
+ data-info="draw right-angled walls"
+ class="ion-ios-grid-view-outline mode"></span>
+
+ <span
+ data-role="eraser-mode"
+ data-info="remove walls"
+ class="ion-scissors mode"></span>
+
+ <span
+ data-role="start-position-mode"
+ data-info="set starting position"
+ class="ion-ios-home-outline mode"></span>
+
+ <span
+ data-role='toggle-layout-settings'
+ data-info="save blueprint"
+ class="ion-ios-compose-outline"></span>
+</div>
diff --git a/views/controls/builder/info.ejs b/views/controls/builder/info.ejs
index 8a0e0d5..11e995a 100644
--- a/views/controls/builder/info.ejs
+++ b/views/controls/builder/info.ejs
@@ -34,8 +34,8 @@
<label for="builder-units">units</label>
<select id="builder-units" name="units">
<option value="px">pixels</option>
- <option value="ft">foot</option>
- <option value="m">meter</option>
+ <option value="ft">feet</option>
+ <option value="m">meters</option>
</select>
</div>
diff --git a/views/controls/builder/settings.ejs b/views/controls/builder/settings.ejs
index aae67d0..f7642ae 100644
--- a/views/controls/builder/settings.ejs
+++ b/views/controls/builder/settings.ejs
@@ -4,7 +4,7 @@
<div class="setting">
<a href="#" id="startpoint">
- <span class="ion-ios7-navigate-outline"></span>
+ <span class="ion-ios-navigate-outline"></span>
<span id="startText">Select Startpoint</span>
<span id="moveText">Move to Desired Point</span></a>
</div>
diff --git a/views/controls/builder/toolbar.ejs b/views/controls/builder/toolbar.ejs
index 8b2e9b8..ad51f0e 100644
--- a/views/controls/builder/toolbar.ejs
+++ b/views/controls/builder/toolbar.ejs
@@ -2,7 +2,7 @@
<span
data-role='toggle-map-view'
data-info="toggle map view"
- class="ion-ios7-photos-outline"></span>
+ class="ion-ios-photos-outline"></span>
<!--
<span
data-role='create-mode'
@@ -20,7 +20,7 @@
<span
data-role='destroy-mode'
data-info="delete"
- class="ion-ios7-trash-outline"></span>
+ class="ion-ios-trash-outline"></span>
<!--
<span
data-role='undo'
@@ -30,5 +30,5 @@
<span
data-role='toggle-layout-settings'
data-info="save layout"
- class="ion-ios7-compose-outline"></span>
+ class="ion-ios-compose-outline"></span>
</div>
diff --git a/views/controls/editor/media-drawer.ejs b/views/controls/editor/media-drawer.ejs
index f9bce61..8070941 100644
--- a/views/controls/editor/media-drawer.ejs
+++ b/views/controls/editor/media-drawer.ejs
@@ -3,8 +3,6 @@
<img class="floatingImg">
</div>
-<span class="close" id="fixed_close">X</span>
-
<div class="mediaDrawer fixed animate mediaViewer">
<h2>
<a href="#" class="userToggle active">Your Media</a>
@@ -35,7 +33,7 @@
<span class="fileUpload" id="fileUpload">
<input type="hidden" name="_csrf" value="[[- token ]]">
<form>
- <span class="ion-ios7-upload-outline upload-icon"></span><br>
+ <span class="ion-ios-upload-outline upload-icon"></span><br>
Upload File
<input type="file" accept="image/*" multiple>
</form>
diff --git a/views/controls/editor/media-editor.ejs b/views/controls/editor/media-editor.ejs
index 99746e8..225bdc8 100644
--- a/views/controls/editor/media-editor.ejs
+++ b/views/controls/editor/media-editor.ejs
@@ -13,8 +13,8 @@
<div class="video audio setting">
<span class="playButton" data-role="play-media">
- <span class="on ion-ios7-play-outline"></span>
- <span class="off ion-ios7-pause-outline"></span>
+ <span class="on ion-ios-play-outline"></span>
+ <span class="off ion-ios-pause-outline"></span>
</span>
<!--
ion-volume-high
@@ -49,8 +49,8 @@
<div class="setting number">
<select id="builder-units" name="units">
<option value="px">pixels</option>
- <option value="ft">foot</option>
- <option value="m">meter</option>
+ <option value="ft">feet</option>
+ <option value="m">meters</option>
</select>
</div>
-->
diff --git a/views/controls/editor/sculpture.ejs b/views/controls/editor/sculpture.ejs
new file mode 100644
index 0000000..dfe917f
--- /dev/null
+++ b/views/controls/editor/sculpture.ejs
@@ -0,0 +1,42 @@
+<div class="vvbox settings" id="sculptureEditor">
+ <h4>3D Object</h4>
+
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <input type="hidden" name="_id" value="new">
+
+ <div class="setting">
+ <input type="text" name="name" placeholder="media title">
+ </div>
+
+ <div class="setting">
+ <textarea name="description" placeholder="short description"></textarea>
+ </div>
+
+ <div class="setting">
+ <input type="checkbox" name="outline" value="1" id="sculpture-outline">
+ <label for="sculpture-outline">Show outline?</label>
+ <input type="color" name="outlineColor" value="#000000">
+ </div>
+
+ <div class="setting">
+ <input type="checkbox" name="billboard" value="1" id="sculpture-billboard">
+ <label for="sculpture-billboard">Billboard?</label>
+ </div>
+
+ <div class="setting number">
+ <label for="sculpture-width">width</label>
+ <input type="text" class="units" name="width" id="sculpture-width">
+ </div>
+ <div class="setting number">
+ <label for="sculpture-height">height</label>
+ <input type="text" class="units" name="height" id="sculpture-height">
+ </div>
+ <div class="setting number">
+ <label for="sculpture-height">depth</label>
+ <input type="text" class="units" name="depth" id="sculpture-depth">
+ </div>
+ <div class="setting">
+ <a href="#" class="warn btn" data-role="destroy-sculpture">remove object</a>
+ </div>
+
+</div>
diff --git a/views/controls/editor/settings.ejs b/views/controls/editor/settings.ejs
index cd915c5..0ee00de 100644
--- a/views/controls/editor/settings.ejs
+++ b/views/controls/editor/settings.ejs
@@ -7,7 +7,7 @@
<div class="setting" id="startpoint">
<a href="#" class="modalLink">
- <span class="ion-ios7-navigate-outline"></span>
+ <span class="ion-ios-navigate-outline"></span>
<span id="startText">Set Startpoint</span>
<span id="moveText">Move to Desired Point <span class="done">done</span></span>
<span id="confirmText">Set Startpoint</span>
@@ -17,7 +17,7 @@
<div class="setting">
<a href="#" class="modalLink" data-role='show-collaborators'>
- <span class="ion-ios7-plus-outline"></span>
+ <span class="ion-ios-plus-outline"></span>
Add Collaborators
</a>
</div>
@@ -29,7 +29,7 @@
</a>
<a href="#" class="modalLink" data-role='view-project' style="margin-left: 40px;">
- <span class="ion-ios7-search-strong"></span>
+ <span class="ion-ios-search-strong"></span>
View project
</a>
diff --git a/views/controls/editor/toolbar.ejs b/views/controls/editor/toolbar.ejs
index 6960cbc..1a3e2d7 100644
--- a/views/controls/editor/toolbar.ejs
+++ b/views/controls/editor/toolbar.ejs
@@ -9,11 +9,11 @@
<span
data-role='open-media-viewer'
data-info="add media"
- class="ion-ios7-photos-outline"></span>
+ class="ion-ios-photos-outline"></span>
<span
data-role='toggle-presets'
data-info="preset styles"
- class="ion-ios7-briefcase-outline"></span>
+ class="ion-ios-briefcase-outline"></span>
<!--
<span
data-role='resize-media'
@@ -22,25 +22,25 @@
<span
data-role='destroy-media'
data-info="delete media"
- class="ion-ios7-trash-outline"></span>
+ class="ion-ios-trash-outline"></span>
-->
<span
data-role='toggle-wallpaper-panel'
data-info="add wallpaper"
- class="ion-ios7-keypad-outline"></span>
+ class="ion-ios-keypad-outline"></span>
<span
data-role='toggle-color-control'
data-info="edit room colors"
- class="ion-ios7-sunny-outline"></span>
+ class="ion-ios-sunny-outline"></span>
<span
data-role='toggle-text-editor'
data-info="add text to wall"
- class="ion-ios7-compose-outline"></span>
+ class="ion-ios-compose-outline"></span>
<!--
<span
data-role='toggle-map-view'
data-info="toggle map view"
- class="ion-ios7-world-outline"></span>
+ class="ion-ios-world-outline"></span>
-->
<span
data-role='toggle-project-settings'
diff --git a/views/controls/editor/wallpaper.ejs b/views/controls/editor/wallpaper.ejs
index 3168f1c..a53f462 100644
--- a/views/controls/editor/wallpaper.ejs
+++ b/views/controls/editor/wallpaper.ejs
@@ -19,7 +19,7 @@
<div class="wallpaperUpload toolButton">
<form>
- <span class="ion-ios7-upload-outline upload-icon"></span>
+ <span class="ion-ios-upload-outline upload-icon"></span>
<label>Upload</label>
<input type="file" accept="image/*" multiple>
</form>
diff --git a/views/controls/reader/about-room.ejs b/views/controls/reader/about-room.ejs
index 974fe0f..a9ef738 100644
--- a/views/controls/reader/about-room.ejs
+++ b/views/controls/reader/about-room.ejs
@@ -5,7 +5,7 @@
[[ if (authorpic) { ]]
<a href="[[- authorlink ]]" class="authorName"><div class="profilePic" style="background-image:url([[- authorpic ]])"></div></a>
[[ } else { ]]
- <a href="[[- authorlink ]]" class="authorName"><span class="ion-ios7-person-outline"></span></a>
+ <a href="[[- authorlink ]]" class="authorName"><span class="ion-ios-person-outline"></span></a>
[[ } ]]
<a href="[[- authorlink ]]" class="authorName">[[- author ]]</a>
</h1>
diff --git a/views/docs.ejs b/views/docs.ejs
index b3ead82..a1f081f 100644
--- a/views/docs.ejs
+++ b/views/docs.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="loading">
diff --git a/views/editor.ejs b/views/editor.ejs
index 656615c..08959a0 100755
--- a/views/editor.ejs
+++ b/views/editor.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="editing loading">
@@ -16,6 +16,7 @@
[[ include controls/builder/info ]]
[[ include controls/editor/media-drawer ]]
[[ include controls/editor/media-editor ]]
+ [[ include controls/editor/sculpture ]]
[[ include controls/editor/wallpaper ]]
[[ include controls/editor/color-control ]]
[[ include controls/editor/text-editor ]]
diff --git a/views/home.ejs b/views/home.ejs
index 36fc2fc..7edac4c 100755
--- a/views/home.ejs
+++ b/views/home.ejs
@@ -1,24 +1,12 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="loading">
<div class="rapper page home">
[[ include partials/header ]]
-
- <div class="hero" style="background-image:url(http://okfocus.s3.amazonaws.com/images/vvalls-video-still1.jpg)">
- <div class="holder">
- <span class="circle">
- <span class="videoTitle">Create 3D Rooms</span><br>
- <span class="ion-ios7-play"></span><br>
- <span class="videoTitle">Watch video.</span>
- </span>
- </div>
- </div>
-
- <h1>What's VValls For?</h1>
<div class="projectList about">
<div class="item">
@@ -57,20 +45,15 @@
<a href="/about/howto" class="greenbtn learn">Read Tutorial</a>
</div>
+ <h1>Sign Up</h1>
+
+ <div class="projectList about aboutintro">
+ </div>
+
<h1>Room Showcase</h1>
[[ include projects/list-projects ]]
-
- <div class="projectList about gopro">
-
- <span>
- <h3>Ready To Go Pro?</h3>
- Use VValls as part of your product, service, or marketing campaign.
- We offer many types of customizations, including automation of layouts, more elaborate floor plans, enhanced video, interactivity, and other features.
- <a href="mailto:info@vvalls.com?subject=VValls platform" class="greenbtn">Contact</a>
- </span>
- </div>
[[ include partials/confirm-modal ]]
[[ include projects/layouts-modal ]]
[[ include partials/sign-in ]]
@@ -78,7 +61,7 @@
</div>
<div class="videoModal">
-<span class="ion-ios7-close-empty"></span>
+<span class="ion-ios-close-empty"></span>
<div class="holder">
<div class="video" style="width: 960px; margin: 0 auto; height: 540px; overflow: hidden; position: relative;"><iframe frameborder="0" scrolling="no" seamless="seamless" webkitallowfullscreen="webkitAllowFullScreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowfullscreen" id="okplayer" src="http://player.vimeo.com/video/109947131?api=1&player_id=okplayer" width="960" height="540" style="width: 960px; height: 800px; margin-top: -130px;"></iframe></div>
</div>
diff --git a/views/modal.ejs b/views/modal.ejs
index 7ca869c..dfc5573 100644
--- a/views/modal.ejs
+++ b/views/modal.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="loading">
@@ -10,7 +10,7 @@
<div style="height: 70%; clear: both;" id="content"></div>
- [[ include partials/confirm-modal ]]
+ [[ include partials/confirm-modal ]]
[[ include partials/sign-in ]]
[[ include projects/layouts-modal ]]
[[ include projects/edit-project ]]
diff --git a/views/partials/edit-profile.ejs b/views/partials/edit-profile.ejs
index 5775ca5..5720bc8 100644
--- a/views/partials/edit-profile.ejs
+++ b/views/partials/edit-profile.ejs
@@ -83,7 +83,7 @@
</li>
</div>
<li class="buttons">
- <input id="saveForm" class="button_text" type="submit" value="Submit" />
+ <input id="saveForm" class="button_text" type="submit" value="Save Changes">
</li>
<div class="errors">
<div>There was a problem with your submission:</div>
diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs
new file mode 100644
index 0000000..f3c3589
--- /dev/null
+++ b/views/partials/edit-subscription.ejs
@@ -0,0 +1,78 @@
+<div class="mediaDrawer fixed animate editSubscription">
+ <span class="close">X</span>
+ <div id="form_container">
+ <form>
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <ul>
+ <li class="section_break">
+ <h3>Edit Subscription</h3>
+ </li>
+ <li class="freePlan">
+ You are currently using the free version of VValls. For access to all of VValls features,
+ consider upgrading to a paid plan.
+ <br><br>
+ <div class="planList"></div>
+ <br><br><br>
+ </li>
+ <li class="paidPlan">
+ <div class="currentPlanLevel">
+ Your current plan level is <span data-role="planName"></span>
+ </div>
+ <div class="planMenu">
+ <h3>Select desired plan:</h3>
+ <div>
+ <input type="radio" id="chooseBasicPlan" data-role="basicPlanInput" name="planRadio" value="basic">
+ <label for="chooseBasicPlan" data-role="basicPlanName"></label>
+ $<span data-role="basicPlanCost"></span>/<span data-role="billingInterval"></span>
+ </div>
+ <div>
+ <input type="radio" id="chooseProPlan" data-role="proPlanInput" name="planRadio" value="pro">
+ <label for="chooseProPlan" data-role="proPlanName"></label>
+ $<span data-role="proPlanCost"></span>/<span data-role="billingInterval"></span>
+ </div>
+ </div>
+ <table class="planInfo">
+ <tr class="planRow">
+ <th><span data-role="planName"></span></th>
+ <td></td>
+ <td></td>
+ <td>$<span data-role="planCost"></span>/<span data-role="billingInterval"></span></td>
+ </tr>
+ <tr class="basicLayoutRow">
+ <th>Basic layouts</th>
+ <td><input type="number" min="0" max="100" step="1" data-role="basicLayoutInput"><span data-role="basicLayoutQuantity"></span></td>
+ <td>each $<span data-role="basicLayoutCost"></span>/<span data-role="billingInterval"></span></td>
+ <td>$<span data-role="basicLayoutTotal"></span>/<span data-role="billingInterval"></span></td>
+ </tr>
+ <tr class="proLayoutRow">
+ <th>Pro layouts</th>
+ <td><input type="number" min="0" max="100" data-role="proLayoutInput"><span data-role="proLayoutQuantity"></span></td>
+ <td>each $<span data-role="proLayoutCost"></span>/<span data-role="billingInterval"></span></td>
+ <td>$<span data-role="proLayoutTotal"></span>/<span data-role="billingInterval"></span></td>
+ </tr>
+ <tr class="totalRow">
+ <td></td>
+ <td></td>
+ <th>Total</th>
+ <td>$<span data-role="planTotal"></span>/<span data-role="billingInterval"></span></td>
+ </tr>
+ </table>
+ <div class="billingMenu">
+ <button data-role="showEditMenu">Edit Your Plan</button><br>
+ <button data-role="cancelSubscription">Cancel your subscription</button>
+ </div>
+ <div class="editMenu">
+ <div class="fineprint">
+ Your credit card will be charged the difference of XXXX for this month.
+ Your subscription will renew at XXXX at the start of your next billing cycle.
+ We thank you for your support!
+ </div>
+ <button data-role="saveChanges">Save Subscription</button>
+ <button data-role="closeMenu">Cancel</button>
+ </div>
+ </li>
+ <div class="gear"><span class="ion-gear-a"></span></div>
+ </ul>
+ </form>
+ </div>
+</div>
diff --git a/views/partials/footer.ejs b/views/partials/footer.ejs
index e3c572f..c62f31e 100644
--- a/views/partials/footer.ejs
+++ b/views/partials/footer.ejs
@@ -2,7 +2,7 @@
[[ if (logged_in) { ]]
<span>
- signed in as &rarr;
+ signed in as
<a href="/profile/[[- user.username ]]"><b>[[- user.displayName ]]</b></a>
[[ if (user.isStaff) { ]]
<a href="/staff">Staff Area</a>
@@ -17,9 +17,5 @@
<a href="/about/howto">How To</a>
<a href="/about/terms">Terms</a>
<a href="/about/privacy">Privacy</a>
- <a href="mailto:hello@vvalls.com">Contact</a>
- <br><br>
- <span>©2014 Dot Dash 3, Inc.</span>
- <a href="http://okfoc.us/">Site by OKFocus</a>
</div>
diff --git a/views/partials/header.ejs b/views/partials/header.ejs
index ce5bab9..ce9ffae 100644
--- a/views/partials/header.ejs
+++ b/views/partials/header.ejs
@@ -64,6 +64,9 @@
[[ if (profile && String(user._id) == String(profile._id)) { ]]
<a href="/profile" data-role="edit-profile-modal" class="topLink editProfile">Settings</a>
+<!--
+ <a href="/profile" data-role="edit-subscription-modal" class="topLink editSubscription">Subscription</a>
+ -->
[[ } else if (! profile) { ]]
<a href="/profile" class="topLink profileLink">Profile</a>
[[ } ]]
@@ -77,4 +80,6 @@
<a href="/signin" data-role="show-signin-modal" class="signIn topLink">Sign In</a>
[[ } ]]
</span>
-</div> \ No newline at end of file
+</div>
+
+<span class="close" id="fixed_close">X</span> \ No newline at end of file
diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs
index fc94992..479fb0c 100644
--- a/views/partials/scripts.ejs
+++ b/views/partials/scripts.ejs
@@ -5,6 +5,7 @@
<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js"></script>
<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js"></script>
<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js"></script>
+<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
<!-- <script type="text/javascript" src="/assets/javascripts/vendor/bower_components/prefixfree/prefixfree.min.js"></script> -->
<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/marked/lib/marked.js"></script>
<script type="text/javascript" src="/assets/javascripts/vendor/tube.js"></script>
@@ -18,15 +19,21 @@
<script type="text/javascript" src="/assets/javascripts/util.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/mx.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/extensions/mx.movements.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/extensions/mx.movementsMobile.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.image.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.text.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.video.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.youtube.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.vimeo.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.soundcloud.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.grid.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.point.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.polyline.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/_env.js"></script>
@@ -64,6 +71,7 @@
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/move.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/resize.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/randomize.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/sound.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/undo.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/_object.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/audio.js"></script>
@@ -71,16 +79,38 @@
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/text.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/video.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/_sculpture.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/move.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/resize.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/types/_object.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/types/image.js"></script>
+
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/shapes/polyline.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/shapes/ortho.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/shapes/shapelist.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/shapes/regionlist.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui_editor.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui_minimap.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui/editor.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui/minimap.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui/ortho.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/_base.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/arrow.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/line.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/eraser.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/ortho.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/polyline.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/position.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/start.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/View.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/Router.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/ModalView.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/FormView.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/UploadView.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/lib/AnimatedView.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/lib/ToggleableView.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/AlertModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/ConfirmModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/ErrorModal.js"></script>
@@ -92,9 +122,12 @@
<script type="text/javascript" src="/assets/javascripts/ui/site/UsernameTaken.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/PasswordForgot.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/PasswordReset.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/site/LayoutsIndex.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/LayoutsModal.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/site/NewProjectModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/EditProjectModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/EditProfileModal.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/site/EditSubscriptionModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/DocumentModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/HomeView.js"></script>
@@ -106,6 +139,15 @@
<script type="text/javascript" src="/assets/javascripts/ui/builder/BuilderToolbar.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/builder/BuilderInfo.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintView.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintInfo.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintSettings.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintEditor.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintScaler.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintToolbar.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintUploader.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintNotice.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/ui/editor/EditorView.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/EditorSettings.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/EditorToolbar.js"></script>
@@ -117,6 +159,7 @@
<script type="text/javascript" src="/assets/javascripts/ui/editor/MediaUpload.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/MediaViewer.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/Presets.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/editor/SculptureEditor.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/TextEditor.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/WallpaperPicker.js"></script>
diff --git a/views/profile.ejs b/views/profile.ejs
index a62652c..d3ae10e 100644
--- a/views/profile.ejs
+++ b/views/profile.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls | [[- profile.displayName ]]</title>
[[ include partials/meta ]]
</head>
<body class="loading">
@@ -9,48 +9,53 @@
[[- include partials/header ]]
<div class="profilepage">
- [[ if (profile.photo && profile.photo.length) { ]]
- <div class="profilePic" style="background-image:url([[- profile.photo ]])">
- </div>
- [[ } else { ]]
- <div class="profilePic noPic">
- <span class="holder">
- <span class="ion-ios7-person-outline"></span>
- [[ if (isOwnProfile) { ]]
- <div>click to add profile pic</div>
- <input id="profile_avatar" name="avatar" class="element file" type="file">
- [[ } ]]
- </span>
- </div>
+ [[ if (profile.photo && profile.photo.length) { ]]
+ <div class="profilePic" style="background-image:url([[- profile.photo ]])">
+ </div>
+ [[ } else { ]]
+ <div class="profilePic noPic">
+ <span class="holder">
+ <span class="ion-ios-person-outline"></span>
+ [[ if (isOwnProfile) { ]]
+ <div>click to add profile pic</div>
+ <input id="profile_avatar" name="avatar" class="element file" type="file">
[[ } ]]
- <div class="bio">
- <div class="holder">
- <h2>[[- profile.displayName ]]</h2>
- [[ if (profile.location) { ]]
- <span>
- [[- profile.location ]]
- </span>
- [[ } ]]
- [[ if (profile.website && profile.website.length) { ]]
- <span>
- <a href="[[- profile.website ]]" target="_blank">[[- profile.website ]]</a>
- </span>
- [[ } ]]
- [[ if (profile.twitterName && profile.twitterName.length) { ]]
- <span>
- <a href="https://twitter.com/[[- profile.twitterName ]]" target="_blank">@[[- profile.twitterName ]]</a>
- </span>
- [[ } ]]
- </div>
- </div>
-
+ </span>
+ </div>
+ [[ } ]]
+ <div class="bio">
+ <div class="holder">
+ <h2>[[- profile.displayName ]]</h2>
+ [[ if (profile.location) { ]]
+ <span>
+ [[- profile.location ]]
+ </span>
+ [[ } ]]
+ [[ if (profile.website && profile.website.length) { ]]
+ <span>
+ <a href="[[- profile.website ]]" target="_blank">[[- profile.website ]]</a>
+ </span>
+ [[ } ]]
+ [[ if (profile.twitterName && profile.twitterName.length) { ]]
+ <span>
+ <a href="https://twitter.com/[[- profile.twitterName ]]" target="_blank">@[[- profile.twitterName ]]</a>
+ </span>
+ [[ } ]]
+ [[ if (profile.plan_level == 1) { ]]
+ <span class="plan_level premium">PREMIUM</span>
+ [[ } else if (profile.plan_level == 2) { ]]
+ <span class="plan_level pro">PRO</span>
+ [[ } ]]
+ </div>
+ </div>
[[ if (projects.length) { ]]
+
<h1>[[- profile.username ]] has [[- projectCount ]] project[[- projectCount != 1 ? "s" : "" ]]</h1>
-
[[ include projects/list-projects ]]
+
[[ } else { ]]
-
+
<h1>Welcome to VVALLS</h1>
<div class="projectList about">
<h2>
@@ -69,8 +74,13 @@
<h3>This person has no projects.</h3>
[[ } ]]
</div>
+
[[ } ]]
- </div>
+
+ </div>
+<!--
+ [[ include partials/edit-subscription ]]
+ -->
[[ include partials/edit-profile ]]
[[ include projects/layouts-modal ]]
[[ include projects/edit-project ]]
diff --git a/views/projects/layouts-modal.ejs b/views/projects/layouts-modal.ejs
index 6f60d81..0d648cd 100644
--- a/views/projects/layouts-modal.ejs
+++ b/views/projects/layouts-modal.ejs
@@ -7,7 +7,8 @@
<div class="templates-list">
</div>
<form>
- <input data-role="create-new-layout" class="button_text" type="submit" value="New Layout">
+ <input data-role="create-new-blueprint" class="button_text" type="submit" value="Trace a Blueprint">
+ <input data-role="create-new-layout" class="button_text" type="submit" value="Make a Standard Layout">
</form>
</div>
<div class="no-templates">
@@ -43,7 +44,9 @@
<div class="templates-list">
</div>
+
<form>
+ <input data-role="create-new-blueprint" class="button_text" type="submit" value="trace a blueprint">
<input data-role="create-new-layout" class="button_text" type="submit" value="or make your own template">
</form>
</div>
diff --git a/views/reader.ejs b/views/reader.ejs
index 6c9856a..7035356 100644
--- a/views/reader.ejs
+++ b/views/reader.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="loading reader">
diff --git a/views/staff/_blueprints.ejs b/views/staff/_blueprints.ejs
new file mode 100644
index 0000000..58fe2a3
--- /dev/null
+++ b/views/staff/_blueprints.ejs
@@ -0,0 +1,21 @@
+<table id="users">
+[[ blueprints.forEach(function(blueprint){ ]]
+ <tr>
+ <td>
+ <a href="/staff/blueprints/[[- blueprint.slug ]]">[[- blueprint.name ]]</a>
+ </td>
+ <td class="editLinks">
+ <a href="/blueprint/[[- blueprint.slug ]]">[view]</a>
+<!--
+ <a href="/api/rooms/[[- blueprint.slug ]]">[api]</a>
+ -->
+ </td>
+ <td>
+ <a href="/staff/users/[[- blueprint.user.username ]]">[[- blueprint.user.username ]]</a>
+ </td>
+ <td>
+ [[- blueprint.date ]]
+ </td>
+ </tr>
+[[ }) ]]
+</table>
diff --git a/views/staff/_header.ejs b/views/staff/_header.ejs
index 3bbf4f1..a73c12e 100644
--- a/views/staff/_header.ejs
+++ b/views/staff/_header.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls | staff</title>
+ <title>VValls | staff</title>
[[ include ../partials/meta ]]
<link rel="stylesheet" href="/assets/javascripts/vendor/bower_components/jquery-jsonview/dist/jquery.jsonview.css"></script>
<link rel="stylesheet" href="/assets/stylesheets/staff.css"></script>
diff --git a/views/staff/_layouts.ejs b/views/staff/_layouts.ejs
new file mode 100644
index 0000000..d97883b
--- /dev/null
+++ b/views/staff/_layouts.ejs
@@ -0,0 +1,22 @@
+<table id="users">
+[[ layouts.forEach(function(layout){ ]]
+ <tr>
+ <td>
+ <a href="/staff/layouts/[[- layout.slug ]]">[[- layout.name ]]</a>
+ </td>
+ <td class="editLinks">
+ <a href="/layout/[[- layout.slug ]]">[view]</a>
+ <a href="/layout/[[- layout.slug ]]/edit">[edit]</a>
+<!--
+ <a href="/api/rooms/[[- layout.slug ]]">[api]</a>
+ -->
+ </td>
+ <td>
+ <a href="/staff/users/[[- layout.user.username ]]">[[- layout.user.username ]]</a>
+ </td>
+ <td>
+ [[- layout.date ]]
+ </td>
+ </tr>
+[[ }) ]]
+</table>
diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs
new file mode 100644
index 0000000..702a374
--- /dev/null
+++ b/views/staff/_nav.ejs
@@ -0,0 +1,10 @@
+<nav>
+ <a href="/staff">home</a>
+ <a href="/staff/users">users</a>
+ <a href="/staff/projects">projects</a>
+ <a href="/staff/layouts">layouts</a>
+ <a href="/staff/blueprints">blueprints</a>
+ <a href="/staff/media">media</a>
+ <a href="/staff/plans">plans</a>
+<!-- <a href="/staff/subscriptions">subscriptions</a> -->
+</nav> \ No newline at end of file
diff --git a/views/staff/_pagination.ejs b/views/staff/_pagination.ejs
index 6c3bfb1..7d85c71 100644
--- a/views/staff/_pagination.ejs
+++ b/views/staff/_pagination.ejs
@@ -10,7 +10,7 @@
[[ if (pagination.next_page !== -1) { ]]
<a href="?[[- pagination.query ]]&offset=[[- pagination.next_page ]]">Next page &rarr;</a>
[[ } else { ]]
- &rarr;
+ ->
[[ } ]]
</div>
diff --git a/views/staff/_users.ejs b/views/staff/_users.ejs
index d46058f..ee988ab 100644
--- a/views/staff/_users.ejs
+++ b/views/staff/_users.ejs
@@ -1,3 +1,18 @@
+<nav class="subnav">
+ sort by <a href="?sort=date">join date</a> ... <a href="?sort=last_seen">recent</a> ... <a href="?sort=name">name</a> ... jump to a letter:
+ <span class="alphabet">
+ [[ "abcdefghijklmnopqrstuvwxyz?".split("").forEach(function(letter){ ]]
+ <a href="?sort=name&initial=[[- letter ]]">[[- letter.toUpperCase() ]]</a>
+ [[ }) ]]
+ </span>
+</nav>
+
+[[ if (! users.length || opt.error) { ]]
+<div class="error">
+ [[- opt.error ]]
+</div>
+[[ } ]]
+
<table id="users">
[[ users.forEach(function(user){ ]]
<tr>
@@ -5,6 +20,10 @@
<a href="/staff/users/[[- user.username ]]"><div style="background-image:url([[- user.photo ]])" class="avatar"></div></a>
</td>
<td>
+ [[- user.plan_type ]]
+ [[- user.last_charged ]]
+ </td>
+ <td>
<a href="/staff/users/[[- user.username ]]">[[- user.username ]]</a>
</td>
<td>
@@ -12,6 +31,8 @@
</td>
<td class="editLinks">
<a href="/profile/[[- user.username ]]">[view profile]</a>
+ <a href="/staff/users/[[- user.username ]]/media">[view media]</a>
+ <a href="https://vvalls.recurly.com/accounts/[[- user._id ]]">[recurly]</a>
</td>
<td>
[[- user.last_seen ]]
diff --git a/views/staff/blueprints/index.ejs b/views/staff/blueprints/index.ejs
new file mode 100644
index 0000000..2206a1c
--- /dev/null
+++ b/views/staff/blueprints/index.ejs
@@ -0,0 +1,13 @@
+[[ include ../_header ]]
+
+ <h1>Blueprints</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_pagination ]]
+[[ include ../_blueprints ]]
+[[ include ../_pagination ]]
+
+[[ include ../_footer ]]
diff --git a/views/staff/blueprints/show.ejs b/views/staff/blueprints/show.ejs
new file mode 100644
index 0000000..5fd9db6
--- /dev/null
+++ b/views/staff/blueprints/show.ejs
@@ -0,0 +1,59 @@
+[[ include ../_header ]]
+
+ <h1>[[- blueprint.name ]]</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+ <table>
+ <tr>
+ <td>
+ <a href="/staff/blueprints/[[- blueprint.slug ]]">[[- blueprint.name ]]</a>
+ </td>
+ <td class="editLinks">
+ <a href="/blueprint/[[- blueprint.slug ]]">[view]</a>
+ <a href="/blueprint/[[- blueprint.slug ]]/edit">[edit]</a>
+<!--
+ <a href="/api/rooms/[[- blueprint.slug ]]">[api]</a>
+ -->
+ </td>
+ <td>
+ [[- blueprint.date ]]
+ </td>
+ </tr>
+ <tr>
+ <td>
+ [[ if (blueprintUser.photo) { ]]
+ <a href="/staff/users/[[- blueprintUser.username ]]"><div style="background-image:url([[- blueprintUser.photo ]])" class="avatar"></div></a>
+ [[ } ]]
+ <a href="/staff/users/[[- blueprintUser.username ]]">[[- blueprintUser.username ]]</a>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="999">
+ <img src="[[- blueprint.url ]]" style="max-width: 400px">
+ </td>
+ </tr>
+ <tr>
+ <td>Width</td>
+ <td>[[- blueprint.width ]]</td>
+ </tr>
+ <tr>
+ <td>Height</td>
+ <td>[[- blueprint.height ]]</td>
+ </tr>
+ <tr>
+ <td>Scale</td>
+ <td>[[- blueprint.scale ]]</td>
+ </tr>
+ </table>
+
+ <br><br>
+ <div id="actions">
+ </div>
+
+ <br>
+ <br>
+
+[[ include ../_footer ]]
diff --git a/views/staff/blueprints/show_404.ejs b/views/staff/blueprints/show_404.ejs
new file mode 100644
index 0000000..0ffca86
--- /dev/null
+++ b/views/staff/blueprints/show_404.ejs
@@ -0,0 +1,9 @@
+[[ include ../_header ]]
+
+ <h1>Blueprint not found</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_footer ]]
diff --git a/views/staff/index.ejs b/views/staff/index.ejs
index 5ca7269..1b73641 100644
--- a/views/staff/index.ejs
+++ b/views/staff/index.ejs
@@ -2,11 +2,7 @@
<h1>Staff Area</h1>
- <nav>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+ [[ include _nav ]]
<hr>
diff --git a/views/staff/layouts/index.ejs b/views/staff/layouts/index.ejs
new file mode 100644
index 0000000..71f5dc7
--- /dev/null
+++ b/views/staff/layouts/index.ejs
@@ -0,0 +1,13 @@
+[[ include ../_header ]]
+
+ <h1>Layouts</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_pagination ]]
+[[ include ../_layouts ]]
+[[ include ../_pagination ]]
+
+[[ include ../_footer ]]
diff --git a/views/staff/layouts/show.ejs b/views/staff/layouts/show.ejs
new file mode 100644
index 0000000..2742c1f
--- /dev/null
+++ b/views/staff/layouts/show.ejs
@@ -0,0 +1,61 @@
+[[ include ../_header ]]
+
+ <h1>[[- layout.name ]]</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+ <table>
+ <tr>
+ <td>
+ <a href="/staff/layouts/[[- layout.slug ]]">[[- layout.name ]]</a>
+ </td>
+ <td class="editLinks">
+ <a href="/layout/[[- layout.slug ]]">[view]</a>
+ <a href="/layout/[[- layout.slug ]]/edit">[edit]</a>
+<!--
+ <a href="/api/rooms/[[- layout.slug ]]">[api]</a>
+ -->
+ </td>
+ <td>
+ [[- layout.date ]]
+ </td>
+<!--
+ <td>
+ [[- layout.privacy ? "private" : "" ]]
+ </td>
+ -->
+ </tr>
+ <tr>
+ <td>
+ [[ if (layoutUser.photo) { ]]
+ <a href="/staff/users/[[- layoutUser.username ]]"><div style="background-image:url([[- layoutUser.photo ]])" class="avatar"></div></a>
+ [[ } ]]
+ <a href="/staff/users/[[- layoutUser.username ]]">[[- layoutUser.username ]]</a>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="999" class="description">
+ "[[- layout.description ]]"
+ </td>
+ </tr>
+ <tr>
+ <th>
+ stock layout?
+ </th>
+ <td id="isStockLayout">
+ [[- layout.is_stock ? "yes" : "no" ]]
+ </td>
+ </tr>
+ </table>
+
+ <br><br>
+ <div id="actions">
+ <button id="toggle-stock" data-stock="[[- !! (layout.is_stock) ]]">Make this layout Stock</button>
+ </div>
+
+ <br>
+ <br>
+
+[[ include ../_footer ]]
diff --git a/views/staff/layouts/show_404.ejs b/views/staff/layouts/show_404.ejs
new file mode 100644
index 0000000..5d24aa8
--- /dev/null
+++ b/views/staff/layouts/show_404.ejs
@@ -0,0 +1,9 @@
+[[ include ../_header ]]
+
+ <h1>Layout not found</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_footer ]]
diff --git a/views/staff/media/index.ejs b/views/staff/media/index.ejs
index 516af2d..3805c8e 100644
--- a/views/staff/media/index.ejs
+++ b/views/staff/media/index.ejs
@@ -2,12 +2,7 @@
<h1>Media</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/media/show.ejs b/views/staff/media/show.ejs
index 76dcd32..9d05cb9 100644
--- a/views/staff/media/show.ejs
+++ b/views/staff/media/show.ejs
@@ -2,12 +2,7 @@
<h1>Media: [[- media.type ]]</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/media/show_404.ejs b/views/staff/media/show_404.ejs
index f07cef2..c6bac6f 100644
--- a/views/staff/media/show_404.ejs
+++ b/views/staff/media/show_404.ejs
@@ -2,13 +2,8 @@
<h1>Media not found</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
-
+[[ include ../_nav ]]
+
<hr>
[[ include ../_footer ]]
diff --git a/views/staff/plans/_form.ejs b/views/staff/plans/_form.ejs
new file mode 100644
index 0000000..85375fa
--- /dev/null
+++ b/views/staff/plans/_form.ejs
@@ -0,0 +1,154 @@
+<input type="hidden" id="_csrf" name="_csrf" value="[[- token ]]">
+
+<ul>
+
+<li class="section_break">
+ <h3>New Plan</h3>
+</li>
+
+<li>
+ <label for="plan_name">Name</label>
+ <div><input id="plan_name" name="name" type="text" value="[[- plan.name ]]"></div>
+</li>
+
+<li>
+ <label for="plan_slug">Slug</label>
+ <div><input id="plan_slug" name="slug" type="text" value="[[- plan.slug ]]"></div>
+</li>
+
+<li>
+ <label for="plan_level">Level</label>
+ <div><input id="plan_level" name="level" type="number" min="0" value="[[- plan.level ]]"></div>
+</li>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Plan Pricing</h3>
+</li>
+
+<li>
+ <label for="plan_monthly_price">Monthly Price</label>
+ <div><input id="plan_monthly_price" name="monthly_price" type="number" min="0" value="[[- plan.monthly_price ]]"></div>
+</li>
+
+<li>
+ <label for="plan_yearly_price">Yearly Price</label>
+ <div><input id="plan_yearly_price" name="yearly_price" type="number" min="0" value="[[- plan.yearly_price ]]"></div>
+</li>
+
+<p>
+ <i>Note:</i> Pricing should be in cents, i.e. a price of $10.00 should be entered as 1000.
+</p>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Additional Template Pricing</h3>
+</li>
+
+<li>
+ <label for="plan_basic_layout_monthly_price">Basic Template Price (Monthly)</label>
+ <div><input id="plan_basic_layout_monthly_price" name="basic_layout_monthly_price" type="number" min="0" value="[[- plan.basic_layout_monthly_price ]]"></div>
+</li>
+
+<li>
+ <label for="plan_basic_layout_yearly_price">Basic Template Price (Yearly)</label>
+ <div><input id="plan_basic_layout_yearly_price" name="basic_layout_yearly_price" type="number" min="0" value="[[- plan.basic_layout_yearly_price ]]"></div>
+</li>
+
+<li>
+ <label for="plan_pro_layout_monthly_price">Pro Template Price (Monthly)</label>
+ <div><input id="plan_pro_layout_monthly_price" name="pro_layout_monthly_price" type="number" min="0" value="[[- plan.pro_layout_monthly_price ]]"></div>
+</li>
+
+<li>
+ <label for="plan_pro_layout_yearly_price">Pro Template Price (Yearly)</label>
+ <div><input id="plan_pro_layout_yearly_price" name="pro_layout_yearly_price" type="number" min="0" value="[[- plan.pro_layout_yearly_price ]]"></div>
+</li>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Per-Plan Template Limits</h3>
+</li>
+
+<li>
+ <label for="plan_basic_layout_limit">Basic Template Limit</label>
+ <div><input id="plan_basic_layout_limit" name="basic_layout_limit" type="number" min="0" value="[[- plan.basic_layout_limit ]]"></div>
+</li>
+
+<li>
+ <label for="plan_pro_layout_limit">Pro Template Limit</label>
+ <div><input id="plan_pro_layout_limit" name="pro_layout_limit" type="number" min="0" value="[[- plan.pro_layout_limit ]]"></div>
+</li>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Per-Plan Project Limits</h3>
+</li>
+
+<li>
+ <label for="plan_stock_project_limit">Stock Project Limit</label>
+ <div><input id="plan_stock_project_limit" name="stock_project_limit" type="number" min="0" value="[[- plan.stock_project_limit ]]"></div>
+</li>
+
+<li>
+ <label for="plan_basic_project_limit">Basic Project Limit</label>
+ <div><input id="plan_basic_project_limit" name="basic_project_limit" type="number" min="0" value="[[- plan.basic_project_limit ]]"></div>
+</li>
+
+<li>
+ <label for="plan_pro_project_limit">Pro Project Limit</label>
+ <div><input id="plan_pro_project_limit" name="pro_project_limit" type="number" min="0" value="[[- plan.pro_project_limit ]]"></div>
+</li>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Permissions</h3>
+</li>
+
+<div>
+<li>
+ <input name="permissions_basic_editor" type="hidden" value="0">
+ <input id="plan_permissions_basic_editor" name="permissions_basic_editor" type="checkbox" value="1" [[ if (plan.permissions.basic_editor) { ]]checked[[ } ]]>
+ <label for="plan_permissions_basic_editor">Basic Editor</label>
+</li>
+
+<li>
+ <input name="permissions_pro_editor" type="hidden" value="0">
+ <input id="plan_permissions_pro_editor" name="permissions_pro_editor" type="checkbox" value="1" [[ if (plan.permissions.pro_editor) { ]]checked[[ } ]]>
+ <label for="plan_permissions_pro_editor">Pro Editor</label>
+</li>
+
+<li>
+ <input name="permissions_sculpture" type="hidden" value="0">
+ <input id="plan_permissions_sculpture" name="permissions_sculpture" type="checkbox" value="1" [[ if (plan.permissions.sculpture) { ]]checked[[ } ]]>
+ <label for="plan_permissions_sculpture">3D Objects</label>
+</li>
+
+<li>
+ <input name="permissions_collaborators" type="hidden" value="0">
+ <input id="plan_permissions_collaborators" name="permissions_collaborators" type="checkbox" value="1" [[ if (plan.permissions.collaborators) { ]]checked[[ } ]]>
+ <label for="plan_permissions_collaborators">Collaborators</label>
+</li>
+
+<li>
+ <input name="permissions_no_logo" type="hidden" value="0">
+ <input id="plan_permissions_no_logo" name="permissions_no_logo" type="checkbox" value="1" [[ if (plan.permissions.no_logo) { ]]checked[[ } ]]>
+ <label for="plan_permissions_no_logo">No Logo</label>
+</li>
+
+<p>
+ These permissions should harmonize with the restrictions on layouts set above.
+</p>
+
+</div>
+
+<li>
+ <input type="submit" value="Save Changes">
+</li>
+
+</ul>
diff --git a/views/staff/plans/edit.ejs b/views/staff/plans/edit.ejs
new file mode 100644
index 0000000..9848873
--- /dev/null
+++ b/views/staff/plans/edit.ejs
@@ -0,0 +1,13 @@
+[[ include ../_header ]]
+
+ <h1>Edit Plan</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+<form action="" method="post">
+[[- include _form ]]
+</form>
+
+[[ include ../_footer ]]
diff --git a/views/staff/plans/index.ejs b/views/staff/plans/index.ejs
new file mode 100644
index 0000000..16fcf14
--- /dev/null
+++ b/views/staff/plans/index.ejs
@@ -0,0 +1,65 @@
+[[ include ../_header ]]
+
+ <h1>Plans</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+<table>
+ <tr>
+ <td>
+ </td>
+ [[ plans.forEach(function(plan){ ]]
+ <td style="text-align:right; min-width: 100px;">
+ <b style="text-transform:uppercase">[[- plan.name ]]</b>
+ </td>
+ [[ }) ]]
+ </tr>
+
+ <tr class="editLinks">
+ <td>
+ <a href="/staff/plans/new">New Plan</a>
+ </td>
+ [[ plans.forEach(function(plan){ ]]
+ <td style="text-align:right">
+ [<a href="/staff/plans/[[- plan.slug ]]">edit</a>]
+ </td>
+ [[ }) ]]
+ </tr>
+
+ [[ fields.forEach(function(field){ ]]
+ <tr>
+ <td style="text-transform:capitalize">[[- field.replace(/_/g," ") ]]</td>
+ [[ plans.forEach(function(plan){ ]]
+ <td style="text-align:right">
+ [[ if (field.indexOf("_price") != -1) { ]]
+ [[- plan[field] == 0 ? "" : "$" + (plan[field]/100).toFixed(2) ]]
+ [[ } else { ]]
+ [[- plan[field] ]]
+ [[ } ]]
+ </td>
+ [[ }) ]]
+ </tr>
+ [[ }) ]]
+
+ <tr>
+ <td style="border-bottom: 1px dotted #888;" colspan='10'></td>
+ </tr>
+
+ [[ permissions.forEach(function(permission){ ]]
+ <tr>
+ <td style="text-transform:capitalize">[[- permission.replace(/_/g," ") ]]</td>
+ [[ plans.forEach(function(plan){ ]]
+ <td style="text-align:right">
+ [[- plan.permissions[permission] ? "<b>x</b>" : " " ]]
+ </td>
+ [[ }) ]]
+ </tr>
+ [[ }) ]]
+</table>
+<br clear="all">
+
+ <hr>
+
+[[ include ../_footer ]]
diff --git a/views/staff/plans/new.ejs b/views/staff/plans/new.ejs
new file mode 100644
index 0000000..297d3d6
--- /dev/null
+++ b/views/staff/plans/new.ejs
@@ -0,0 +1,13 @@
+[[ include ../_header ]]
+
+ <h1>New Plan</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+<form action="" method="post">
+[[- include _form ]]
+</form>
+
+[[ include ../_footer ]]
diff --git a/views/staff/projects/index.ejs b/views/staff/projects/index.ejs
index 482ea25..e4ba469 100644
--- a/views/staff/projects/index.ejs
+++ b/views/staff/projects/index.ejs
@@ -2,12 +2,7 @@
<h1>Projects</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/projects/show.ejs b/views/staff/projects/show.ejs
index 1034b31..b090a41 100644
--- a/views/staff/projects/show.ejs
+++ b/views/staff/projects/show.ejs
@@ -2,13 +2,8 @@
<h1>[[- project.name ]]</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
-
+[[ include ../_nav ]]
+
<hr>
<table>
diff --git a/views/staff/projects/show_404.ejs b/views/staff/projects/show_404.ejs
index 70320c0..f5e1658 100644
--- a/views/staff/projects/show_404.ejs
+++ b/views/staff/projects/show_404.ejs
@@ -2,12 +2,7 @@
<h1>Project not found</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/subscriptions/index.ejs b/views/staff/subscriptions/index.ejs
new file mode 100644
index 0000000..adf148c
--- /dev/null
+++ b/views/staff/subscriptions/index.ejs
@@ -0,0 +1,39 @@
+[[ include ../_header ]]
+
+ <h1>Subscriptions</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_pagination ]]
+
+<table id="users">
+[[ subscriptions.forEach(function(subscription){ ]]
+ <tr>
+ <td>
+ <a href="/staff/subscriptions/[[- subscription._id ]]"><div style="background-image:url([[- subscription.user.photo ]])" class="avatar"></div></a>
+ </td>
+ <td>
+ <a href="/staff/subscriptions/[[- subscription._id ]]">[[- subscription.user.username ]]</a>
+ </td>
+ <td>
+ [[- subscription.user.displayName ]]
+ </td>
+ <td class="editLinks">
+ <a href="/profile/[[- user.username ]]">[view profile]</a>
+ </td>
+ <td>
+ [[- subscription.user.last_seen ]]
+ </td>
+ <td>
+ [[- subscription.plan_code ]]
+ </td>
+ </tr>
+[[ }) ]]
+</table>
+
+
+[[ include ../_pagination ]]
+
+[[ include ../_footer ]]
diff --git a/views/staff/subscriptions/show.ejs b/views/staff/subscriptions/show.ejs
new file mode 100644
index 0000000..e2839a6
--- /dev/null
+++ b/views/staff/subscriptions/show.ejs
@@ -0,0 +1,12 @@
+[[ include ../_header ]]
+ <h1>User: [[- subscription.user.username ]]</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+<pre>
+info to show..
+- link to recurly profile
+- link to vvalls profile
+- subscription tier + add-ons
diff --git a/views/staff/users/index.ejs b/views/staff/users/index.ejs
index f14d666..1795dde 100644
--- a/views/staff/users/index.ejs
+++ b/views/staff/users/index.ejs
@@ -2,12 +2,7 @@
<h1>Users</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/users/media.ejs b/views/staff/users/media.ejs
index c1097dd..8927c00 100644
--- a/views/staff/users/media.ejs
+++ b/views/staff/users/media.ejs
@@ -1,15 +1,10 @@
[[ include ../_header ]]
- <h1>User Media: [[- profile.username ]]</h1>
+<h1>User Media: [[- profile.username ]]</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
-
- <hr>
+[[ include ../_nav ]]
+
+<hr>
[[ include ../_pagination ]]
[[ include ../_gallery ]]
diff --git a/views/staff/users/show.ejs b/views/staff/users/show.ejs
index 8e9b447..a434b57 100644
--- a/views/staff/users/show.ejs
+++ b/views/staff/users/show.ejs
@@ -1,12 +1,7 @@
[[ include ../_header ]]
<h1>User: [[- profile.username ]]</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
@@ -22,12 +17,38 @@
[[- profile.displayName ]]
</td>
<td class="editLinks">
- <a href="/profile/[[- profile.username ]]">[view profile]</a>
- <a href="/staff/users/[[- profile.username ]]/media">[view media]</a>
+ <a href="/profile/[[- profile.username ]]">[profile]</a>
+ <a href="/staff/users/[[- profile.username ]]/media">[media]</a>
+ [[ if (profile.subscription) { ]]
+ <a href="https://vvalls.recurly.com/accounts/[[- profile._id ]]">[recurly]</a>
+ [[ } ]]
</td>
</tr>
</table>
+
+ [[ if (profile.subscription) { ]]
+ <h2>Subscription</h2>
+ <table>
+ <tr>
+ <th>
+ plan
+ </th>
+ <td>
+ [[- profile.plan_code ]]
+ </td>
+ </tr>
+ <tr>
+ <th>
+ last charged
+ </th>
+ <td>
+ [[- profile.last_charged ]]
+ </td>
+ </tr>
+ </table>
+ [[ } ]]
+
<h2>Profile</h2>
<table>
@@ -80,12 +101,21 @@
[[- profile.isStaff ? "yes" : "no" ]]
</td>
</tr>
+ <tr>
+ <th>
+ is artist?
+ </th>
+ <td id="is-artist">
+ [[- profile.isArtist ? "yes" : "no" ]]
+ </td>
+ </tr>
</table>
<br><br>
<div id="actions">
[[ if (String(user._id) != String(profile._id)) { ]]
<button id="toggle-staff" data-isStaff="[[- !! profile.isStaff ]]">Make Staff</button>
+ <button id="toggle-artist" data-isArtist="[[- !! profile.isArtist ]]">Make Artist</button>
[[ } ]]
</div>
diff --git a/views/staff/users/show_404.ejs b/views/staff/users/show_404.ejs
index bcd0271..11663fa 100644
--- a/views/staff/users/show_404.ejs
+++ b/views/staff/users/show_404.ejs
@@ -1,13 +1,9 @@
[[ include ../_header ]]
- <h1>User not found</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
-
- <hr>
+<h1>User not found</h1>
+
+[[ include ../_nav ]]
+
+<hr>
[[ include ../_footer ]]