├── log
└── .gitkeep
├── public
└── root
│ ├── robots.txt
│ ├── favicon.ico
│ └── snippet.png
├── assets
├── vendor
│ ├── bootstrap
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── js
│ │ │ │ ├── .jshintrc
│ │ │ │ ├── bootstrap-transition.js
│ │ │ │ ├── bootstrap-alert.js
│ │ │ │ ├── bootstrap-button.js
│ │ │ │ └── bootstrap-popover.js
│ │ │ └── less
│ │ │ │ ├── layouts.less
│ │ │ │ ├── component-animations.less
│ │ │ │ ├── utilities.less
│ │ │ │ ├── breadcrumbs.less
│ │ │ │ ├── grid.less
│ │ │ │ ├── hero-unit.less
│ │ │ │ ├── responsive-768px-979px.less
│ │ │ │ ├── wells.less
│ │ │ │ ├── responsive-1200px-min.less
│ │ │ │ ├── close.less
│ │ │ │ ├── accordion.less
│ │ │ │ ├── pager.less
│ │ │ │ ├── scaffolding.less
│ │ │ │ ├── responsive.less
│ │ │ │ ├── responsive-utilities.less
│ │ │ │ ├── thumbnails.less
│ │ │ │ ├── alerts.less
│ │ │ │ ├── code.less
│ │ │ │ ├── pagination.less
│ │ │ │ ├── bootstrap.less
│ │ │ │ ├── tooltip.less
│ │ │ │ ├── labels-badges.less
│ │ │ │ ├── modals.less
│ │ │ │ ├── carousel.less
│ │ │ │ ├── progress-bars.less
│ │ │ │ ├── reset.less
│ │ │ │ └── popovers.less
│ │ ├── bootstrap.js
│ │ ├── bootstrap-responsive.less
│ │ ├── bootstrap.less
│ │ └── var_override.less
│ ├── fontello
│ │ ├── src
│ │ │ ├── font
│ │ │ │ ├── icons.eot
│ │ │ │ ├── icons.ttf
│ │ │ │ ├── icons.woff
│ │ │ │ └── icons.svg
│ │ │ ├── css
│ │ │ │ ├── icons-codes.css
│ │ │ │ ├── icons-ie7-codes.css
│ │ │ │ ├── icons-ie7.css
│ │ │ │ └── icons.css
│ │ │ ├── LICENSE.txt
│ │ │ ├── config.json
│ │ │ └── README.txt
│ │ └── icons.css.ejs
│ ├── jquery-ui
│ │ ├── README.md
│ │ └── images
│ │ │ ├── ui-icons_222222_256x240.png
│ │ │ ├── ui-icons_2e83ff_256x240.png
│ │ │ ├── ui-icons_454545_256x240.png
│ │ │ ├── ui-icons_888888_256x240.png
│ │ │ ├── ui-icons_cd0a0a_256x240.png
│ │ │ ├── ui-icons_f6cf3b_256x240.png
│ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png
│ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png
│ │ │ ├── ui-bg_glass_65_ffffff_1x400.png
│ │ │ ├── ui-bg_glass_75_dadada_1x400.png
│ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png
│ │ │ ├── ui-bg_glass_75_ffffff_1x400.png
│ │ │ ├── ui-bg_inset-soft_95_fef1ec_1x100.png
│ │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png
│ ├── jquery.noty
│ │ ├── noty.css
│ │ └── src
│ │ │ └── css
│ │ │ └── jquery.noty.css
│ └── jade
│ │ └── runtime.js
├── embedded_fonts
│ ├── entypo.eot
│ ├── entypo.ttf
│ ├── iconic.eot
│ ├── iconic.ttf
│ ├── brandico.eot
│ ├── brandico.ttf
│ ├── entypo.woff
│ ├── fontello.eot
│ ├── fontello.ttf
│ ├── iconic.woff
│ ├── typicons.eot
│ ├── typicons.ttf
│ ├── brandico.woff
│ ├── fontawesome.eot
│ ├── fontawesome.ttf
│ ├── fontello.woff
│ ├── modernpics.eot
│ ├── modernpics.ttf
│ ├── modernpics.woff
│ ├── typicons.woff
│ ├── websymbols.eot
│ ├── websymbols.ttf
│ ├── websymbols.woff
│ ├── fontawesome.woff
│ ├── fontface-fontello.css.ejs
│ └── fontface-embedded.css.ejs
├── javascripts
│ ├── app.js
│ ├── loader.js.ejs
│ └── nodeca.js.ejs
└── stylesheets
│ ├── ui
│ ├── tabs.styl
│ ├── panes
│ │ ├── preview.styl
│ │ ├── codes_editor.styl
│ │ └── selector.styl
│ └── toolbar.styl
│ ├── variables.styl
│ ├── bootstrap_override.styl
│ └── app.styl
├── views
├── errors
│ ├── read-config.jade
│ ├── fatal.jade
│ ├── version-mismatch.jade
│ ├── no-file-reader.jade
│ └── max-glyphs.jade
├── preview
│ └── glyph.jade
├── result
│ └── download-banner.jade
├── code-editor
│ └── glyph.jade
├── selector
│ ├── font-item.jade
│ └── font-info.jade
└── app.jade
├── config
├── production.yml
├── router.yml
├── application.yml
└── logger.yml
├── .jshintignore
├── .gitignore
├── support
├── font-templates
│ ├── css
│ │ ├── css-ie7-codes.jade
│ │ ├── css-codes.jade
│ │ ├── css-ie7.jade
│ │ └── css.jade
│ ├── LICENSE.jade
│ ├── demo.jade
│ └── README.txt
└── forever.sh
├── lib
├── filters.js
├── init
│ ├── server
│ │ ├── http
│ │ │ └── compression.js
│ │ └── http.js
│ ├── assets
│ │ ├── build_i18n_files.js
│ │ ├── compile_views.js
│ │ ├── mincer.js
│ │ ├── mincer
│ │ │ ├── manifest.js
│ │ │ ├── stylus
│ │ │ │ └── import-dir.js
│ │ │ └── environment.js
│ │ └── build_api_tree.js
│ ├── assets.js
│ ├── cronjob.js
│ └── server.js
├── filters
│ ├── renderer
│ │ └── helpers.js
│ ├── fix_vhost.js
│ └── renderer.js
├── stats.js
├── stylus
│ └── import-dir.js
└── env.js
├── etc
├── init
│ └── fontello.conf
└── certs
│ ├── fontello-dev.cert
│ └── fontello-dev.key
├── DEV-NOTES.md
├── client
├── models
│ ├── source_font.js
│ ├── font.js
│ └── glyph.js
├── ui
│ ├── panes
│ │ ├── selector.js
│ │ ├── codes_editor.js
│ │ ├── preview.js
│ │ ├── selector_glyph.js
│ │ ├── preview_glyph.js
│ │ ├── selector_font.js
│ │ └── codes_editor_glyph.js
│ ├── tabs.js
│ └── toolbar.js
├── util.js
├── init.js
└── render.js
├── cli
├── server.js
└── font_config.js
├── shared
├── getByPath.js
└── render.js
├── .gitmodules
├── server
├── app.js
├── assets.js
└── static.js
├── LICENSE
├── INSTALL.md
├── fontello.js
├── package.json
├── bin
├── tpl-render.js
├── font_copy_to_assets.py
├── build_embedded_fonts_css.py
├── build_common_font.py
└── generate_font.sh
├── HISTORY.md
└── README.md
/log/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/root/robots.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/README.md:
--------------------------------------------------------------------------------
1 | To update - just refresh files in `./src` fonder.
2 |
--------------------------------------------------------------------------------
/views/errors/read-config.jade:
--------------------------------------------------------------------------------
1 | | Failed read your config file: #{self.error}.
2 |
--------------------------------------------------------------------------------
/config/production.yml:
--------------------------------------------------------------------------------
1 | ^production:
2 | listen:
3 | host: fontello.com
4 | port: 80
5 |
--------------------------------------------------------------------------------
/public/root/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/public/root/favicon.ico
--------------------------------------------------------------------------------
/public/root/snippet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/public/root/snippet.png
--------------------------------------------------------------------------------
/assets/embedded_fonts/entypo.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/entypo.eot
--------------------------------------------------------------------------------
/assets/embedded_fonts/entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/entypo.ttf
--------------------------------------------------------------------------------
/assets/embedded_fonts/iconic.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/iconic.eot
--------------------------------------------------------------------------------
/assets/embedded_fonts/iconic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/iconic.ttf
--------------------------------------------------------------------------------
/views/preview/glyph.jade:
--------------------------------------------------------------------------------
1 | span.font-fontello.icon #{self.chr}
2 | span.prefix icon-
3 | span.glyph-name #{self.css}
4 |
--------------------------------------------------------------------------------
/assets/embedded_fonts/brandico.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/brandico.eot
--------------------------------------------------------------------------------
/assets/embedded_fonts/brandico.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/brandico.ttf
--------------------------------------------------------------------------------
/assets/embedded_fonts/entypo.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/entypo.woff
--------------------------------------------------------------------------------
/assets/embedded_fonts/fontello.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/fontello.eot
--------------------------------------------------------------------------------
/assets/embedded_fonts/fontello.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/fontello.ttf
--------------------------------------------------------------------------------
/assets/embedded_fonts/iconic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/iconic.woff
--------------------------------------------------------------------------------
/assets/embedded_fonts/typicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/typicons.eot
--------------------------------------------------------------------------------
/assets/embedded_fonts/typicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/typicons.ttf
--------------------------------------------------------------------------------
/assets/embedded_fonts/brandico.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/brandico.woff
--------------------------------------------------------------------------------
/assets/embedded_fonts/fontawesome.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/fontawesome.eot
--------------------------------------------------------------------------------
/assets/embedded_fonts/fontawesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/fontawesome.ttf
--------------------------------------------------------------------------------
/assets/embedded_fonts/fontello.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/fontello.woff
--------------------------------------------------------------------------------
/assets/embedded_fonts/modernpics.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/modernpics.eot
--------------------------------------------------------------------------------
/assets/embedded_fonts/modernpics.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/modernpics.ttf
--------------------------------------------------------------------------------
/assets/embedded_fonts/modernpics.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/modernpics.woff
--------------------------------------------------------------------------------
/assets/embedded_fonts/typicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/typicons.woff
--------------------------------------------------------------------------------
/assets/embedded_fonts/websymbols.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/websymbols.eot
--------------------------------------------------------------------------------
/assets/embedded_fonts/websymbols.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/websymbols.ttf
--------------------------------------------------------------------------------
/assets/embedded_fonts/websymbols.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/websymbols.woff
--------------------------------------------------------------------------------
/assets/embedded_fonts/fontawesome.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/embedded_fonts/fontawesome.woff
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/font/icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/fontello/src/font/icons.eot
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/font/icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/fontello/src/font/icons.ttf
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/font/icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/fontello/src/font/icons.woff
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/README.md:
--------------------------------------------------------------------------------
1 | custom jquery-ui. contains only:
2 |
3 | - core
4 | - widget
5 | - mouse
6 | - selectable
7 | - slider
8 |
--------------------------------------------------------------------------------
/views/errors/fatal.jade:
--------------------------------------------------------------------------------
1 | | Internal error happened during processing your request:
2 | | "#{self.error}". Please, try again later.
3 |
--------------------------------------------------------------------------------
/views/errors/version-mismatch.jade:
--------------------------------------------------------------------------------
1 | | Application is outdated. Please
2 | | reload
3 | | the page.
4 |
--------------------------------------------------------------------------------
/.jshintignore:
--------------------------------------------------------------------------------
1 | .git/
2 | doc/
3 | node_modules/
4 | tmp/
5 | bin/
6 | fonts/
7 | assets/vendor/
8 | assets/embedded_fonts/
9 | public/
10 | src/
11 | support/
12 |
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-icons_2e83ff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-icons_2e83ff_256x240.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-icons_454545_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-icons_454545_256x240.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-icons_888888_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-icons_888888_256x240.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-icons_cd0a0a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-icons_cd0a0a_256x240.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-icons_f6cf3b_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-icons_f6cf3b_256x240.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-bg_glass_75_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-bg_glass_75_ffffff_1x400.png
--------------------------------------------------------------------------------
/views/result/download-banner.jade:
--------------------------------------------------------------------------------
1 | | Are you designer? You can help us improve fontello!
2 |
3 |
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-bg_inset-soft_95_fef1ec_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-bg_inset-soft_95_fef1ec_1x100.png
--------------------------------------------------------------------------------
/assets/vendor/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msurguy/fontello/master/assets/vendor/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png
--------------------------------------------------------------------------------
/views/code-editor/glyph.jade:
--------------------------------------------------------------------------------
1 | .top
2 | span.char-editable !{self.top}
3 |
4 | .center.font-fontello !{self.chr}
5 |
6 | .bottom
7 | span.code-prefix U+
8 | span.code-editable !{self.bottom}
9 |
--------------------------------------------------------------------------------
/views/selector/font-item.jade:
--------------------------------------------------------------------------------
1 | h2.src-font-head
2 | a.label.label-important.font-info(href="#") info
3 | a.src-font-name._collapser(href="#") #{self.fontname}
4 | ul.unstyled.font-glyphs.font-fontello
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | config/*.local.yml
2 | node_modules/
3 | doc/
4 | tmp/
5 | log/
6 |
7 | *.log
8 | *.swp
9 | *.sublime-project
10 | *.sublime-workspace
11 |
12 | /public/assets/
13 | /public/download/
14 |
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/css/icons-codes.css:
--------------------------------------------------------------------------------
1 |
2 | .icon-settings:before { content: '\2699'; } /* '⚙' */
3 | .icon-download:before { content: '\f000'; } /* '' */
4 | .icon-search:before { content: '\f001'; } /* '' */
--------------------------------------------------------------------------------
/views/errors/no-file-reader.jade:
--------------------------------------------------------------------------------
1 | | Config importer requires modern browser.
2 | | Please, upgrade
3 | | your browser to be able import your previous configurations.
4 |
--------------------------------------------------------------------------------
/views/errors/max-glyphs.jade:
--------------------------------------------------------------------------------
1 | | You can't select more than #{self.max} icons at once.
2 | | If you have a real use-case, please,
3 | | create
4 | | ticket in issue tracker.
5 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/js/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "validthis": true,
3 | "laxcomma" : true,
4 | "laxbreak" : true,
5 | "browser" : true,
6 | "debug" : true,
7 | "boss" : true,
8 | "expr" : true,
9 | "asi" : true
10 | }
--------------------------------------------------------------------------------
/assets/vendor/jquery.noty/noty.css:
--------------------------------------------------------------------------------
1 | /*
2 | *= require ./src/css/jquery.noty
3 | *= require ./src/css/noty_theme_twitter
4 | */
5 |
6 | .noty_bar.noty_theme_twitter.noty_information {
7 | font-size: 24px;
8 | font-weight: bold;
9 | padding: 10px;
10 | }
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Font license info
2 |
3 |
4 | ## Entypo
5 |
6 | Copyright (C) 2012 by Daniel Bruce
7 |
8 | Author: Daniel Buce
9 | License: SIL (http://scripts.sil.org/OFL)
10 | Homepage: http://www.entypo.com
11 |
12 |
13 |
--------------------------------------------------------------------------------
/config/router.yml:
--------------------------------------------------------------------------------
1 | router:
2 | map:
3 | app:
4 | "/": ~
5 | font.download:
6 | "/download/{file}":
7 | file: /.+/
8 | assets:
9 | "/assets/{path}":
10 | path: /.+/
11 | static:
12 | "/{file}":
13 | file: /favicon.ico|robots.txt|snippet.png|fuckup.log/
14 |
--------------------------------------------------------------------------------
/support/font-templates/css/css-ie7-codes.jade:
--------------------------------------------------------------------------------
1 | - var i, g, css, hex, chr
2 | - for (i in glyphs)
3 | - g = glyphs[i]
4 | - css = meta.css_prefix + g.css
5 | - hex = g.code.toString(16)
6 | - chr = unichr(g.code)
7 | != '\n'
8 | | .#{css} { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '#{hex}; '); }
9 |
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/css/icons-ie7-codes.css:
--------------------------------------------------------------------------------
1 |
2 | .icon-settings { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '⚙ '); }
3 | .icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
4 | .icon-search { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
--------------------------------------------------------------------------------
/lib/filters.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | var path = require('path');
5 | var fs = require('fs');
6 |
7 |
8 | ////////////////////////////////////////////////////////////////////////////////
9 |
10 |
11 | fs.readdirSync(path.join(__dirname, 'filters')).forEach(function (file) {
12 | if ('.js' === path.extname(file)) {
13 | require(path.join(__dirname, 'filters', file));
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/support/font-templates/LICENSE.jade:
--------------------------------------------------------------------------------
1 | | Font license info
2 | != '\n\n\n'
3 |
4 | - var i, f
5 | - for (i in used_fonts)
6 | - f = used_fonts[i]
7 | | ## #{f.font.fullname}
8 | != '\n\n'
9 | | #{f.font.copyright}
10 | != '\n\n'
11 | | Author: #{f.meta.author}
12 | | License: #{f.meta.license} (#{f.meta.license_url})
13 | | Homepage: #{f.meta.homepage}
14 | != '\n\n\n'
15 |
--------------------------------------------------------------------------------
/etc/init/fontello.conf:
--------------------------------------------------------------------------------
1 | # fontello.com upstart script
2 | description "Fontello - Iconic fonts scissors"
3 | author "Nodeca"
4 |
5 | start on startup
6 | stop on shutdown
7 |
8 | # production|staging|development
9 | env NODECA_ENV="production"
10 |
11 | script
12 | /bin/bash <&1
17 | EOT
18 | end script
19 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/layouts.less:
--------------------------------------------------------------------------------
1 | //
2 | // Layouts
3 | // --------------------------------------------------
4 |
5 |
6 | // Container (centered, fixed-width layouts)
7 | .container {
8 | .container-fixed();
9 | }
10 |
11 | // Fluid layouts (left aligned, with sidebar, min- & max-width content)
12 | .container-fluid {
13 | padding-right: @gridGutterWidth;
14 | padding-left: @gridGutterWidth;
15 | .clearfix();
16 | }
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/component-animations.less:
--------------------------------------------------------------------------------
1 | //
2 | // Component animations
3 | // --------------------------------------------------
4 |
5 |
6 | .fade {
7 | opacity: 0;
8 | .transition(opacity .15s linear);
9 | &.in {
10 | opacity: 1;
11 | }
12 | }
13 |
14 | .collapse {
15 | position: relative;
16 | height: 0;
17 | overflow: hidden;
18 | .transition(height .35s ease);
19 | &.in {
20 | height: auto;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/assets/javascripts/app.js:
--------------------------------------------------------------------------------
1 | //= require store
2 | //= require jquery/jquery
3 | //= require jquery-ui/jquery-ui
4 | //= require jquery.noty/src/js/jquery.noty
5 | //= require underscore
6 | //= require bootstrap/bootstrap
7 | //= require backbone
8 | //= require jquery.collapser
9 | //= require jquery.inplaceEditor
10 | //= require jade/runtime
11 | //= require babelfish-runtime
12 | //= require nodeca
13 | //= require i18n
14 | //= require views
15 | //= require api
16 |
--------------------------------------------------------------------------------
/config/application.yml:
--------------------------------------------------------------------------------
1 | app:
2 | builder_concurrency: 4 # Default: amount of CPUs
3 | max_glyphs: ~ # Max allowed glyphs per download. Unlimited if null.
4 | glyph_size:
5 | min: 12 # minimal size
6 | val: 16 # default size
7 | max: 30 # miximum size
8 | autoguess_charcode:
9 | min: 0xe800
10 | max: 0xf8ff
11 | locales:
12 | enabled: [en]
13 | default: en
14 | listen:
15 | host: localhost
16 | port: 3000
17 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/utilities.less:
--------------------------------------------------------------------------------
1 | //
2 | // Utility classes
3 | // --------------------------------------------------
4 |
5 |
6 | // Quick floats
7 | .pull-right {
8 | float: right;
9 | }
10 | .pull-left {
11 | float: left;
12 | }
13 |
14 | // Toggling content
15 | .hide {
16 | display: none;
17 | }
18 | .show {
19 | display: block;
20 | }
21 |
22 | // Visibility
23 | .invisible {
24 | visibility: hidden;
25 | }
26 |
27 | // For Affix plugin
28 | .affix {
29 | position: fixed;
30 | }
31 |
--------------------------------------------------------------------------------
/views/app.jade:
--------------------------------------------------------------------------------
1 | .container
2 | #myTabContent.tab-content
3 | // tab0 `Loading`
4 | #loading.tab-pane.fade.active.in Loading...
5 |
6 | // tab1 `Select
7 | #selector.tab-pane.fade
8 | ul#selector-fonts.unstyled
9 |
10 | // tab2 `Preview`
11 | #preview.tab-pane.fade
12 | p.note Click glyph name to edit
13 | #preview-font.row
14 |
15 | // tab3 `Download`
16 | #codes-editor.tab-pane.fade
17 | p.note Click symbol codes on black lines to edit
18 | #result-font
19 |
--------------------------------------------------------------------------------
/support/font-templates/css/css-codes.jade:
--------------------------------------------------------------------------------
1 | - if (_.any(glyphs, function (g) { return 0xffff < g.code; }))
2 | | @charset "UTF-8";
3 | != '\n'
4 | != '\n'
5 |
6 | - var i, g, css, hex, chr
7 | - for (i in glyphs)
8 | - g = glyphs[i]
9 | - css = meta.css_prefix + g.css
10 | - hex = '\\' + g.code.toString(16)
11 | - chr = unichr(g.code)
12 | != '\n'
13 | - if (0xffff < g.code)
14 | | .#{css}:before { content: '#{chr}'; } /* '#{hex}' */
15 | - else
16 | | .#{css}:before { content: '#{hex}'; } /* '#{chr}' */
17 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/breadcrumbs.less:
--------------------------------------------------------------------------------
1 | //
2 | // Breadcrumbs
3 | // --------------------------------------------------
4 |
5 |
6 | .breadcrumb {
7 | padding: 8px 15px;
8 | margin: 0 0 @baseLineHeight;
9 | list-style: none;
10 | background-color: #f5f5f5;
11 | .border-radius(4px);
12 | li {
13 | display: inline-block;
14 | .ie7-inline-block();
15 | text-shadow: 0 1px 0 @white;
16 | }
17 | .divider {
18 | padding: 0 5px;
19 | color: #ccc;
20 | }
21 | .active {
22 | color: @grayLight;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/assets/embedded_fonts/fontface-fontello.css.ejs:
--------------------------------------------------------------------------------
1 | .font-fontello { font-family: 'fontello'; }
2 |
3 | @font-face {
4 | font-family: 'fontello';
5 | src: url('<%= asset_path("fontello.eot") %>');
6 | src: url('<%= asset_path("fontello.eot") %>?#iefix') format('embedded-opentype'),
7 | url('<%= asset_path("fontello.woff") %>') format('woff'),
8 | url('<%= asset_path("fontello.ttf") %>') format('truetype'),
9 | url('<%= asset_path("fontello.svg") %>#entypo') format('svg');
10 | font-weight: normal;
11 | font-style: normal;
12 | }
13 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/grid.less:
--------------------------------------------------------------------------------
1 | //
2 | // Grid system
3 | // --------------------------------------------------
4 |
5 |
6 | // Fixed (940px)
7 | #grid > .core(@gridColumnWidth, @gridGutterWidth);
8 |
9 | // Fluid (940px)
10 | #grid > .fluid(@fluidGridColumnWidth, @fluidGridGutterWidth);
11 |
12 | // Reset utility classes due to specificity
13 | [class*="span"].hide,
14 | .row-fluid [class*="span"].hide {
15 | display: none;
16 | }
17 |
18 | [class*="span"].pull-right,
19 | .row-fluid [class*="span"].pull-right {
20 | float: right;
21 | }
22 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/hero-unit.less:
--------------------------------------------------------------------------------
1 | //
2 | // Hero unit
3 | // --------------------------------------------------
4 |
5 |
6 | .hero-unit {
7 | padding: 60px;
8 | margin-bottom: 30px;
9 | background-color: @heroUnitBackground;
10 | .border-radius(6px);
11 | h1 {
12 | margin-bottom: 0;
13 | font-size: 60px;
14 | line-height: 1;
15 | color: @heroUnitHeadingColor;
16 | letter-spacing: -1px;
17 | }
18 | p {
19 | font-size: 18px;
20 | font-weight: 200;
21 | line-height: @baseLineHeight * 1.5;
22 | color: @heroUnitLeadColor;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/responsive-768px-979px.less:
--------------------------------------------------------------------------------
1 | //
2 | // Responsive: Tablet to desktop
3 | // --------------------------------------------------
4 |
5 |
6 | @media (min-width: 768px) and (max-width: 979px) {
7 |
8 | // Fixed grid
9 | #grid > .core(@gridColumnWidth768, @gridGutterWidth768);
10 |
11 | // Fluid grid
12 | #grid > .fluid(@fluidGridColumnWidth768, @fluidGridGutterWidth768);
13 |
14 | // Input grid
15 | #grid > .input(@gridColumnWidth768, @gridGutterWidth768);
16 |
17 | // No need to reset .thumbnails here since it's the same @gridGutterWidth
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/bootstrap.js:
--------------------------------------------------------------------------------
1 | //= //require ./src/js/bootstrap-alert
2 | //= //require ./src/js/bootstrap-button
3 | //= //require ./src/js/bootstrap-carousel
4 | //= require ./src/js/bootstrap-collapse
5 | //= require ./src/js/bootstrap-dropdown
6 | //= require ./src/js/bootstrap-modal
7 | //= //require ./src/js/bootstrap-scrollspy
8 | //= require ./src/js/bootstrap-tab
9 | //= require ./src/js/bootstrap-tooltip
10 | //= require ./src/js/bootstrap-transition
11 | //= require ./src/js/bootstrap-typeahead
12 |
13 | // Popover must go AFTER tooltip
14 | //= //require ./src/js/bootstrap-popover
15 |
16 |
--------------------------------------------------------------------------------
/DEV-NOTES.md:
--------------------------------------------------------------------------------
1 | Developers Notes
2 | ----------------
3 |
4 | You can run font generator manually from command line:
5 |
6 | ./bin/generate_font.sh FONTNAME TMPDIR ZIPBALL
7 |
8 | - `FONTNAME`: generated font filename
9 | - `TMPDIR`: path where `config.json` (with user config) is placed
10 | - `ZIPBALL`: output archive with generated font and demo
11 |
12 |
13 | If you are debugging font merger or builder, you might want to generate
14 | *generator config* manually on base of user config (you can get it from the
15 | generated zipball):
16 |
17 | ./fontello.js font_config --input config.json --output builder-config.json
18 |
--------------------------------------------------------------------------------
/assets/javascripts/loader.js.ejs:
--------------------------------------------------------------------------------
1 | //= require modernizr.custom
2 | //= require yepnope
3 | //= require_self
4 |
5 |
6 | /*jshint browser:true,node:false*/
7 | /*global yepnope, window*/
8 |
9 |
10 | yepnope([
11 | {
12 | // JSON is required for Opera < 11 + IE < 8
13 | // See: http://caniuse.com/json
14 | test: !!window.JSON,
15 | nope: <%- JSON.stringify(asset_path('json2.js')) %>
16 | },
17 | {
18 | load: <%- JSON.stringify(asset_path('app.js')) %>,
19 | complete: function () {
20 | window.nodeca.client.init();
21 | }
22 | }
23 | ]);
24 |
25 |
26 | // vim: filetype=javascript:syntax=javascript
27 |
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/css/icons-ie7.css:
--------------------------------------------------------------------------------
1 | [class^="icon-"],
2 | [class*=" icon-"] {
3 | font-family: 'icons';
4 | font-style: normal;
5 | font-weight: normal;
6 | /* fix buttons height */
7 | line-height: 1em;
8 | /* you can be more comfortable with increased icons size */
9 | /* font-zize: 120%; */
10 | }
11 |
12 | .icon-settings { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '⚙ '); }
13 | .icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
14 | .icon-search { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
--------------------------------------------------------------------------------
/client/models/source_font.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 | "use strict";
4 |
5 | module.exports = Backbone.Model.extend({
6 | defaults: function () {
7 | return {
8 | font: {fontname: "unknown"},
9 | glyphs: []
10 | };
11 | },
12 |
13 |
14 | getGlyph: function (glyph_id) {
15 | return this.get("glyphs")[glyph_id];
16 | },
17 |
18 |
19 | // Stub to prevent Backbone from reading or saving the model to the server.
20 | // Backbone calls `Backbone.sync()` function (on fetch/save/destroy)
21 | // if model doesn't have own `sync()` method.
22 | sync: function () {}
23 | });
24 |
--------------------------------------------------------------------------------
/support/font-templates/css/css-ie7.jade:
--------------------------------------------------------------------------------
1 | :stylus_nowrap
2 | [class^="icon-"], [class*=" icon-"]
3 | font-family '#{font.fontname}'
4 | font-style normal
5 | font-weight normal
6 |
7 | /* fix buttons height */
8 | line-height 1em
9 |
10 | /* you can be more comfortable with increased icons size */
11 | /* font-size: 120%; */
12 |
13 | - var i, g, css, hex, chr
14 | - for (i in glyphs)
15 | - g = glyphs[i]
16 | - css = meta.css_prefix + g.css
17 | - hex = g.code.toString(16)
18 | - chr = unichr(g.code)
19 | != '\n'
20 | | .#{css} { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '#{hex}; '); }
21 |
--------------------------------------------------------------------------------
/client/ui/panes/selector.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | module.exports = Backbone.View.extend({
8 | el: '#selector',
9 |
10 |
11 | initialize: function (attributes) {
12 | this.changeGlyphSize(nodeca.config.app.glyph_size.val);
13 | this.model.each(this.addFont, this);
14 | },
15 |
16 |
17 | changeGlyphSize: function (size) {
18 | this.$el.css('font-size', size);
19 | },
20 |
21 |
22 | addFont: function (font) {
23 | var view = new nodeca.client.ui.panes.selector_font({model: font});
24 | this.$('#selector-fonts').append(view.render().el);
25 | }
26 | });
27 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/wells.less:
--------------------------------------------------------------------------------
1 | //
2 | // Wells
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | .well {
8 | min-height: 20px;
9 | padding: 19px;
10 | margin-bottom: 20px;
11 | background-color: @wellBackground;
12 | border: 1px solid darken(@wellBackground, 7%);
13 | .border-radius(4px);
14 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
15 | blockquote {
16 | border-color: #ddd;
17 | border-color: rgba(0,0,0,.15);
18 | }
19 | }
20 |
21 | // Sizes
22 | .well-large {
23 | padding: 24px;
24 | .border-radius(6px);
25 | }
26 | .well-small {
27 | padding: 9px;
28 | .border-radius(3px);
29 | }
30 |
--------------------------------------------------------------------------------
/support/forever.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | FONTELLO_PID=""
4 | WATCH_PATHS="assets client config node_modules shared server src support views"
5 |
6 | start_fontello() {
7 | test "x" != "x$FONTELLO_PID" && kill -9 $FONTELLO_PID
8 | node ./fontello.js server & FONTELLO_PID=$!
9 | }
10 |
11 | # Initial start
12 | start_fontello
13 |
14 | inotifywait -m -r --format '%w%f' -e modify -e move -e create -e delete $WATCH_PATHS | while read f ; do
15 | # when not excluded
16 | (echo $f | egrep -v -q '\.swpx?$|/\.git/') && \
17 | # and actually included
18 | (echo $f | egrep -q '\.(js|css|styl|less|ejs|jade)$') && \
19 | # restart server
20 | start_fontello
21 | done
22 |
--------------------------------------------------------------------------------
/client/ui/panes/codes_editor.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 | "use strict";
4 |
5 |
6 | module.exports = Backbone.View.extend({
7 | el: '#codes-editor',
8 |
9 |
10 | initialize: function () {
11 | var $glyphs = this.$('#result-font'), views = {};
12 |
13 | function add(glyph) {
14 | var v = new nodeca.client.ui.panes.codes_editor_glyph({model: glyph});
15 | views[glyph.cid] = v;
16 | $glyphs.append(v.render().el);
17 | }
18 |
19 | this.model.each(add);
20 | this.model.on('add', add);
21 |
22 | this.model.on('remove', function (glyph) {
23 | views[glyph.cid].remove();
24 | delete views[glyph.cid];
25 | });
26 | }
27 | });
28 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/responsive-1200px-min.less:
--------------------------------------------------------------------------------
1 | //
2 | // Responsive: Large desktop and up
3 | // --------------------------------------------------
4 |
5 |
6 | @media (min-width: 1200px) {
7 |
8 | // Fixed grid
9 | #grid > .core(@gridColumnWidth1200, @gridGutterWidth1200);
10 |
11 | // Fluid grid
12 | #grid > .fluid(@fluidGridColumnWidth1200, @fluidGridGutterWidth1200);
13 |
14 | // Input grid
15 | #grid > .input(@gridColumnWidth1200, @gridGutterWidth1200);
16 |
17 | // Thumbnails
18 | .thumbnails {
19 | margin-left: -@gridGutterWidth1200;
20 | }
21 | .thumbnails > li {
22 | margin-left: @gridGutterWidth1200;
23 | }
24 | .row-fluid .thumbnails {
25 | margin-left: 0;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "icons",
3 | "glyphs": [
4 | {
5 | "uid": "7222571caa5c15f83dcfd447c58d68d9",
6 | "orig_css": "search",
7 | "orig_code": 61441,
8 | "css": "search",
9 | "code": 61441,
10 | "src": "entypo"
11 | },
12 | {
13 | "uid": "b08cfe8039de2ce815686aced2caef06",
14 | "orig_css": "download",
15 | "orig_code": 61440,
16 | "css": "download",
17 | "code": 61440,
18 | "src": "entypo"
19 | },
20 | {
21 | "uid": "bc64550dd022ce21604f97309b346cea",
22 | "orig_css": "cog",
23 | "orig_code": 9881,
24 | "css": "settings",
25 | "code": 9881,
26 | "src": "entypo"
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/assets/stylesheets/ui/tabs.styl:
--------------------------------------------------------------------------------
1 | //=== Fix tab styles
2 | .nav-tabs
3 | margin-bottom 0
4 |
5 | .nav-tabs .disabled
6 | .nav-tabs .disabled:hover
7 | opacity 0.3
8 | cursor default
9 |
10 | .nav-tabs > li > a
11 | outline: none
12 | transition background-color .5s ease-in-out
13 |
14 | .nav-tabs > .active > a,
15 | .nav-tabs > .active > a:hover
16 | font-weight: bold;
17 | border-color #aaa #aaa transparent
18 | box-shadow -2px -2px 2px -2px #ccc, 2px -2px 2px -2px #ccc
19 |
20 | .nav-tabs
21 | border-bottom: 1px solid #aaa
22 | box-shadow 0 10px 15px 10px #fff;
23 |
24 | //====== users counter ============
25 | .stats
26 | text-align center
27 | font-size 10px
28 | color #888
29 | position absolute
30 | right 0
31 | bottom 0
32 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/close.less:
--------------------------------------------------------------------------------
1 | //
2 | // Close icons
3 | // --------------------------------------------------
4 |
5 |
6 | .close {
7 | float: right;
8 | font-size: 20px;
9 | font-weight: bold;
10 | line-height: @baseLineHeight;
11 | color: @black;
12 | text-shadow: 0 1px 0 rgba(255,255,255,1);
13 | .opacity(20);
14 | &:hover {
15 | color: @black;
16 | text-decoration: none;
17 | cursor: pointer;
18 | .opacity(40);
19 | }
20 | }
21 |
22 | // Additional properties for button version
23 | // iOS requires the button element instead of an anchor tag.
24 | // If you want the anchor version, it requires `href="#"`.
25 | button.close {
26 | padding: 0;
27 | cursor: pointer;
28 | background: transparent;
29 | border: 0;
30 | -webkit-appearance: none;
31 | }
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/accordion.less:
--------------------------------------------------------------------------------
1 | //
2 | // Accordion
3 | // --------------------------------------------------
4 |
5 |
6 | // Parent container
7 | .accordion {
8 | margin-bottom: @baseLineHeight;
9 | }
10 |
11 | // Group == heading + body
12 | .accordion-group {
13 | margin-bottom: 2px;
14 | border: 1px solid #e5e5e5;
15 | .border-radius(4px);
16 | }
17 | .accordion-heading {
18 | border-bottom: 0;
19 | }
20 | .accordion-heading .accordion-toggle {
21 | display: block;
22 | padding: 8px 15px;
23 | }
24 |
25 | // General toggle styles
26 | .accordion-toggle {
27 | cursor: pointer;
28 | }
29 |
30 | // Inner needs the styles because you can't animate properly with any styles on the element
31 | .accordion-inner {
32 | padding: 9px 15px;
33 | border-top: 1px solid #e5e5e5;
34 | }
35 |
--------------------------------------------------------------------------------
/etc/certs/fontello-dev.cert:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICATCCAWoCCQDrxv/Pozx1tTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJS
3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
4 | cyBQdHkgTHRkMB4XDTEyMDYwNzIyMTUzOFoXDTEzMDYwNzIyMTUzOFowRTELMAkG
5 | A1UEBhMCUlUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
6 | IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxNy0
7 | 3QpTO58fS0ApducrCum5lIJHHCoY6TqMfH9sE+MsQXzDpvPU2dhqfTQonLX6LU0B
8 | Su9PYt9va13Yz7rLet9N/yqhmH5pbZuo4iC8y11nYaUtgW6XjboBxnzewJPUkySJ
9 | m9ZbempfIYfCWDFaYgQiYvgls3qx2oBZg4pZVpsCAwEAATANBgkqhkiG9w0BAQUF
10 | AAOBgQB2rAHylGkCdt4wKIj5kx4MP/ktrZ3vkvnaEmEVlrcNJo3HCsATq4waJAdI
11 | SMXtuLaKIqa3GQ3QLR1MbWJvvHL4hkPxiGyxvF/52F25tPWxiX0FXrx0AWePSMV8
12 | UHbVJHhGMPP5nAup418mee6quX3GntTOgf7z9KJTR8MrgZjivA==
13 | -----END CERTIFICATE-----
14 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/pager.less:
--------------------------------------------------------------------------------
1 | //
2 | // Pager pagination
3 | // --------------------------------------------------
4 |
5 |
6 | .pager {
7 | margin: @baseLineHeight 0;
8 | list-style: none;
9 | text-align: center;
10 | .clearfix();
11 | }
12 | .pager li {
13 | display: inline;
14 | }
15 | .pager a,
16 | .pager span {
17 | display: inline-block;
18 | padding: 5px 14px;
19 | background-color: #fff;
20 | border: 1px solid #ddd;
21 | .border-radius(15px);
22 | }
23 | .pager a:hover {
24 | text-decoration: none;
25 | background-color: #f5f5f5;
26 | }
27 | .pager .next a,
28 | .pager .next span {
29 | float: right;
30 | }
31 | .pager .previous a {
32 | float: left;
33 | }
34 | .pager .disabled a,
35 | .pager .disabled a:hover,
36 | .pager .disabled span {
37 | color: @grayLight;
38 | background-color: #fff;
39 | cursor: default;
40 | }
--------------------------------------------------------------------------------
/cli/server.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca*/
5 |
6 |
7 | // nodeca
8 | var NLib = require('nlib');
9 |
10 |
11 | // 3rd-party
12 | var Async = NLib.Vendor.Async;
13 | var FsTools = NLib.Vendor.FsTools;
14 |
15 |
16 | module.exports.parserParameters= {
17 | version: nodeca.runtime.version,
18 | addHelp: true,
19 | help: 'start fontello server',
20 | description: 'Start fontello server'
21 | };
22 |
23 |
24 | module.exports.run = function (args, callback) {
25 | Async.series([
26 | NLib.InitStages.loadServerApiSubtree,
27 | NLib.InitStages.loadSharedApiSubtree,
28 | NLib.InitStages.loadClientApiSubtree,
29 | NLib.InitStages.initRouter,
30 | NLib.InitStages.initTranslations,
31 |
32 | require('../lib/init/cronjob'),
33 | require('../lib/init/assets'),
34 | require('../lib/init/server')
35 | ], callback);
36 | };
37 |
--------------------------------------------------------------------------------
/client/ui/panes/preview.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | module.exports = Backbone.View.extend({
8 | el: '#preview',
9 |
10 |
11 | initialize: function () {
12 | var $glyphs = this.$('#preview-font'), views = {};
13 |
14 | this.changeGlyphSize(nodeca.config.app.glyph_size.val);
15 |
16 | function add(glyph) {
17 | var v = new nodeca.client.ui.panes.preview_glyph({model: glyph});
18 | views[glyph.cid] = v;
19 | $glyphs.append(v.render().el);
20 | }
21 |
22 | this.model.each(add);
23 | this.model.on('add', add);
24 |
25 | this.model.on('remove', function (glyph) {
26 | views[glyph.cid].remove();
27 | delete views[glyph.cid];
28 | });
29 | },
30 |
31 |
32 | changeGlyphSize: function (size) {
33 | this.$el.css('font-size', size);
34 | }
35 | });
36 |
--------------------------------------------------------------------------------
/client/ui/panes/selector_glyph.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | module.exports = Backbone.View.extend({
8 | tagName: 'li',
9 | className: 'glyph',
10 |
11 |
12 | events: {
13 | click: function () {
14 | this.model.toggle('selected');
15 | }
16 | },
17 |
18 |
19 | initialize: function () {
20 | var self = this,
21 | font = this.model.get('font').getName(),
22 | uid = this.model.get('source').uid,
23 | code = nodeca.shared.glyphs_map[font][uid],
24 | text = nodeca.client.util.fixedFromCharCode(code);
25 |
26 | this.$el.data('model', this.model);
27 | this.$el.text(text);
28 |
29 | //
30 | // Listen to the model changes
31 | //
32 |
33 | this.model.on('change:selected', function (g, v) {
34 | self.$el.toggleClass('selected', v);
35 | });
36 | }
37 | });
38 |
--------------------------------------------------------------------------------
/assets/stylesheets/variables.styl:
--------------------------------------------------------------------------------
1 | black = #000
2 | grayDarker = #222
3 | grayDark = #444
4 | gray = #666
5 | grayLight = #999
6 | grayLighter = #ccc
7 | grayLightest = #eee
8 | white = #fff
9 |
10 |
11 | // Accent colors
12 | // -------------------------
13 | blue = #049cdb
14 | blueDark = #0064cd
15 | green = #46a546
16 | red = #9d261d
17 | yellow = #ffc40d
18 | orange = #f89406
19 | pink = #c3325f
20 | purple = #7a43b6
21 |
22 | baseFontSize = 14px
23 | baseLineHeight = 20px
24 |
25 | sansFontFamily = "Helvetica Neue", Helvetica, Arial, sans-serif;
26 | sansWideFontFamily = Verdana, sans-serif;
27 | serifFontFamily = Georgia, "Times New Roman", Times, serif;
28 | monoFontFamily = Menlo, Monaco, Consolas, "Courier New", monospace;
29 |
30 | navbarText = #bbb
31 | navbarLinkColor = #bbb
32 |
33 |
--------------------------------------------------------------------------------
/shared/getByPath.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /**
5 | * shared
6 | **/
7 |
8 |
9 | /*global nodeca, _*/
10 |
11 |
12 | ////////////////////////////////////////////////////////////////////////////////
13 |
14 |
15 | /**
16 | * shared.getByPath(obj, path) -> Mixed
17 | * - obj (Object): Object to get value from
18 | * - path (String): Path of a property
19 | *
20 | * Extracts property from more than one level down, via a `.` delimited
21 | * string of property names.
22 | *
23 | *
24 | * ##### Example
25 | *
26 | * shared.getByPath({foo: {bar: 123}}, 'foo.bar');
27 | * // => 123
28 | **/
29 | module.exports = function getByPath(obj, path) {
30 | var parts = path.split('.');
31 |
32 | // this is the fastest way to find nested value:
33 | // http://jsperf.com/find-object-deep-nested-value
34 |
35 | while (obj && parts.length) {
36 | obj = obj[parts.shift()];
37 | }
38 |
39 | return obj;
40 | };
41 |
--------------------------------------------------------------------------------
/etc/certs/fontello-dev.key:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICXwIBAAKBgQDE3LTdClM7nx9LQCl25ysK6bmUgkccKhjpOox8f2wT4yxBfMOm
3 | 89TZ2Gp9NCictfotTQFK709i329rXdjPust6303/KqGYfmltm6jiILzLXWdhpS2B
4 | bpeNugHGfN7Ak9STJImb1lt6al8hh8JYMVpiBCJi+CWzerHagFmDillWmwIDAQAB
5 | AoGBALtCRjjMjYf1QMtP6SFVm7fxw7nkgsfjs3aHXwM+Igx416wjhejVn+7o0cLv
6 | ToJjB+r3iPdC1Hz0lQPIbWiMAujcm/yQ2uHqbvgUODJj85RmL1PLPmzXQmIMIXjW
7 | TBC3Z7WOXaP8fM/Bc+jmXANE+qQS5wTFxF89rPzYk7+70uihAkEA+0O3TQ3/6Qtn
8 | ok++bJI/GxRcOFSZi2yg9Gt9DUPzFay5wX5EP6fvv0TB3HhKekV20X/M3cv6OhCq
9 | SfldNgmi9wJBAMiSg3jjGmjZWzIZXOHa+olNaWqarv8+NCYsmQEzleBZTdbNTsaM
10 | EaHGPwmjAqgHETe/URw8GnQTOVr0Nn6MXH0CQQDxTstPeU54pbdVrngXFSz9+MPI
11 | ZZdAy4aYtlJW1xcxjbyoE3fAGqypaIM2FWCRpPzDnpVFvYwHD9I7UP0v1HlpAkEA
12 | lYSbG4f4zQaTNDKyCfAq6iXaGs06/S2KxJZkbP/ej4MjQqiEPAB4uGdH4NAzD71M
13 | +YjWVzz632LhU8tPwGC0JQJBAL3Q1WCPMFHqhoKCs3YPAP6BUBgmrRych4c2ErtL
14 | Fo9/q2zikU7t2fZjGIybud6cMKdt5s7FRacq7xL0S8KC79g=
15 | -----END RSA PRIVATE KEY-----
16 |
--------------------------------------------------------------------------------
/lib/init/server/http/compression.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // stdlib
8 | var zlib = require('zlib');
9 |
10 |
11 | ////////////////////////////////////////////////////////////////////////////////
12 |
13 |
14 | // Returns whenever or not compression is allowed by client
15 | //
16 | // - `'gzip'` if GZip allowed
17 | // - `'deflate'` if Deflate allowed
18 | // - `false` otherwise
19 | //
20 | module.exports.is_allowed = function get_allowed_compression(req) {
21 | var accept = req.headers['accept-encoding'] || '';
22 |
23 | if ('*' === accept || 0 <= accept.indexOf('gzip')) {
24 | return 'gzip';
25 | }
26 |
27 | if (0 <= accept.indexOf('deflate')) {
28 | return 'deflate';
29 | }
30 |
31 | return false;
32 | };
33 |
34 |
35 | // small helper to run compressor
36 | //
37 | module.exports.process = function compress(algo, source, callback) {
38 | ('gzip' === algo ? zlib.gzip : zlib.deflate)(source, callback);
39 | };
40 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/iconic-uni.font"]
2 | path = src/iconic-uni.font
3 | url = git://github.com/fontello/iconic-uni.font.git
4 | [submodule "src/awesome-uni.font"]
5 | path = src/awesome-uni.font
6 | url = git://github.com/fontello/awesome-uni.font.git
7 | [submodule "src/websymbols-uni.font"]
8 | path = src/websymbols-uni.font
9 | url = git://github.com/fontello/websymbols-uni.font.git
10 | [submodule "src/entypo"]
11 | path = src/entypo
12 | url = git://github.com/fontello/entypo.git
13 | [submodule "src/brandico.font"]
14 | path = src/brandico.font
15 | url = git://github.com/fontello/brandico.font.git
16 | [submodule "support/font-builder"]
17 | path = support/font-builder
18 | url = git://github.com/fontello/font-builder.git
19 | [submodule "src/modernpics.font"]
20 | path = src/modernpics.font
21 | url = git://github.com/fontello/modernpics.font.git
22 | [submodule "src/typicons.font"]
23 | path = src/typicons.font
24 | url = git://github.com/fontello/typicons.font.git
25 |
--------------------------------------------------------------------------------
/server/app.js:
--------------------------------------------------------------------------------
1 | /*global nodeca*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | ////////////////////////////////////////////////////////////////////////////////
8 |
9 |
10 | function hash(str) {
11 | return require('crypto').createHash('md5').update(str).digest('hex');
12 | }
13 |
14 |
15 | ////////////////////////////////////////////////////////////////////////////////
16 |
17 |
18 | // FIXME: this works for single-process model only.
19 | // switch to shared cache in future.
20 | var etag = hash('fontello-app-' + Date.now());
21 |
22 |
23 | ////////////////////////////////////////////////////////////////////////////////
24 |
25 |
26 | module.exports = function app(params, callback) {
27 | if (!this.origin.http) {
28 | callback('HTTP only');
29 | return;
30 | }
31 |
32 | // set headers
33 | this.response.headers['ETag'] = etag;
34 | this.response.headers['Cache-Control'] = 'private, max-age=0, must-revalidate';
35 |
36 | // done
37 | callback();
38 | };
39 |
--------------------------------------------------------------------------------
/client/ui/panes/preview_glyph.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | module.exports = Backbone.View.extend({
8 | tagName: "div",
9 | className: "preview-glyph span3",
10 |
11 |
12 | render: function () {
13 | var self = this,
14 | font = this.model.get('font').getName(),
15 | uid = this.model.get('source').uid,
16 | code = nodeca.shared.glyphs_map[font][uid];
17 |
18 | this.$el.html(nodeca.client.render('preview.glyph', {
19 | css: this.model.get('css'),
20 | chr: nodeca.client.util.fixedFromCharCode(code)
21 | }));
22 |
23 |
24 | this.$el.find('.glyph-name').inplaceEditor({
25 | noPaste: true,
26 | validateChar: function (char) {
27 | return /[a-zA-Z0-9\-\_]/.test(char) && 20 > this.getValue().length;
28 | }
29 | }).on('change', function (event, value) {
30 | self.model.set( 'css', value );
31 | });
32 |
33 | return this;
34 | }
35 | });
36 |
--------------------------------------------------------------------------------
/support/font-templates/demo.jade:
--------------------------------------------------------------------------------
1 | !!! 5
2 | html
3 | head
4 | //if lt IE 9
5 | script(src='http://html5shim.googlecode.com/svn/trunk/html5.js')
6 |
7 | :stylus
8 | @import "_demo"
9 |
10 | link(rel='stylesheet', href='css/#{font.fontname}.css')
11 | //if IE 7
12 | link(rel='stylesheet', href='css/#{font.fontname}-ie7.css')
13 |
14 | body
15 | .container
16 | .page-header
17 | h1 #{font.fullname} font icons demo
18 | .row
19 | - var col_class = "span" + Math.ceil(12 / meta.columns)
20 | - var chunk_size = Math.ceil(glyphs.length / meta.columns)
21 | - for (var i = 0; i < meta.columns; i++)
22 | div(class=col_class)
23 | ul.the-icons
24 | - var offset = i * chunk_size
25 | - for (var c = 0; c < chunk_size && glyphs[offset + c]; c++)
26 | - var g = glyphs[offset + c]
27 | - var css_class = meta.css_prefix + (g.css || g.file)
28 | | #{css_class}
29 |
--------------------------------------------------------------------------------
/lib/filters/renderer/helpers.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // nodeca
8 | var JASON = require('nlib').Vendor.JASON;
9 |
10 |
11 | ////////////////////////////////////////////////////////////////////////////////
12 |
13 |
14 | var helpers = module.exports = {};
15 |
16 |
17 | ////////////////////////////////////////////////////////////////////////////////
18 |
19 |
20 | // returns asset source
21 | helpers.asset_include = function asset_include(path) {
22 | var asset = nodeca.runtime.assets.environment.findAsset(path);
23 | return !asset ? "" : asset.toString();
24 | };
25 |
26 |
27 | // returns link for the api path `name`
28 | helpers.link_to = function (name, params) {
29 | return nodeca.runtime.router.linkTo(name, params) || '#';
30 | };
31 |
32 |
33 | // nodeca reference
34 | helpers.nodeca = function (path) {
35 | return !path ? nodeca : nodeca.shared.getByPath(nodeca, path);
36 | };
37 |
38 |
39 | // JSON alike serializer (but that treats RegExps, Function as they are)
40 | helpers.jason = JASON.stringify;
41 |
--------------------------------------------------------------------------------
/assets/stylesheets/ui/panes/preview.styl:
--------------------------------------------------------------------------------
1 | #preview
2 | padding-bottom 10px // to show shadow of bottom row elements
3 |
4 | .preview-glyph
5 | line-height 1.5em
6 | height 1.5em
7 | white-space nowrap
8 | background-color white
9 |
10 | span.icon
11 | display inline-block
12 | width 1.1em
13 | text-align center
14 | cursor default
15 |
16 | span.prefix
17 | margin-left 0.5em
18 | cursor default
19 |
20 | &:hover .glyph-name
21 | background-color lighten(yellow, 70%)
22 | //box-shadow 0 0 0px 2px rgba(168, 82, 82, 0.6) inset
23 | border-radius 4px
24 | cursor pointer
25 |
26 | .glyph-name
27 | display inline-block
28 |
29 | &:focus
30 | outline none
31 | box-shadow 0 0 8px rgba(168, 82, 82, 0.6), 0 0 0 2px rgba(168, 82, 82, 0.6)
32 | background-color lighten(rgb(168, 82, 82), 95%)
33 | border-radius 4px
34 | position relative
35 | z-index 1000
36 | cursor auto
37 |
38 |
39 | ._3d .preview-glyph span.icon
40 | text-shadow 1px 1px 1px rgba(127, 127, 127, 0.3)
41 |
--------------------------------------------------------------------------------
/assets/vendor/fontello/icons.css.ejs:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | *= require_self
4 | *= require ./src/css/icons-codes
5 |
6 | **/
7 |
8 | @font-face {
9 | font-family: 'icons';
10 | src: url(<%= asset_path('fontello/src/font/icons.eot') %>);
11 | src: url(<%= asset_path('fontello/src/font/icons.eot') %>?#iefix) format('embedded-opentype'),
12 | url(<%= asset_path('fontello/src/font/icons.woff') %>) format('woff'),
13 | url(<%= asset_path('fontello/src/font/icons.ttf') %>) format('truetype'),
14 | url(<%= asset_path('fontello/src/font/icons.svg') %>#icons) format('svg');
15 | font-weight: normal; font-style: normal;
16 | }
17 |
18 | [class^="icon-"]:before, [class*=" icon-"]:before {
19 | font-family: "icons";
20 | speak: none;
21 | font-size: 120%;
22 | opacity: .7;
23 | text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3);
24 |
25 | display: inline-block;
26 | width: 1em;
27 | margin-right: .2em;
28 | text-align: center;
29 | line-height: 1em;
30 |
31 | font-style: normal !important;
32 | font-weight: normal !important;
33 | }
34 |
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/css/icons.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'icons';
3 | src: url("../font/icons.eot");
4 | src: url("../font/icons.eot?#iefix") format('embedded-opentype'), url("../font/icons.woff") format('woff'), url("../font/icons.ttf") format('truetype'), url("../font/icons.svg#icons") format('svg');
5 | font-weight: normal;
6 | font-style: normal;
7 | }
8 | [class^="icon-"]:before,
9 | [class*=" icon-"]:before {
10 | font-family: 'icons';
11 | font-style: normal;
12 | font-weight: normal;
13 | speak: none;
14 | display: inline-block;
15 | text-decoration: inherit;
16 | width: 1em;
17 | margin-right: 0.2em;
18 | text-align: center;
19 | opacity: 0.7;
20 | /* Uncomment for 3D effect */
21 | /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
22 | /* fix buttons height */
23 | line-height: 1em;
24 | /* you can be more comfortable with increased icons size */
25 | /* font-size: 120%; */
26 | }
27 |
28 | .icon-settings:before { content: '\2699'; } /* '⚙' */
29 | .icon-download:before { content: '\f000'; } /* '' */
30 | .icon-search:before { content: '\f001'; } /* '' */
--------------------------------------------------------------------------------
/views/selector/font-info.jade:
--------------------------------------------------------------------------------
1 | .modal.fade
2 | .modal-header
3 | a.close(data-dismiss="modal") ×
4 | h3 #{self.font.fullname}
5 | .modal-body
6 | dl.dl-horizontal
7 | - if (self.meta)
8 | - var meta = self.meta
9 | - if (meta.license)
10 | dt License:
11 | dd
12 | - if (meta.license_meta)
13 | a(href=meta.license_meta, target="_blank") #{meta.license}
14 | - else
15 | | #{meta.license}
16 | - if (meta.author)
17 | dt Author:
18 | dd #{meta.author}
19 | - if (meta.email)
20 | dt Email:
21 | dd: a(href="mailto:#{meta.email}") #{meta.email}
22 | - if (meta.homepage)
23 | dt Homepage:
24 | dd: a(href="#{meta.homepage}", target="_blank") #{meta.homepage}
25 | - if (meta.twitter)
26 | dd: a(href="#{meta.twitter}", target="_blank") Twitter
27 | - if (meta.dribble)
28 | dd: a(href="#{meta.dribble}", target="_blank") Dribble
29 | - if (meta.github)
30 | dd: a(href="#{meta.github}", target="_blank") Github
31 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/scaffolding.less:
--------------------------------------------------------------------------------
1 | //
2 | // Scaffolding
3 | // --------------------------------------------------
4 |
5 |
6 | // Body reset
7 | // -------------------------
8 |
9 | body {
10 | margin: 0;
11 | font-family: @baseFontFamily;
12 | font-size: @baseFontSize;
13 | line-height: @baseLineHeight;
14 | color: @textColor;
15 | background-color: @bodyBackground;
16 | }
17 |
18 |
19 | // Links
20 | // -------------------------
21 |
22 | a {
23 | color: @linkColor;
24 | text-decoration: none;
25 | }
26 | a:hover {
27 | color: @linkColorHover;
28 | text-decoration: underline;
29 | }
30 |
31 |
32 | // Images
33 | // -------------------------
34 |
35 | // Rounded corners
36 | .img-rounded {
37 | .border-radius(6px);
38 | }
39 |
40 | // Add polaroid-esque trim
41 | .img-polaroid {
42 | padding: 4px;
43 | background-color: #fff;
44 | border: 1px solid #ccc;
45 | border: 1px solid rgba(0,0,0,.2);
46 | .box-shadow(0 1px 3px rgba(0,0,0,.1));
47 | }
48 |
49 | // Perfect circle
50 | .img-circle {
51 | .border-radius(500px); // crank the border-radius so it works with most reasonably sized images
52 | }
53 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright (C) 2011 by Vitaly Puzrin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/lib/init/assets/build_i18n_files.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // stdlib
8 | var fs = require('fs');
9 | var path = require('path');
10 |
11 |
12 | // 3rd-party
13 | var async = require('nlib').Vendor.Async;
14 | var fstools = require('nlib').Vendor.FsTools;
15 | var JASON = require('nlib').Vendor.JASON;
16 |
17 |
18 | ////////////////////////////////////////////////////////////////////////////////
19 |
20 |
21 | // buildI18nFiles(root, callback(err)) -> Void
22 | // - root (String): Pathname where to save i18n.js files.
23 | // - callback (Function): Executed once everything is done.
24 | //
25 | // Writes i18n.js file.
26 | //
27 | module.exports = function buildI18nFiles(root, callback) {
28 | var chunks = [];
29 |
30 | nodeca.config.locales.enabled.forEach(function (lang) {
31 | var data = nodeca.runtime.i18n.getCompiledData(lang);
32 | chunks.push(
33 | 'nodeca.runtime.i18n.load(' +
34 | JSON.stringify(lang) + ',' +
35 | JASON.stringify(data) +
36 | ');'
37 | );
38 | });
39 |
40 | fs.writeFile(path.join(root, 'i18n.js'), chunks.join('\n'), callback);
41 | };
42 |
--------------------------------------------------------------------------------
/INSTALL.md:
--------------------------------------------------------------------------------
1 | installation instruction
2 |
3 | ## Install node.js
4 |
5 | Install build dependencies of node:
6 |
7 | sudo apt-get install build-essential libssl-dev
8 | sudo apt-get install git curl
9 | git clone git://github.com/creationix/nvm.git ~/.nvm
10 |
11 | Add following code into the end of your shell startup script (`.bashrc` for BASH):
12 |
13 | if [ -s "$HOME/.nvm/nvm.sh" ] ; then
14 | . ~/.nvm/nvm.sh # Loads NVM into a shell session.
15 | fi
16 |
17 | Reopen terminal. Install node (long), and set default version:
18 |
19 | nvm install v0.8.8
20 | nvm alias default 0.8
21 |
22 | ## Install Fontomas
23 |
24 | sudo apt-get install zip
25 | git clone git://github.com/nodeca/fontomas.git fontomas
26 | cd fontomas
27 | git submodule init
28 | git submodule update
29 | cd support/font-builder
30 | sudo make dev-deps
31 | make support
32 |
33 | Then, depending on your installation type, run:
34 |
35 | - `npm install` for production
36 | - `make dev-setup` for development
37 |
38 | ## Run Fontomas server
39 |
40 | make app-start
41 |
42 | Now you can point your browser to the page http://localhost:3000
43 |
44 | ## Rebuilding embedded fonts
45 |
46 | Detailed description will be added soon.
47 |
48 | make rebuild-fonts
49 |
--------------------------------------------------------------------------------
/lib/stats.js:
--------------------------------------------------------------------------------
1 | /*global nodeca*/
2 |
3 |
4 | 'use strict';
5 |
6 |
7 | // stdlib
8 | var path = require('path');
9 | var fs = require('fs');
10 |
11 |
12 | function start_logger(file) {
13 | var size = path.existsSync(file) ? fs.statSync(file).size : 0;
14 |
15 | return {write: function (str) {
16 | fs.open(file, 'a', function (err, fd) {
17 | if (err) {
18 | nodeca.logger.error("Failed open stats log file: " + err);
19 | return;
20 | }
21 |
22 | fs.write(fd, str, size, Buffer.byteLength(str), function (err) {
23 | if (err) {
24 | nodeca.logger.error("Failed write to stats log file: " + err);
25 | }
26 |
27 | fs.close(fd);
28 | });
29 | });
30 | }};
31 | }
32 |
33 |
34 | var logfile = path.join(nodeca.runtime.apps[0].root, 'log/fontello-stats.log');
35 | var logger = start_logger(logfile);
36 |
37 |
38 | module.exports.push = function (stats) {
39 | var parts = [];
40 |
41 | try {
42 | parts.push((new Date).toISOString());
43 | parts.push(stats.user);
44 | parts.push(stats.glyphs);
45 | parts.push(stats.time);
46 |
47 | logger.write(parts.join('\t') + "\n");
48 | } catch (err) {
49 | nodeca.logger.warn("Failed write stat results");
50 | nodeca.logger.error(err);
51 | }
52 | };
53 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/responsive.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap Responsive v2.1.1
3 | *
4 | * Copyright 2012 Twitter, Inc
5 | * Licensed under the Apache License v2.0
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Designed and built with all the love in the world @twitter by @mdo and @fat.
9 | */
10 |
11 |
12 | // Responsive.less
13 | // For phone and tablet devices
14 | // -------------------------------------------------------------
15 |
16 |
17 | // REPEAT VARIABLES & MIXINS
18 | // -------------------------
19 | // Required since we compile the responsive stuff separately
20 |
21 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc
22 | @import "mixins.less";
23 |
24 |
25 | // RESPONSIVE CLASSES
26 | // ------------------
27 |
28 | @import "responsive-utilities.less";
29 |
30 |
31 | // MEDIA QUERIES
32 | // ------------------
33 |
34 | // Large desktops
35 | @import "responsive-1200px-min.less";
36 |
37 | // Tablets to regular desktops
38 | @import "responsive-768px-979px.less";
39 |
40 | // Phones to portrait tablets and narrow desktops
41 | @import "responsive-767px-max.less";
42 |
43 |
44 | // RESPONSIVE NAVBAR
45 | // ------------------
46 |
47 | // From 979px and below, show a button to toggle navbar contents
48 | @import "responsive-navbar.less";
49 |
--------------------------------------------------------------------------------
/lib/init/assets/compile_views.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /*global nodeca*/
5 |
6 |
7 | // stdlib
8 | var fs = require('fs');
9 | var path = require('path');
10 |
11 |
12 | // 3rd-party
13 | var views = require('nlib').Views;
14 | var async = require('nlib').Vendor.Async;
15 | var _ = require('nlib').Vendor.Underscore;
16 |
17 |
18 | ////////////////////////////////////////////////////////////////////////////////
19 |
20 |
21 | // compileViews(root, callback(err)) -> Void
22 | // - root (String): Pathname containing views directories.
23 | // - callback (Function): Executed once everything is done.
24 | //
25 | // Compiles all views, inject them into `nodeca.runtime.views` for the
26 | // server and writes browserified versions into `views.js`.
27 | //
28 | module.exports = function compileViews(root, callback) {
29 | views.collect(path.join(nodeca.runtime.apps[0].root, 'views'), function (err, tree) {
30 | if (err) {
31 | callback(err);
32 | return;
33 | }
34 |
35 | // set server-side views tree
36 | nodeca.runtime.views = views.buildServerTree(tree);
37 |
38 | // write client-side views tree
39 | views.writeClientTree(
40 | path.join(root, 'views.js'),
41 | tree,
42 | 'this.nodeca.views',
43 | callback
44 | );
45 | });
46 | };
47 |
--------------------------------------------------------------------------------
/assets/stylesheets/ui/panes/codes_editor.styl:
--------------------------------------------------------------------------------
1 | .result-glyph
2 | float left
3 | width 64px
4 | margin 0 10px 10px 0
5 | color #fff
6 | //background-color #888
7 | //border-left 1px solid #888
8 | //border-right 1px solid #888
9 | background-color #444
10 | border-left 1px solid #444
11 | border-right 1px solid #444
12 | border-radius 6px
13 |
14 | .top
15 | text-align center
16 | line-height 16px
17 | font-size 14px
18 |
19 | .center
20 | height 64px
21 | line-height 64px
22 | text-align center
23 | background-color #fff
24 | color #444
25 | font-size 24px
26 |
27 | .bottom
28 | text-align center
29 | line-height 16px
30 | font-size 10px
31 |
32 |
33 | //&.mapping-matched
34 | // border-color #444
35 | // background-color #444
36 |
37 | .code-prefix, .code-editable, .char-editable
38 | display inline-block
39 | margin 3px 0
40 | .char-editable
41 | padding 0 3px
42 |
43 |
44 | &:hover
45 | .char-editable, .code-editable
46 | background-color #888
47 | border-radius 2px
48 | cursor pointer
49 |
50 | .char-editable, .code-editable
51 | &:focus
52 | outline none
53 | box-shadow 0 0 2px #fff
54 | background-color white
55 | color grayDark
56 | border-radius 2px
57 | cursor auto
58 |
--------------------------------------------------------------------------------
/client/util.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 | "use strict";
4 |
5 |
6 | module.exports.notify = function (type, options, message) {
7 | if (!message) {
8 | message = options;
9 | options = {};
10 | }
11 |
12 | $.noty(_.extend({layout: 'topRight'}, options, {
13 | type: type,
14 | text: message,
15 | theme: 'noty_theme_twitter'
16 | }));
17 | };
18 |
19 |
20 | // Int to char, with fix for big numbers
21 | // see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/fromCharCode
22 | module.exports.fixedFromCharCode = function (code) {
23 | /*jshint bitwise: false*/
24 | if (code > 0xffff) {
25 | code -= 0x10000;
26 | var surrogate1 = 0xd800 + (code >> 10),
27 | surrogate2 = 0xdc00 + (code & 0x3ff);
28 | return String.fromCharCode(surrogate1, surrogate2);
29 | } else {
30 | return String.fromCharCode(code);
31 | }
32 | };
33 |
34 |
35 | // Char to Int, with fix for big numbers
36 | module.exports.fixedCharCodeAt = function (char) {
37 | /*jshint bitwise: false*/
38 | var char1 = char.charCodeAt(0),
39 | char2 = char.charCodeAt(1);
40 |
41 | if ((char.length >= 2) &&
42 | ((char1 & 0xfc00) === 0xd800) &&
43 | ((char2 & 0xfc00) === 0xdc00)) {
44 | return 0x10000 + ((char1 - 0xd800) << 10) + (char2 - 0xdc00);
45 | } else {
46 | return char1;
47 | }
48 | };
49 |
--------------------------------------------------------------------------------
/assets/stylesheets/bootstrap_override.styl:
--------------------------------------------------------------------------------
1 | // Buttons tweaks
2 | //
3 | .btn
4 | font-family sansWideFontFamily
5 | background-image none
6 | transition background-color 0.5s ease
7 | &:hover
8 | transition background-color 0.5s ease
9 | .btn-icon-only
10 | min-width 40px
11 | &:before
12 | margin 0
13 | .btn-info
14 | font-weight bold
15 | .btn.disabled, .btn[disabled]
16 | opacity .4
17 |
18 | .input-append
19 | whitespace nowrap
20 |
21 |
22 | // Focus style tweak
23 | //
24 | input, textarea
25 | box-shadow 0 1px 1px rgba(0, 0, 0, .3) inset
26 | input:focus,
27 | textarea:focus
28 | border-color rgba(168,82,82,.8)
29 | outline 0
30 | /* IE6-9 */
31 | outline thin dotted \9
32 | box-shadow 0 1px 1px rgba(0, 0, 0, .075) inset, 0 0 8px rgba(168, 82, 82, .6)
33 |
34 |
35 | // Search icon tweak
36 | //
37 | .search-form
38 | .search-query
39 | padding-left 25px
40 | .icon-search
41 | position absolute
42 | color gray
43 | top 6px
44 | left 8px
45 | // restore font size
46 | font-size 14px
47 |
48 | // Fix vertical offset for toolbar inputs
49 | //
50 | .btn-group > input
51 | margin-bottom 0
52 |
53 | // When we like to hide ugly file input, but can't use display:none, because
54 | // Chromium will miss events. So, use .invisible, but position out of screen
55 | //
56 | input[type="file"].invisible
57 | position absolute
58 | left -10000px
59 |
60 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/bootstrap-responsive.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap Responsive v2.0.3
3 | *
4 | * Copyright 2012 Twitter, Inc
5 | * Licensed under the Apache License v2.0
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Designed and built with all the love in the world @twitter by @mdo and @fat.
9 | */
10 |
11 |
12 | // Responsive.less
13 | // For phone and tablet devices
14 | // -------------------------------------------------------------
15 |
16 |
17 | // REPEAT VARIABLES & MIXINS
18 | // -------------------------
19 | // Required since we compile the responsive stuff separately
20 |
21 | @import "src/less/variables.less";
22 | @import "var_override.less"; // Modify this for custom colors, font-sizes, etc
23 | @import "src/less/mixins.less";
24 |
25 |
26 | // RESPONSIVE CLASSES
27 | // ------------------
28 |
29 | @import "src/less/responsive-utilities.less";
30 |
31 |
32 | // MEDIA QUERIES
33 | // ------------------
34 |
35 | // Phones to portrait tablets and narrow desktops
36 | //@import "src/less/responsive-767px-max.less";
37 |
38 | // Tablets to regular desktops
39 | //@import "src/less/responsive-768px-979px.less";
40 |
41 | // Large desktops
42 | @import "src/less/responsive-1200px-min.less";
43 |
44 |
45 | // RESPONSIVE NAVBAR
46 | // ------------------
47 |
48 | // From 979px and below, show a button to toggle navbar contents
49 | //@import "src/less/responsive-navbar.less";
50 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/responsive-utilities.less:
--------------------------------------------------------------------------------
1 | //
2 | // Responsive: Utility classes
3 | // --------------------------------------------------
4 |
5 |
6 | // Hide from screenreaders and browsers
7 | // Credit: HTML5 Boilerplate
8 | .hidden {
9 | display: none;
10 | visibility: hidden;
11 | }
12 |
13 | // Visibility utilities
14 |
15 | // For desktops
16 | .visible-phone { display: none !important; }
17 | .visible-tablet { display: none !important; }
18 | .hidden-phone { }
19 | .hidden-tablet { }
20 | .hidden-desktop { display: none !important; }
21 | .visible-desktop { display: inherit !important; }
22 |
23 | // Tablets & small desktops only
24 | @media (min-width: 768px) and (max-width: 979px) {
25 | // Hide everything else
26 | .hidden-desktop { display: inherit !important; }
27 | .visible-desktop { display: none !important ; }
28 | // Show
29 | .visible-tablet { display: inherit !important; }
30 | // Hide
31 | .hidden-tablet { display: none !important; }
32 | }
33 |
34 | // Phones only
35 | @media (max-width: 767px) {
36 | // Hide everything else
37 | .hidden-desktop { display: inherit !important; }
38 | .visible-desktop { display: none !important; }
39 | // Show
40 | .visible-phone { display: inherit !important; } // Use inherit to restore previous behavior
41 | // Hide
42 | .hidden-phone { display: none !important; }
43 | }
44 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/thumbnails.less:
--------------------------------------------------------------------------------
1 | //
2 | // Thumbnails
3 | // --------------------------------------------------
4 |
5 |
6 | // Note: `.thumbnails` and `.thumbnails > li` are overriden in responsive files
7 |
8 | // Make wrapper ul behave like the grid
9 | .thumbnails {
10 | margin-left: -@gridGutterWidth;
11 | list-style: none;
12 | .clearfix();
13 | }
14 | // Fluid rows have no left margin
15 | .row-fluid .thumbnails {
16 | margin-left: 0;
17 | }
18 |
19 | // Float li to make thumbnails appear in a row
20 | .thumbnails > li {
21 | float: left; // Explicity set the float since we don't require .span* classes
22 | margin-bottom: @baseLineHeight;
23 | margin-left: @gridGutterWidth;
24 | }
25 |
26 | // The actual thumbnail (can be `a` or `div`)
27 | .thumbnail {
28 | display: block;
29 | padding: 4px;
30 | line-height: @baseLineHeight;
31 | border: 1px solid #ddd;
32 | .border-radius(4px);
33 | .box-shadow(0 1px 3px rgba(0,0,0,.055));
34 | .transition(all .2s ease-in-out);
35 | }
36 | // Add a hover state for linked versions only
37 | a.thumbnail:hover {
38 | border-color: @linkColor;
39 | .box-shadow(0 1px 4px rgba(0,105,214,.25));
40 | }
41 |
42 | // Images and captions
43 | .thumbnail > img {
44 | display: block;
45 | max-width: 100%;
46 | margin-left: auto;
47 | margin-right: auto;
48 | }
49 | .thumbnail .caption {
50 | padding: 9px;
51 | color: @gray;
52 | }
53 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/alerts.less:
--------------------------------------------------------------------------------
1 | //
2 | // Alerts
3 | // --------------------------------------------------
4 |
5 |
6 | // Base styles
7 | // -------------------------
8 |
9 | .alert {
10 | padding: 8px 35px 8px 14px;
11 | margin-bottom: @baseLineHeight;
12 | text-shadow: 0 1px 0 rgba(255,255,255,.5);
13 | background-color: @warningBackground;
14 | border: 1px solid @warningBorder;
15 | .border-radius(4px);
16 | color: @warningText;
17 | }
18 | .alert h4 {
19 | margin: 0;
20 | }
21 |
22 | // Adjust close link position
23 | .alert .close {
24 | position: relative;
25 | top: -2px;
26 | right: -21px;
27 | line-height: @baseLineHeight;
28 | }
29 |
30 |
31 | // Alternate styles
32 | // -------------------------
33 |
34 | .alert-success {
35 | background-color: @successBackground;
36 | border-color: @successBorder;
37 | color: @successText;
38 | }
39 | .alert-danger,
40 | .alert-error {
41 | background-color: @errorBackground;
42 | border-color: @errorBorder;
43 | color: @errorText;
44 | }
45 | .alert-info {
46 | background-color: @infoBackground;
47 | border-color: @infoBorder;
48 | color: @infoText;
49 | }
50 |
51 |
52 | // Block alerts
53 | // -------------------------
54 |
55 | .alert-block {
56 | padding-top: 14px;
57 | padding-bottom: 14px;
58 | }
59 | .alert-block > p,
60 | .alert-block > ul {
61 | margin-bottom: 0;
62 | }
63 | .alert-block p + p {
64 | margin-top: 5px;
65 | }
66 |
--------------------------------------------------------------------------------
/lib/init/assets/mincer.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // stdlib
8 | var fs = require('fs');
9 | var path = require('path');
10 |
11 |
12 | // 3rd-party
13 | var Mincer = require('mincer');
14 | var nib = require('nib');
15 |
16 |
17 | // internal
18 | var environment = require('./mincer/environment');
19 | var manifest = require('./mincer/manifest');
20 |
21 |
22 | ////////////////////////////////////////////////////////////////////////////////
23 |
24 |
25 | //
26 | // set custom logger for the Mincer
27 | //
28 |
29 | Mincer.logger.use(nodeca.logger.getLogger('system'));
30 |
31 | //
32 | // Add some funky stuff to Stylus
33 | //
34 |
35 | Mincer.StylusEngine.registerConfigurator(function (style) {
36 | style.use(nib());
37 | style.define('import-dir', require('./mincer/stylus/import-dir'));
38 | });
39 |
40 |
41 | ////////////////////////////////////////////////////////////////////////////////
42 |
43 |
44 | module.exports = function mincer(root, callback) {
45 | var env = environment.configure(root).index,
46 | output = path.join(nodeca.runtime.apps[0].root, 'public', 'assets');
47 |
48 | //
49 | // compile assets
50 | //
51 |
52 | manifest.compile(output, env, function (err, data) {
53 | if (err) {
54 | callback(err);
55 | return;
56 | }
57 |
58 | nodeca.runtime.assets = { environment: env, manifest: data };
59 | callback();
60 | });
61 | };
62 |
--------------------------------------------------------------------------------
/client/ui/tabs.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | // prevent the event from bubbling to ancestor elements
8 | function stopPropagation(event) {
9 | event.preventDefault();
10 | event.stopPropagation();
11 | }
12 |
13 |
14 | module.exports = Backbone.View.extend({
15 | el: '#tabs',
16 |
17 | $preview_tab: null,
18 | $editor_tab: null,
19 |
20 | initialize: function () {
21 | // init tabs plugin
22 | this.$el.tab('show');
23 |
24 | // add submenu activation
25 | this.$('a[data-toggle="tab"]').on('shown', function (event) {
26 | var $curr = $(event.target),
27 | $prev = $(event.relatedTarget);
28 |
29 | $($prev.data('submenu')).removeClass('active');
30 | $($curr.data('submenu')).addClass('active');
31 | });
32 |
33 | this.$preview_tab = this.$('a[href="#preview"]');
34 | this.$editor_tab = this.$('a[href="#codes-editor"]');
35 |
36 | // disable click handler of tabs plugin on preview and result tabs
37 | this.$preview_tab.add(this.$editor_tab).on('click', stopPropagation);
38 | },
39 |
40 | activate: function (id) {
41 | this.$('a[href="' + id + '"]').tab('show');
42 | },
43 |
44 | setGlyphsCount: function (count) {
45 | var $tabs = this.$preview_tab.add(this.$editor_tab);
46 |
47 | $tabs.toggleClass('disabled', !count);
48 | $tabs[!count ? 'on' : 'off']('click', stopPropagation);
49 | }
50 | });
51 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/code.less:
--------------------------------------------------------------------------------
1 | //
2 | // Code (inline and blocK)
3 | // --------------------------------------------------
4 |
5 |
6 | // Inline and block code styles
7 | code,
8 | pre {
9 | padding: 0 3px 2px;
10 | #font > #family > .monospace;
11 | font-size: @baseFontSize - 2;
12 | color: @grayDark;
13 | .border-radius(3px);
14 | }
15 |
16 | // Inline code
17 | code {
18 | padding: 2px 4px;
19 | color: #d14;
20 | background-color: #f7f7f9;
21 | border: 1px solid #e1e1e8;
22 | }
23 |
24 | // Blocks of code
25 | pre {
26 | display: block;
27 | padding: (@baseLineHeight - 1) / 2;
28 | margin: 0 0 @baseLineHeight / 2;
29 | font-size: @baseFontSize - 1; // 14px to 13px
30 | line-height: @baseLineHeight;
31 | word-break: break-all;
32 | word-wrap: break-word;
33 | white-space: pre;
34 | white-space: pre-wrap;
35 | background-color: #f5f5f5;
36 | border: 1px solid #ccc; // fallback for IE7-8
37 | border: 1px solid rgba(0,0,0,.15);
38 | .border-radius(4px);
39 |
40 | // Make prettyprint styles more spaced out for readability
41 | &.prettyprint {
42 | margin-bottom: @baseLineHeight;
43 | }
44 |
45 | // Account for some code outputs that place code tags in pre tags
46 | code {
47 | padding: 0;
48 | color: inherit;
49 | background-color: transparent;
50 | border: 0;
51 | }
52 | }
53 |
54 | // Enable scrollable blocks of code
55 | .pre-scrollable {
56 | max-height: 340px;
57 | overflow-y: scroll;
58 | }
--------------------------------------------------------------------------------
/client/init.js:
--------------------------------------------------------------------------------
1 | /*global $, nodeca*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | module.exports = function () {
8 | $(function () {
9 | nodeca.client.init.app();
10 |
11 | //
12 | // Social buttons defered load - after all
13 | //
14 |
15 | setTimeout(function () {
16 |
17 | // Twitter buttons
18 |
19 | (function(d,s,id) {
20 | var js, fjs = d.getElementsByTagName(s)[0];
21 |
22 | if (!d.getElementById(id)) {
23 | js = d.createElement(s);
24 | js.id = id;
25 | js.src = "//platform.twitter.com/widgets.js";
26 |
27 | fjs.parentNode.insertBefore(js,fjs);
28 | }
29 | }(document, "script", "twitter-wjs"));
30 |
31 | // Google +1
32 |
33 | (function() {
34 | var po = document.createElement('script');
35 |
36 | po.type = 'text/javascript';
37 | po.async = true;
38 | po.src = 'https://apis.google.com/js/plusone.js';
39 |
40 | var s = document.getElementsByTagName('script')[0];
41 | s.parentNode.insertBefore(po, s);
42 | }());
43 |
44 | // Flattr
45 | /*
46 |
47 | (function() {
48 | var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
49 | s.type = 'text/javascript';
50 | s.async = true;
51 | s.src = '//api.flattr.com/js/0.6/load.js?mode=auto';
52 | t.parentNode.insertBefore(s, t);
53 | }());
54 | */
55 |
56 | }, 2000);
57 | });
58 | };
59 |
--------------------------------------------------------------------------------
/config/logger.yml:
--------------------------------------------------------------------------------
1 | #
2 | # Logger configuration
3 | #
4 |
5 | logger:
6 |
7 | options:
8 |
9 | #
10 | # Global minimal error level
11 | #
12 |
13 | level: debug
14 |
15 | #
16 | # Appenders options
17 | #
18 |
19 | file:
20 | logSize: 10 # Max MB per log file
21 | backups: 5 # Amount of "old" log files
22 |
23 | #
24 | # Logger categories
25 | #
26 |
27 | system:
28 | - level: debug
29 | file: log/system.log
30 | - level: error
31 | file: log/system-error.log
32 |
33 | server.static:
34 | - level: debug
35 | file: log/static.log
36 | - level: error
37 | file: log/static-error.log
38 |
39 | server.assets:
40 | - level: debug
41 | file: log/static.log
42 | - level: error
43 | file: log/static-error.log
44 |
45 | server.font.download:
46 | - level: debug
47 | file: log/static.log
48 | - level: error
49 | file: log/static-error.log
50 |
51 | server.font:
52 | - level: debug
53 | file: log/generator.log
54 | - level: error
55 | file: log/generator-error.log
56 |
57 | server:
58 | - level: debug
59 | file: log/server.log
60 | - level: error
61 | file: log/server-error.log
62 |
63 | rpc:
64 | - level: debug
65 | file: log/rpc.log
66 | - level: error
67 | file: log/rpc-error.log
68 |
69 |
70 | #^production:
71 | # options:
72 | # logger:
73 | # level: info
74 |
75 |
76 | #
77 | # vim:syntax=yaml
78 |
--------------------------------------------------------------------------------
/server/assets.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /*global nodeca*/
5 |
6 |
7 | // 3rd-party
8 | var Mincer = require('mincer');
9 |
10 |
11 | // internal
12 | var logger = nodeca.logger.getLogger('server.assets');
13 |
14 |
15 | ////////////////////////////////////////////////////////////////////////////////
16 |
17 |
18 | var server;
19 |
20 |
21 |
22 |
23 | // Formats and writes log event into our logger
24 | //
25 | function assets_logger(level, event) {
26 | logger[level]('%s - "%s %s HTTP/%s" %d "%s" - %s',
27 | event.remoteAddress,
28 | event.method,
29 | event.url,
30 | event.httpVersion,
31 | event.code,
32 | event.headers['user-agent'],
33 | event.message);
34 | }
35 |
36 |
37 |
38 | // helper to pass request to the lazy-loaded miner server
39 | function call_mincer_server(req, res) {
40 | var assets;
41 |
42 | if (!server) {
43 | assets = nodeca.runtime.assets,
44 | server = new Mincer.Server(assets.environment, assets.manifest);
45 | server.log = assets_logger;
46 | }
47 |
48 | server.handle(req, res);
49 | }
50 |
51 |
52 | ////////////////////////////////////////////////////////////////////////////////
53 |
54 |
55 | module.exports = function (params, callback) {
56 | if (!this.origin.http) {
57 | callback({statusCode: 400, body: "HTTP ONLY"});
58 | return;
59 | }
60 |
61 | this.origin.http.req.url = params.path;
62 | call_mincer_server(this.origin.http.req, this.origin.http.res);
63 | };
64 |
--------------------------------------------------------------------------------
/lib/init/assets.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // 3rd-party
8 | var async = require('nlib').Vendor.Async;
9 | var fstools = require('nlib').Vendor.FsTools;
10 |
11 |
12 | ////////////////////////////////////////////////////////////////////////////////
13 |
14 |
15 | /**
16 | *
17 | * RESULTING STRUCTURE
18 | *
19 | * .
20 | * ├╴ i18n.js
21 | * ├╴ views.js
22 | * ╰╴ api.js
23 | *
24 | **/
25 |
26 | ////////////////////////////////////////////////////////////////////////////////
27 |
28 |
29 | module.exports = function (next) {
30 | var tmp, environment;
31 |
32 | try {
33 | tmp = fstools.tmpdir('/tmp/fontello.XXXXX');
34 | } catch (err) {
35 | next(err);
36 | return;
37 | }
38 |
39 | // schedule files cleanup upon normal exit
40 | process.on('exit', function (code) {
41 | if (0 !== +code) {
42 | console.warn("Unclean exit. Bundled files left in '" + tmp + "'");
43 | return;
44 | }
45 |
46 | try {
47 | console.warn("Removing '" + tmp + "'...");
48 | fstools.removeSync(tmp);
49 | } catch(err) {
50 | console.warn("Failed remove '" + tmp + "'... " + String(err));
51 | }
52 | });
53 |
54 | async.series([
55 | async.apply(fstools.mkdir, tmp),
56 | async.apply(require('./assets/build_api_tree'), tmp),
57 | async.apply(require('./assets/build_i18n_files'), tmp),
58 | async.apply(require('./assets/compile_views'), tmp),
59 | async.apply(require('./assets/mincer'), tmp)
60 | ], function (err/*, results*/) {
61 | next(err);
62 | });
63 | };
64 |
--------------------------------------------------------------------------------
/lib/init/server/http.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // stdlib
8 | var url = require('url');
9 |
10 |
11 | // 3rd-party
12 | var qs = require('qs');
13 |
14 |
15 | // internal
16 | var env = require('../../env');
17 | var handle_http = require('./http/handle_http');
18 | var handle_rpc = require('./http/handle_rpc');
19 |
20 |
21 | ////////////////////////////////////////////////////////////////////////////////
22 |
23 |
24 | // Attach HTTP application server to the given `server`
25 | //
26 | module.exports.attach = function attach(server, next) {
27 |
28 | //
29 | // For each connection - update timeout & disable buffering
30 | //
31 |
32 | server.addListener("connection", function (socket) {
33 | socket.setTimeout(15 * 1000);
34 | socket.setNoDelay();
35 | });
36 |
37 | //
38 | // Define application runner
39 | //
40 |
41 | server.on('request', function (req, res) {
42 | var parsed = url.parse(req.url),
43 | handle = ('/rpc' === parsed.pathname) ? handle_rpc : handle_http,
44 | data = '';
45 |
46 | req.query = qs.parse(parsed.query || '');
47 | req.pathname = parsed.pathname;
48 |
49 | // start harvesting POST data
50 | req.on('data', function (chunk) {
51 | data += chunk;
52 | });
53 |
54 | // when done, merge post params and handle request
55 | req.on('end', function () {
56 | req.params = _.defaults(qs.parse(data), req.query);
57 | handle(req, res);
58 | });
59 | });
60 |
61 | //
62 | // HTTP server is ready
63 | //
64 |
65 | next();
66 |
67 | };
68 |
--------------------------------------------------------------------------------
/fontello.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 |
4 | /*global nodeca*/
5 |
6 |
7 | "use strict";
8 |
9 |
10 | var app = require('nlib').Application.create({
11 | name: 'fontomas',
12 | root: __dirname
13 | });
14 |
15 |
16 | //
17 | // Preset application version
18 | //
19 |
20 |
21 | nodeca.runtime.version = require('./package.json').version;
22 |
23 |
24 | //
25 | // Catch unexpected exceptions
26 | //
27 |
28 |
29 | process.on('uncaughtException', function (err) {
30 | var msg, stack;
31 |
32 | try {
33 | msg = 'UNCAUGHT EXCEPTION !!! ' + String(err);
34 | stack = err.stack || '';
35 |
36 | if (err.original) {
37 | msg += '\n' + String(err.original);
38 | stack = err.original.stack || stack;
39 | }
40 |
41 | msg += '\n' + stack.split('\n').slice(1).join('\n');
42 |
43 | nodeca.logger.fatal(msg);
44 | } catch (loggerError) {
45 | // THIS SHOULD NEVER-EVER-EVER HAPPEN -- THIS IS A WORST CASE SCENARIO
46 | // USAGE: ./nodeca.js 2>/var/log/nodeca-cf.log
47 | process.stderr.write('\nLogger failed write: ' + loggerError.stack);
48 | process.stderr.write('\nOriginal error happened: ' + msg);
49 | }
50 | });
51 |
52 |
53 | //
54 | // Handle SIGnals
55 | //
56 |
57 |
58 | function shutdown_gracefully() {
59 | nodeca.logger.info('Shutting down...');
60 | process.exit(0);
61 | }
62 |
63 |
64 | // shutdown gracefully on SIGTERM :
65 | process.on('SIGTERM', shutdown_gracefully);
66 | process.on('SIGINT', shutdown_gracefully);
67 |
68 |
69 | //
70 | // Register filters
71 | //
72 |
73 |
74 | require('./lib/filters');
75 |
76 |
77 | //
78 | // Run application
79 | //
80 |
81 |
82 | app.run();
83 |
--------------------------------------------------------------------------------
/support/font-templates/css/css.jade:
--------------------------------------------------------------------------------
1 | - if (_.any(glyphs, function (g) { return 0xffff < g.code; }))
2 | | @charset "UTF-8";
3 | != '\n'
4 | != '\n'
5 |
6 | :stylus_nowrap
7 | @font-face {
8 | font-family: '#{font.fontname}';
9 | src: url('../font/#{font.fontname}.eot');
10 | src: url('../font/#{font.fontname}.eot?#iefix') format('embedded-opentype'),
11 | url('../font/#{font.fontname}.woff') format('woff'),
12 | url('../font/#{font.fontname}.ttf') format('truetype'),
13 | url('../font/#{font.fontname}.svg##{font.fontname}') format('svg');
14 | font-weight: normal;
15 | font-style: normal;
16 | }
17 |
18 | [class^="icon-"], [class*=" icon-"]
19 | &:before
20 | font-family '#{font.fontname}'
21 | font-style normal
22 | font-weight normal
23 | speak none
24 |
25 | display inline-block
26 | text-decoration inherit
27 | width 1em
28 | margin-right .2em
29 | text-align center
30 | opacity .7
31 |
32 | /* Uncomment for 3D effect */
33 | /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
34 |
35 | /* fix buttons height */
36 | line-height 1em
37 |
38 | /* you can be more comfortable with increased icons size */
39 | /* font-size: 120%; */
40 |
41 | - var i, g, css, hex, chr
42 | - for (i in glyphs)
43 | - g = glyphs[i]
44 | - css = meta.css_prefix + g.css
45 | - hex = '\\' + g.code.toString(16)
46 | - chr = unichr(g.code)
47 | != '\n'
48 | - if (0xffff < g.code)
49 | | .#{css}:before { content: '#{chr}'; } /* '#{hex}' */
50 | - else
51 | | .#{css}:before { content: '#{hex}'; } /* '#{chr}' */
52 |
--------------------------------------------------------------------------------
/client/render.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /**
5 | * client
6 | **/
7 |
8 |
9 | /*global window, $, _, JASON, nodeca*/
10 |
11 |
12 | ////////////////////////////////////////////////////////////////////////////////
13 |
14 |
15 | var tzOffset = (new Date).getTimezoneOffset();
16 | var helpers = {};
17 |
18 |
19 | ////////////////////////////////////////////////////////////////////////////////
20 |
21 |
22 | helpers.t = nodeca.runtime.t;
23 |
24 |
25 | _.each(['asset_path', 'asset_include'], function (method) {
26 | helpers[method] = function () {
27 | throw method + '() is a server-side only helper, thus can be used in base layouts only.';
28 | };
29 | });
30 |
31 | helpers.link_to = function (name, params) {
32 | return nodeca.runtime.router.linkTo(name, params) || '#';
33 | };
34 |
35 | helpers.nodeca = function (path) {
36 | return !path ? nodeca : nodeca.shared.getByPath(nodeca, path);
37 | };
38 |
39 | // substitute JASON with JSON
40 | helpers.jason = JSON.stringify;
41 |
42 |
43 | ////////////////////////////////////////////////////////////////////////////////
44 |
45 |
46 | /**
47 | * client.render(apiPath[, locals[, layout]]) -> Void
48 | * - apiPath (String): Server method API path.
49 | * - locals (Object): Locals data for the renderer
50 | * - layout (String): Layout or layouts stack
51 | *
52 | * Renders view.
53 | **/
54 | module.exports = function render(apiPath, locals, layout) {
55 | if (!nodeca.shared.getByPath(nodeca.views, apiPath)) {
56 | throw new Error("View " + apiPath + " not found");
57 | }
58 |
59 | locals = _.extend(locals || {}, helpers);
60 | return nodeca.shared.render(nodeca.views, apiPath, locals, layout, true);
61 | };
62 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/pagination.less:
--------------------------------------------------------------------------------
1 | //
2 | // Pagination (multiple pages)
3 | // --------------------------------------------------
4 |
5 |
6 | .pagination {
7 | height: @baseLineHeight * 2;
8 | margin: @baseLineHeight 0;
9 | }
10 | .pagination ul {
11 | display: inline-block;
12 | .ie7-inline-block();
13 | margin-left: 0;
14 | margin-bottom: 0;
15 | .border-radius(3px);
16 | .box-shadow(0 1px 2px rgba(0,0,0,.05));
17 | }
18 | .pagination ul > li {
19 | display: inline;
20 | }
21 | .pagination ul > li > a,
22 | .pagination ul > li > span {
23 | float: left;
24 | padding: 0 14px;
25 | line-height: (@baseLineHeight * 2) - 2;
26 | text-decoration: none;
27 | background-color: @paginationBackground;
28 | border: 1px solid @paginationBorder;
29 | border-left-width: 0;
30 | }
31 | .pagination ul > li > a:hover,
32 | .pagination ul > .active > a,
33 | .pagination ul > .active > span {
34 | background-color: #f5f5f5;
35 | }
36 | .pagination ul > .active > a,
37 | .pagination ul > .active > span {
38 | color: @grayLight;
39 | cursor: default;
40 | }
41 | .pagination ul > .disabled > span,
42 | .pagination ul > .disabled > a,
43 | .pagination ul > .disabled > a:hover {
44 | color: @grayLight;
45 | background-color: transparent;
46 | cursor: default;
47 | }
48 | .pagination ul > li:first-child > a,
49 | .pagination ul > li:first-child > span {
50 | border-left-width: 1px;
51 | .border-radius(3px 0 0 3px);
52 | }
53 | .pagination ul > li:last-child > a,
54 | .pagination ul > li:last-child > span {
55 | .border-radius(0 3px 3px 0);
56 | }
57 |
58 | // Centered
59 | .pagination-centered {
60 | text-align: center;
61 | }
62 | .pagination-right {
63 | text-align: right;
64 | }
65 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/bootstrap.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v2.1.1
3 | *
4 | * Copyright 2012 Twitter, Inc
5 | * Licensed under the Apache License v2.0
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Designed and built with all the love in the world @twitter by @mdo and @fat.
9 | */
10 |
11 | // CSS Reset
12 | @import "reset.less";
13 |
14 | // Core variables and mixins
15 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc
16 | @import "mixins.less";
17 |
18 | // Grid system and page structure
19 | @import "scaffolding.less";
20 | @import "grid.less";
21 | @import "layouts.less";
22 |
23 | // Base CSS
24 | @import "type.less";
25 | @import "code.less";
26 | @import "forms.less";
27 | @import "tables.less";
28 |
29 | // Components: common
30 | @import "sprites.less";
31 | @import "dropdowns.less";
32 | @import "wells.less";
33 | @import "component-animations.less";
34 | @import "close.less";
35 |
36 | // Components: Buttons & Alerts
37 | @import "buttons.less";
38 | @import "button-groups.less";
39 | @import "alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less
40 |
41 | // Components: Nav
42 | @import "navs.less";
43 | @import "navbar.less";
44 | @import "breadcrumbs.less";
45 | @import "pagination.less";
46 | @import "pager.less";
47 |
48 | // Components: Popovers
49 | @import "modals.less";
50 | @import "tooltip.less";
51 | @import "popovers.less";
52 |
53 | // Components: Misc
54 | @import "thumbnails.less";
55 | @import "labels-badges.less";
56 | @import "progress-bars.less";
57 | @import "accordion.less";
58 | @import "carousel.less";
59 | @import "hero-unit.less";
60 |
61 | // Utility classes
62 | @import "utilities.less"; // Has to be last to override when necessary
63 |
--------------------------------------------------------------------------------
/cli/font_config.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca*/
5 |
6 |
7 | // nodeca
8 | var NLib = require('nlib');
9 |
10 |
11 | // 3rd-party
12 | var Async = NLib.Vendor.Async;
13 | var FsTools = NLib.Vendor.FsTools;
14 |
15 |
16 | // internal
17 | var fontConfig = require('../lib/font_config');
18 |
19 |
20 | module.exports.parserParameters= {
21 | version: nodeca.runtime.version,
22 | addHelp: true,
23 | help: 'prepare font configuration',
24 | description: 'prepare font configuration'
25 | };
26 |
27 |
28 | module.exports.commandLineArguments = [
29 | {
30 | args: ['-i', '--input'],
31 | options: {
32 | dest: 'input',
33 | help: 'user config',
34 | type: 'string',
35 | metavar: 'FILE',
36 | required: true
37 | }
38 | },
39 | {
40 | args: ['-o', '--output'],
41 | options: {
42 | dest: 'output',
43 | help: 'resulting config',
44 | type: 'string',
45 | metavar: 'FILE',
46 | required: true
47 | }
48 | }
49 | ];
50 |
51 |
52 | module.exports.run = function (args, callback) {
53 | Async.series([
54 | NLib.InitStages.loadServerApiSubtree,
55 | NLib.InitStages.loadSharedApiSubtree,
56 | NLib.InitStages.loadClientApiSubtree
57 | ], function (err) {
58 | var input, config;
59 |
60 | if (err) {
61 | callback(err);
62 | return;
63 | }
64 |
65 | try {
66 | input = require(args.input);
67 | } catch (err) {
68 | callback(err);
69 | return;
70 | }
71 |
72 | try {
73 | config = JSON.stringify(fontConfig(input));
74 | require('fs').writeFileSync(args.output, config);
75 | } catch (err) {
76 | callback(err);
77 | return;
78 | }
79 |
80 | callback();
81 | });
82 | };
83 |
--------------------------------------------------------------------------------
/lib/filters/fix_vhost.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /*global nodeca*/
5 |
6 |
7 | ////////////////////////////////////////////////////////////////////////////////
8 |
9 |
10 | // TODO: test before assigning this middleware
11 | var NOHOST_RE = new RegExp(
12 | '^(?:' +
13 | [ 'localhost',
14 | '\\d{1,3}(?:\\.\\d{1,3}){3}',
15 | '(?::1|[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){4,7})'
16 | ].join('|') +
17 | ')$', 'i');
18 |
19 | ////////////////////////////////////////////////////////////////////////////////
20 |
21 |
22 | // Filter middleware that interrupts request and sends redirect response with
23 | // new `Location` to default host if `Host` of request is unknown.
24 | //
25 | nodeca.filters.before('', { weight: -900 }, function fix_vhost(params, callback) {
26 | var http = this.origin.http, host;
27 |
28 | if (!http) {
29 | callback();
30 | return;
31 | }
32 |
33 | // if no host in config - then we accept any host
34 | if (!nodeca.config.listen.host || NOHOST_RE.test(nodeca.config.listen.host)) {
35 | callback();
36 | return;
37 | }
38 |
39 | host = (http.req.headers.host || '').split(':')[0];
40 |
41 | // known hostname
42 | if (host === nodeca.config.listen.host) {
43 | callback();
44 | return;
45 | }
46 |
47 | // fix hostname by redirect
48 | host = nodeca.config.listen.host;
49 | if (nodeca.config.listen.port && 80 !== nodeca.config.listen.port) {
50 | host += ':' + nodeca.config.listen.port;
51 | }
52 |
53 | // Don't use 301 redirect, because it locks browsers forever,
54 | // and can make troubles with adding new domains to project.
55 | // But add cache for 1 day as compensation.
56 | callback({ statusCode: 302,
57 | headers: {
58 | 'Location': 'http://' + host,
59 | 'Cache-Control': 'public, max-age=' + 60*60*24
60 | }
61 | });
62 | });
63 |
--------------------------------------------------------------------------------
/client/models/font.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | module.exports = Backbone.Model.extend({
8 | defaults: function () {
9 | return {
10 | id : null,
11 | font : null,
12 | meta : null,
13 | collapsed : false
14 | };
15 | },
16 |
17 |
18 | initialize: function (attributes) {
19 | this._glyphs = new (Backbone.Collection.extend({
20 | model: nodeca.client.models.glyph
21 | }))();
22 |
23 | // remove glyphs data array
24 | this.unset('glyphs', {silent: true});
25 |
26 | // process each glyph data
27 | _.each(attributes.glyphs || [], this.addGlyph, this);
28 | },
29 |
30 |
31 | getName: function () {
32 | return this.get('font').fontname;
33 | },
34 |
35 |
36 | addGlyph: function (data) {
37 | return this._glyphs.create({
38 | uid : data.uid,
39 | source : data,
40 | font : this
41 | });
42 | },
43 |
44 |
45 | eachGlyph: function (iterator, thisArg) {
46 | this._glyphs.each(iterator, thisArg);
47 | },
48 |
49 |
50 | getGlyph: function (criteria) {
51 | var g;
52 |
53 | if (criteria.uid) {
54 | g = this._glyphs.get(criteria.uid);
55 | }
56 |
57 | if (!g && criteria.code) {
58 | g = this._glyphs.find(function (g) {
59 | return criteria.code === g.get('source').code;
60 | });
61 | }
62 |
63 | if (!g && criteria.css) {
64 | g = this._glyphs.find(function (g) {
65 | return criteria.css === g.get('source').css;
66 | });
67 | }
68 |
69 | return g;
70 | },
71 |
72 |
73 | // Stub to prevent Backbone from reading or saving the model to the server.
74 | // Backbone calls `Backbone.sync()` function (on fetch/save/destroy)
75 | // if model doesn't have own `sync()` method.
76 | sync: function sync() {}
77 | });
78 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/tooltip.less:
--------------------------------------------------------------------------------
1 | //
2 | // Tooltips
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | .tooltip {
8 | position: absolute;
9 | z-index: @zindexTooltip;
10 | display: block;
11 | visibility: visible;
12 | padding: 5px;
13 | font-size: 11px;
14 | .opacity(0);
15 | &.in { .opacity(80); }
16 | &.top { margin-top: -3px; }
17 | &.right { margin-left: 3px; }
18 | &.bottom { margin-top: 3px; }
19 | &.left { margin-left: -3px; }
20 | }
21 |
22 | // Wrapper for the tooltip content
23 | .tooltip-inner {
24 | max-width: 200px;
25 | padding: 3px 8px;
26 | color: @tooltipColor;
27 | text-align: center;
28 | text-decoration: none;
29 | background-color: @tooltipBackground;
30 | .border-radius(4px);
31 | }
32 |
33 | // Arrows
34 | .tooltip-arrow {
35 | position: absolute;
36 | width: 0;
37 | height: 0;
38 | border-color: transparent;
39 | border-style: solid;
40 | }
41 | .tooltip {
42 | &.top .tooltip-arrow {
43 | bottom: 0;
44 | left: 50%;
45 | margin-left: -@tooltipArrowWidth;
46 | border-width: @tooltipArrowWidth @tooltipArrowWidth 0;
47 | border-top-color: @tooltipArrowColor;
48 | }
49 | &.right .tooltip-arrow {
50 | top: 50%;
51 | left: 0;
52 | margin-top: -@tooltipArrowWidth;
53 | border-width: @tooltipArrowWidth @tooltipArrowWidth @tooltipArrowWidth 0;
54 | border-right-color: @tooltipArrowColor;
55 | }
56 | &.left .tooltip-arrow {
57 | top: 50%;
58 | right: 0;
59 | margin-top: -@tooltipArrowWidth;
60 | border-width: @tooltipArrowWidth 0 @tooltipArrowWidth @tooltipArrowWidth;
61 | border-left-color: @tooltipArrowColor;
62 | }
63 | &.bottom .tooltip-arrow {
64 | top: 0;
65 | left: 50%;
66 | margin-left: -@tooltipArrowWidth;
67 | border-width: 0 @tooltipArrowWidth @tooltipArrowWidth;
68 | border-bottom-color: @tooltipArrowColor;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/support/font-templates/README.txt:
--------------------------------------------------------------------------------
1 | This webfont is generated by http://fontello.com open source project.
2 |
3 |
4 | ================================================================================
5 | Please, note, that you should obey original font licences, used to make this
6 | webfont pack. Details available in LICENSE.txt file.
7 |
8 | - Usually, it's enougth to publish content of LICENSE.txt file somewhere on your
9 | site in "About" section.
10 |
11 | - If your project is open-source, usually, it will be ok to make LICENSE.txt
12 | file publically available in your repository.
13 |
14 | - Fonts, used in Fontello, don't require to make clickable links on your site.
15 | But any kind of additional authors crediting is welcome.
16 | ================================================================================
17 |
18 |
19 | Attention for server setup (IE users and others)
20 | ------------------------------------------------
21 |
22 | You MUST setup server to reply with proper `mime-types` for font files. In other
23 | case, some browsers will fail to show fonts.
24 |
25 | Usually, `apache` already has necessary settings, but `nginx` and other
26 | webservers should be tuned. Here is list of mime types for our file extentions:
27 |
28 | - `application/vnd.ms-fontobject` - eot
29 | - `application/x-font-woff` - woff
30 | - `application/x-font-ttf` - ttf
31 | - `image/svg+xml` - svg
32 |
33 |
34 | Comments on archive content
35 | ---------------------------
36 |
37 | - /font/* - fonts in different formats
38 |
39 | - /css/* - different kinds of css, for all situations. Should be ok with
40 | twitter bootstrap. Also, you can skip style and assign icon classes
41 | directly to text elements
42 |
43 | - demo.html - demo file, to show your webfont content
44 |
45 | - LICENSE.txt - license info about source fonts, used to build your one.
46 |
47 | - config.json - keeps your settings. You can import it back to fontello anytime,
48 | to continue your work
49 |
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/README.txt:
--------------------------------------------------------------------------------
1 | This webfont is generated by http://fontello.com open source project.
2 |
3 |
4 | ================================================================================
5 | Please, note, that you should obey original font licences, used to make this
6 | webfont pack. Details available in LICENSE.txt file.
7 |
8 | - Usually, it's enougth to publish content of LICENSE.txt file somewhere on your
9 | site in "About" section.
10 |
11 | - If your project is open-source, usually, it will be ok to make LICENSE.txt
12 | file publically available in your repository.
13 |
14 | - Fonts, used in Fontello, don't require to make clickable links on your site.
15 | But any kind of additional authors crediting is welcome.
16 | ================================================================================
17 |
18 |
19 | Attention for server setup (IE users and others)
20 | ------------------------------------------------
21 |
22 | You MUST setup server to reply with proper `mime-types` for font files. In other
23 | case, some browsers will fail to show fonts.
24 |
25 | Usually, `apache` already has necessary settings, but `nginx` and other
26 | webservers should be tuned. Here is list of mime types for our file extentions:
27 |
28 | - `application/vnd.ms-fontobject` - eot
29 | - `application/x-font-woff` - woff
30 | - `application/x-font-ttf` - ttf
31 | - `image/svg+xml` - svg
32 |
33 |
34 | Comments on archive content
35 | ---------------------------
36 |
37 | - /font/* - fonts in different formats
38 |
39 | - /css/* - different kinds of css, for all situations. Should be ok with
40 | twitter bootstrap. Also, you can skip style and assign icon classes
41 | directly to text elements
42 |
43 | - demo.html - demo file, to show your webfont content
44 |
45 | - LICENSE.txt - license info about source fonts, used to build your one.
46 |
47 | - config.json - keeps your settings. You can import it back to fontello anytime,
48 | to continue your work
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "fontello",
3 | "version" : "2.0.4",
4 | "description" : "Iconic fonts scissors",
5 | "keywords" : ["icon", "font", "editor"],
6 | "homepage" : "https://github.com/nodeca/fontomas",
7 |
8 | "authors" : [
9 | "Roman I Shmelev (https://github.com/shmelev)",
10 | "Aleksey Zapparov (https://github.com/ixti)",
11 | "Vitaly Puzrin (https://github.com/puzrin)"
12 | ],
13 |
14 | "bugs" : { "url": "https://github.com/fontello/fontello/issues" },
15 | "license" : { "type": "MIT", "url": "https://github.com/fontello/fontello/blob/master/LICENSE" },
16 | "repository" : { "type": "git", "url": "git://github.com/fontello/fontello.git" },
17 |
18 | "main" : "./index.js",
19 |
20 | "dependencies" : {
21 | "nlib" : "git://github.com/nodeca/nlib.git#95cd4ca92ca8d3b2d251830c01a277202e7dc09d",
22 | "argparse" : "~0.1.3",
23 | "underscore" : "~1.3.3",
24 | "send" : "~0.0.3",
25 | "qs" : "~0.5.0",
26 | "mincer" : "~0.2.5",
27 | "stylus" : "~0.29.0",
28 | "nib" : "~0.8.1",
29 | "less" : "~1.3.0",
30 | "ejs" : "~0.8.2",
31 | "uglify-js" : "~1.3.1",
32 | "csso" : "~1.2.14",
33 | "jade" : "~0.27.2",
34 | "neuron" : "~0.4.5",
35 | "cron" : "~1.0.0"
36 | },
37 | "devDependencies" : {
38 | "webkit-devtools-agent" : "~ 0.0.4"
39 | },
40 | "engines" : { "node": ">= 0.8.0" }
41 | }
42 |
--------------------------------------------------------------------------------
/server/static.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /**
5 | * server
6 | **/
7 |
8 |
9 | /*global nodeca, _*/
10 |
11 |
12 | // stdlib
13 | var path = require('path');
14 | var http = require('http');
15 |
16 |
17 | // 3rd-party
18 | var send = require('send');
19 |
20 |
21 | ////////////////////////////////////////////////////////////////////////////////
22 |
23 |
24 | var root = path.join(nodeca.runtime.apps[0].root, 'public/root');
25 | var logger = nodeca.logger.getLogger('server.static');
26 |
27 |
28 | ////////////////////////////////////////////////////////////////////////////////
29 |
30 |
31 | /**
32 | * server.static(params, callback) -> Void
33 | *
34 | * - **HTTP only**
35 | *
36 | * Middleware that serves static assets from `public/root` directory under the
37 | * main application root path.
38 | **/
39 | module.exports = function (params, callback) {
40 | var req, res;
41 |
42 | if (!this.origin.http) {
43 | callback({statusCode: 400, body: "HTTP ONLY"});
44 | return;
45 | }
46 |
47 | req = this.origin.http.req;
48 | res = this.origin.http.res;
49 |
50 | if ('GET' !== req.method && 'HEAD' !== req.method) {
51 | callback({statusCode: 400});
52 | return;
53 | }
54 |
55 | send(req, params.file)
56 | .root(root)
57 | .on('error', function (err) {
58 | if (404 === err.status) {
59 | callback({statusCode: 404});
60 | return;
61 | }
62 |
63 | callback(err);
64 | })
65 | .on('directory', function () {
66 | callback({statusCode: 400});
67 | })
68 | .on('end', function() {
69 | logger.info('%s - "%s %s HTTP/%s" %d "%s" - %s',
70 | req.connection.remoteAddress,
71 | req.method,
72 | req.url,
73 | req.httpVersion,
74 | res.statusCode,
75 | req.headers['user-agent'],
76 | http.STATUS_CODES[res.statusCode]);
77 | })
78 | .pipe(res);
79 | };
80 |
--------------------------------------------------------------------------------
/assets/javascripts/nodeca.js.ejs:
--------------------------------------------------------------------------------
1 | /*global window, nodeca*/
2 |
3 | //= require_self
4 | //= require_tree ./nodeca
5 |
6 | var nodeca = window.nodeca = (function (nodeca) {
7 | 'use strict';
8 |
9 | nodeca.config = {};
10 | nodeca.config.app = <%- JSON.stringify(nodeca('config.app')) %>
11 | nodeca.views = {};
12 | nodeca.server = {};
13 | nodeca.shared = {};
14 | nodeca.client = {};
15 |
16 | nodeca.runtime = {};
17 | nodeca.runtime.env = "<%= nodeca('runtime.env') %>";
18 | nodeca.runtime.version = "<%= nodeca('runtime.version') %>";
19 | nodeca.runtime.i18n = new BabelFish({});
20 |
21 | // translations injector
22 | nodeca.runtime.i18n.load = function loadTranslations(lang, data) {
23 | nodeca.runtime.i18n._storage[lang] = data;
24 | };
25 |
26 | // some defaults
27 | nodeca.runtime.locale = "<%= nodeca('config.locales.default') %>";
28 |
29 | // translation helper with active locale
30 | nodeca.runtime.t = function (phrase, params) {
31 | return nodeca.runtime.i18n.t(nodeca.runtime.locale, phrase, params);
32 | };
33 |
34 | (function (c) {
35 | var log = c.log || $.noop;
36 |
37 | nodeca.logger = {};
38 |
39 | _.each(['assert', 'error', 'info', 'debug'], function (level) {
40 | var logger = c[level]; // try to get console.
41 |
42 | // we deal with IE6-7 where no console exist at all
43 | // or we deal with IE8 where console.log or whatever might be an object
44 | if (!_.isFunction(logger)) {
45 | logger = function () {
46 | log([level].concat(_.toArray(arguments)));
47 | };
48 | }
49 |
50 | // logger is now a function for sure, so we can safely bind a console
51 | // context, which is needed for Chrome
52 | nodeca.logger[level] = _.bind(logger, c);
53 | });
54 | }(window.console || {}));
55 |
56 | return nodeca;
57 | }({}));
58 |
59 | // vim: syntax=javascript
60 |
--------------------------------------------------------------------------------
/lib/init/assets/mincer/manifest.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // stdlib
8 | var path = require('path');
9 |
10 |
11 | // 3rd-party
12 | var Mincer = require('mincer');
13 |
14 |
15 | ////////////////////////////////////////////////////////////////////////////////
16 |
17 |
18 | // compile(output, environment, callback(err, manifest)) -> Void
19 | // - output (String): Root of the manifest file.
20 | //
21 | // Compiles and outputs files and manifest data for the `environment` into the
22 | // given manifest `root`.
23 | //
24 | function compile(output, environment, callback) {
25 | var manifest = new Mincer.Manifest(environment, output),
26 | filters = [],
27 | blacklist = [],
28 | files = [];
29 |
30 | filters.push('app.css', 'app.js');
31 | filters.push('loader.js', 'json2.js', 'es5-shim.js');
32 | blacklist.push(/^faye-browser/);
33 |
34 | //
35 | // function that mathces any non-js or non-css files
36 | //
37 |
38 | filters.push(function nonAsset(logicalPath) {
39 | var extname = path.extname(logicalPath),
40 | ignore = _.any(blacklist, function (re) {
41 | return re.test(logicalPath);
42 | });
43 |
44 | // - logicalPath should not be ignored
45 | // - extension must exist (e.g. logicalPath of `layout.ejs` is `layout`)
46 | // - extension must be anything but .js or .css
47 | return !(ignore || !extname || /\.(?:js|css)$/.test(extname));
48 | });
49 |
50 | //
51 | // collect assets that must be compiled
52 | //
53 |
54 | try {
55 | environment.eachLogicalPath(filters, function (logicalPath) {
56 | files.push(logicalPath);
57 | });
58 | } catch (err) {
59 | callback(err);
60 | return;
61 | }
62 |
63 | //
64 | // run compiler
65 | //
66 |
67 | manifest.compile(files, callback);
68 | }
69 |
70 |
71 | ////////////////////////////////////////////////////////////////////////////////
72 |
73 |
74 | module.exports.compile = compile;
75 |
--------------------------------------------------------------------------------
/lib/stylus/import-dir.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /**
5 | * lib
6 | **/
7 |
8 | /**
9 | * lib.stylus
10 | **/
11 |
12 |
13 | // stdlib
14 | var path = require('path');
15 | var fs = require('fs');
16 |
17 |
18 | // 3rd-party
19 | var stylus = require('stylus');
20 |
21 |
22 | ////////////////////////////////////////////////////////////////////////////////
23 |
24 |
25 | // returns list of files under given pathname, but not deeper (no recursion)
26 | function find_files(pathname) {
27 | var files = [];
28 |
29 | fs.readdirSync(pathname).forEach(function (filename) {
30 | filename = path.join(pathname, filename);
31 |
32 | if (fs.statSync(filename).isFile()) {
33 | // we are interested in a first level child files only
34 | files.push(filename);
35 | return;
36 | }
37 | });
38 |
39 | return files.sort();
40 | }
41 |
42 |
43 | ////////////////////////////////////////////////////////////////////////////////
44 |
45 |
46 | /**
47 | * lib.stylus.import_dir(expr) -> Array
48 | *
49 | * Stylus extensions that allows to mixin all files in the specified directory.
50 | *
51 | *
52 | * ##### Usage
53 | *
54 | * Assuming `source` is a stylus file:
55 | *
56 | * import-dir('./foobar')
57 | *
58 | * We can define `import-dir` function like this:
59 | *
60 | * stylus(source).define('import-dir', lib.stylus.import_dir);
61 | **/
62 | module.exports = function import_dir(expr) {
63 | var block = this.currentBlock,
64 | vals = [stylus.nodes['null']],
65 | pathname = path.resolve(path.dirname(this.filename), expr.val);
66 |
67 | find_files(pathname).forEach(function (file) {
68 | var expr = new stylus.nodes.Expression(),
69 | node = new stylus.nodes.String(file),
70 | body;
71 |
72 | expr.push(node);
73 |
74 | body = this.visitImport(new stylus.nodes.Import(expr));
75 | vals = vals.concat(body.nodes);
76 | }, this);
77 |
78 | this.mixin(vals, block);
79 | return vals;
80 | };
81 |
--------------------------------------------------------------------------------
/lib/init/cronjob.js:
--------------------------------------------------------------------------------
1 | /*global nodeca*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | // 3rd-party
8 | var cron = require('cron');
9 |
10 |
11 | // nodeca
12 | var NLib = require('nlib');
13 |
14 |
15 | ////////////////////////////////////////////////////////////////////////////////
16 |
17 |
18 | var DOWNLOADS_PATH = require('path').resolve(__dirname, '../../public/download');
19 |
20 |
21 | ////////////////////////////////////////////////////////////////////////////////
22 |
23 |
24 | module.exports = function (next) {
25 | nodeca.logger.warn("Purging obsolet downloads. Removing: " + DOWNLOADS_PATH);
26 | NLib.Vendor.FsTools.remove(DOWNLOADS_PATH, function (err) {
27 | var job;
28 |
29 | if (err) {
30 | next(err);
31 | return;
32 | }
33 |
34 | try {
35 | job = new cron.CronJob({
36 | // run every day at 00:00:00
37 | cronTime: '0 0 0 * * *',
38 | onTick: function () {
39 | var now = Date.now(), // current timestamp in ms
40 | max_age = 60 * 60 * 24 * 1000; // 1 day in ms
41 |
42 | nodeca.logger.warn("Cleaning downloads...");
43 | NLib.Vendor.FsTools.walk(DOWNLOADS_PATH, function (file, stat, next) {
44 | if (max_age > now - Date.parse(stat.mtime)) {
45 | // file is fresh - no need to cleanup
46 | nodeca.logger.debug("Skipping file: " + file);
47 | next();
48 | return;
49 | }
50 |
51 | nodeca.logger.warn("Removing file: " + file);
52 | NLib.Vendor.FsTools.remove(file, next);
53 | }, function (err) {
54 | if (err) {
55 | nodeca.logger.warn("Failed cleanup downloads");
56 | nodeca.logger.error(err);
57 | }
58 | });
59 | },
60 | // do not start immediately
61 | start: false
62 | });
63 | } catch (err) {
64 | next(err);
65 | return;
66 | }
67 |
68 | job.start();
69 | next();
70 | });
71 | };
72 |
--------------------------------------------------------------------------------
/lib/init/assets/mincer/stylus/import-dir.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /**
5 | * lib
6 | **/
7 |
8 | /**
9 | * lib.stylus
10 | **/
11 |
12 |
13 | // stdlib
14 | var path = require('path');
15 | var fs = require('fs');
16 |
17 |
18 | // 3rd-party
19 | var stylus = require('stylus');
20 |
21 |
22 | ////////////////////////////////////////////////////////////////////////////////
23 |
24 |
25 | // returns list of files under given pathname, but not deeper (no recursion)
26 | function find_files(pathname) {
27 | var files = [];
28 |
29 | fs.readdirSync(pathname).forEach(function (filename) {
30 | filename = path.join(pathname, filename);
31 |
32 | if (fs.statSync(filename).isFile()) {
33 | // we are interested in a first level child files only
34 | files.push(filename);
35 | return;
36 | }
37 | });
38 |
39 | return files.sort();
40 | }
41 |
42 |
43 | ////////////////////////////////////////////////////////////////////////////////
44 |
45 |
46 | /**
47 | * lib.stylus.import_dir(expr) -> Array
48 | *
49 | * Stylus extensions that allows to mixin all files in the specified directory.
50 | *
51 | *
52 | * ##### Usage
53 | *
54 | * Assuming `source` is a stylus file:
55 | *
56 | * import-dir('./foobar')
57 | *
58 | * We can define `import-dir` function like this:
59 | *
60 | * stylus(source).define('import-dir', lib.stylus.import_dir);
61 | **/
62 | module.exports = function import_dir(expr) {
63 | var block = this.currentBlock,
64 | vals = [stylus.nodes['null']],
65 | pathname = path.resolve(path.dirname(this.filename), expr.val);
66 |
67 | find_files(pathname).forEach(function (file) {
68 | var expr = new stylus.nodes.Expression(),
69 | node = new stylus.nodes.String(file),
70 | body;
71 |
72 | expr.push(node);
73 |
74 | body = this.visitImport(new stylus.nodes.Import(expr));
75 | vals = vals.concat(body.nodes);
76 | }, this);
77 |
78 | this.mixin(vals, block);
79 | return vals;
80 | };
81 |
--------------------------------------------------------------------------------
/lib/init/assets/build_api_tree.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // stdlib
8 | var fs = require('fs');
9 | var path = require('path');
10 |
11 |
12 | // 3rd-party
13 | var apiTree = require('nlib').ApiTree;
14 | var async = require('nlib').Vendor.Async;
15 | var fstools = require('nlib').Vendor.FsTools;
16 |
17 |
18 | ////////////////////////////////////////////////////////////////////////////////
19 |
20 |
21 | // internal
22 | // browserify(callback(err, str)) -> Void
23 | // - callback (Function): Executed once all namespaces were browserified
24 | //
25 | // Makes browserified client/shared/server trees.
26 | //
27 | function browserify(callback) {
28 | var parts = [];
29 |
30 | // browserify server tree
31 | parts.push(apiTree.browserifyServerTree(nodeca.server, 'this.nodeca.server', {
32 | method: 'nodeca.io.apiTree'
33 | }));
34 |
35 | // browserify client and shared trees
36 | async.forEach(['client', 'shared'], function (part, next) {
37 | var pathname = path.join(nodeca.runtime.apps[0].root, part);
38 |
39 | apiTree.browserifySources(pathname, 'this.nodeca.' + part, function (err, str) {
40 | if (err) {
41 | next(err);
42 | return;
43 | }
44 |
45 | parts.push(str);
46 | next();
47 | });
48 | }, function (err) {
49 | callback(err, parts.join('\n\n'));
50 | });
51 | }
52 |
53 |
54 | ////////////////////////////////////////////////////////////////////////////////
55 |
56 |
57 | // buildApiTree(root, callback(err)) -> Void
58 | // - root (String): Pathname where to save browserified api.js.
59 | // - callback (Function): Executed once everything is done.
60 | //
61 | // Browserifies server/shared/client trees into api.js file.
62 | //
63 | module.exports = function buildApiTree(root, callback) {
64 | browserify(function (err, str) {
65 | if (err) {
66 | callback(err);
67 | return;
68 | }
69 |
70 | fs.writeFile(path.join(root, 'api.js'), str, callback);
71 | });
72 | };
73 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/js/bootstrap-transition.js:
--------------------------------------------------------------------------------
1 | /* ===================================================
2 | * bootstrap-transition.js v2.1.1
3 | * http://twitter.github.com/bootstrap/javascript.html#transitions
4 | * ===================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ========================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | $(function () {
24 |
25 | "use strict"; // jshint ;_;
26 |
27 |
28 | /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
29 | * ======================================================= */
30 |
31 | $.support.transition = (function () {
32 |
33 | var transitionEnd = (function () {
34 |
35 | var el = document.createElement('bootstrap')
36 | , transEndEventNames = {
37 | 'WebkitTransition' : 'webkitTransitionEnd'
38 | , 'MozTransition' : 'transitionend'
39 | , 'OTransition' : 'oTransitionEnd otransitionend'
40 | , 'transition' : 'transitionend'
41 | }
42 | , name
43 |
44 | for (name in transEndEventNames){
45 | if (el.style[name] !== undefined) {
46 | return transEndEventNames[name]
47 | }
48 | }
49 |
50 | }())
51 |
52 | return transitionEnd && {
53 | end: transitionEnd
54 | }
55 |
56 | })()
57 |
58 | })
59 |
60 | }(window.jQuery);
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/labels-badges.less:
--------------------------------------------------------------------------------
1 | //
2 | // Labels and badges
3 | // --------------------------------------------------
4 |
5 |
6 | // Base classes
7 | .label,
8 | .badge {
9 | font-size: @baseFontSize * .846;
10 | font-weight: bold;
11 | line-height: 14px; // ensure proper line-height if floated
12 | color: @white;
13 | vertical-align: baseline;
14 | white-space: nowrap;
15 | text-shadow: 0 -1px 0 rgba(0,0,0,.25);
16 | background-color: @grayLight;
17 | }
18 | // Set unique padding and border-radii
19 | .label {
20 | padding: 1px 4px 2px;
21 | .border-radius(3px);
22 | }
23 | .badge {
24 | padding: 1px 9px 2px;
25 | .border-radius(9px);
26 | }
27 |
28 | // Hover state, but only for links
29 | a {
30 | &.label:hover,
31 | &.badge:hover {
32 | color: @white;
33 | text-decoration: none;
34 | cursor: pointer;
35 | }
36 | }
37 |
38 | // Colors
39 | // Only give background-color difference to links (and to simplify, we don't qualifty with `a` but [href] attribute)
40 | .label,
41 | .badge {
42 | // Important (red)
43 | &-important { background-color: @errorText; }
44 | &-important[href] { background-color: darken(@errorText, 10%); }
45 | // Warnings (orange)
46 | &-warning { background-color: @orange; }
47 | &-warning[href] { background-color: darken(@orange, 10%); }
48 | // Success (green)
49 | &-success { background-color: @successText; }
50 | &-success[href] { background-color: darken(@successText, 10%); }
51 | // Info (turquoise)
52 | &-info { background-color: @infoText; }
53 | &-info[href] { background-color: darken(@infoText, 10%); }
54 | // Inverse (black)
55 | &-inverse { background-color: @grayDark; }
56 | &-inverse[href] { background-color: darken(@grayDark, 10%); }
57 | }
58 |
59 | // Quick fix for labels/badges in buttons
60 | .btn {
61 | .label,
62 | .badge {
63 | position: relative;
64 | top: -1px;
65 | }
66 | }
67 | .btn-mini {
68 | .label,
69 | .badge {
70 | top: 0;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/bin/tpl-render.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 |
4 | 'use strict';
5 |
6 |
7 | // stdlib
8 | var fs = require('fs');
9 |
10 |
11 | // 3rd-party
12 | var _ = require('underscore');
13 | var jade = require('jade');
14 |
15 |
16 | ////////////////////////////////////////////////////////////////////////////////
17 |
18 |
19 | var options = (function (cli) {
20 | cli.addArgument(['--locals'], {action: 'store', required: false});
21 | cli.addArgument(['--output'], {action: 'store', required: true});
22 | cli.addArgument(['--input'], {action: 'store', required: true, dest: 'filename'});
23 | cli.addArgument(['--pretty'], {action: 'storeTrue', defaultValue: false});
24 |
25 | return cli.parseArgs();
26 | }(new (require('argparse').ArgumentParser)));
27 |
28 |
29 | ////////////////////////////////////////////////////////////////////////////////
30 |
31 |
32 | var jade_filters = require('jade/lib/filters');
33 |
34 | jade_filters.stylus_nowrap = function(str, options){
35 | var ret;
36 | str = str.replace(/\\n/g, '\n');
37 | var stylus = require('stylus');
38 | stylus(str, options).render(function(err, css){
39 | if (err) throw err;
40 | ret = css.replace(/\n/g, '\\n');
41 | });
42 | return ret;
43 | }
44 |
45 |
46 | ////////////////////////////////////////////////////////////////////////////////
47 |
48 | var locals = options.locals ? require(options.locals) : {};
49 | var source = fs.readFileSync(options.filename, 'utf8');
50 | var result = jade.compile(source, options)(_.extend({
51 | _: _,
52 | unichr: function unichr(code) {
53 | /*jshint bitwise: false*/
54 | if (code > 0xffff) {
55 | code -= 0x10000;
56 | var surrogate1 = 0xd800 + (code >> 10),
57 | surrogate2 = 0xdc00 + (code & 0x3ff);
58 | return String.fromCharCode(surrogate1, surrogate2);
59 | } else {
60 | return String.fromCharCode(code);
61 | }
62 | }
63 | }, locals));
64 |
65 |
66 | ////////////////////////////////////////////////////////////////////////////////
67 |
68 |
69 | fs.writeFileSync(options.output, result);
70 |
--------------------------------------------------------------------------------
/lib/filters/renderer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // 3rd-party
8 | var treeHas = require('nlib').Support.tree.cache.has;
9 |
10 |
11 | // internals
12 | var helpers = require('./renderer/helpers');
13 |
14 |
15 | ////////////////////////////////////////////////////////////////////////////////
16 |
17 |
18 | // Filter middleware that renders view and required layout and sets
19 | //
20 | // - `response.headers` with approprite headers
21 | // - `response.body` with rendered (and compressed if allowed) html
22 | //
23 | nodeca.filters.after('', { weight: 900 }, function renderer(params, callback) {
24 | var http = this.origin.http,
25 | headers = this.response.headers,
26 | layout = this.response.layout,
27 | viewsTree, locals;
28 |
29 | if (!http) {
30 | // skip non-http requests
31 | callback();
32 | return;
33 | }
34 |
35 | //
36 | // Prepare variables
37 | //
38 |
39 | viewsTree = nodeca.runtime.views;
40 |
41 | if (!treeHas(viewsTree, this.response.view)) {
42 | callback(new Error("View " + this.response.view + " not found"));
43 | return;
44 | }
45 |
46 | //
47 | // Set Content-Type and charset
48 | //
49 |
50 | headers['Content-Type'] = 'text/html; charset=UTF-8';
51 |
52 | //
53 | // 304 Not Modified
54 | //
55 |
56 | if (headers['ETag'] && headers['ETag'] === http.req.headers['if-none-match']) {
57 | // The one who sets `ETag` header must set also (by it's own):
58 | // - `Last-Modified`
59 | // - `Cache-Control`
60 | this.response.statusCode = 304;
61 | callback();
62 | return;
63 | }
64 |
65 | //
66 | // HEAD requested - no need for real rendering
67 | //
68 |
69 | if ('HEAD' === http.req.method) {
70 | callback();
71 | return;
72 | }
73 |
74 | try {
75 | locals = _.extend(this.response.data, helpers, this.helpers);
76 | this.response.body = nodeca.shared.render(viewsTree, this.response.view, locals, layout);
77 | } catch (err) {
78 | callback(err);
79 | return;
80 | }
81 |
82 | callback();
83 | });
84 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/bootstrap.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v2.0.3
3 | *
4 | * Copyright 2012 Twitter, Inc
5 | * Licensed under the Apache License v2.0
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Designed and built with all the love in the world @twitter by @mdo and @fat.
9 | */
10 |
11 | // CSS Reset
12 | @import "src/less/reset.less";
13 |
14 | // Core variables and mixins
15 | @import "src/less/variables.less";
16 | @import "var_override.less"; // Modify this for custom colors, font-sizes, etc
17 |
18 | @import "src/less/mixins.less";
19 |
20 | // Grid system and page structure
21 | @import "src/less/scaffolding.less";
22 | @import "src/less/grid.less";
23 | @import "src/less/layouts.less";
24 |
25 | // Base CSS
26 | @import "src/less/type.less";
27 | //@import "src/less/code.less";
28 | @import "src/less/forms.less";
29 | //@import "src/less/tables.less";
30 |
31 | // Components: common
32 | //@import "src/less/sprites.less";
33 | @import "src/less/dropdowns.less";
34 | @import "src/less/wells.less";
35 | @import "src/less/component-animations.less";
36 | @import "src/less/close.less";
37 |
38 | // Components: Buttons & Alerts
39 | @import "src/less/buttons.less";
40 | @import "src/less/button-groups.less";
41 | @import "src/less/alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less
42 |
43 | // Components: Nav
44 | @import "src/less/navs.less";
45 | @import "src/less/navbar.less";
46 | //@import "src/less/breadcrumbs.less";
47 | //@import "src/less/pagination.less";
48 | //@import "src/less/pager.less";
49 |
50 | // Components: Popovers
51 | @import "src/less/modals.less";
52 | @import "src/less/tooltip.less";
53 | @import "src/less/popovers.less";
54 |
55 | // Components: Misc
56 | //@import "src/less/thumbnails.less";
57 | @import "src/less/labels-badges.less";
58 | //@import "src/less/progress-bars.less";
59 | //@import "src/less/accordion.less";
60 | //@import "src/less/carousel.less";
61 | //@import "src/less/hero-unit.less";
62 |
63 | // Utility classes
64 | @import "src/less/utilities.less"; // Has to be last to override when necessary
65 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/var_override.less:
--------------------------------------------------------------------------------
1 | // Overrides for Variables.less
2 | // to automatically keep new vars on bootstrap updates
3 | // -----------------------------------------------------
4 |
5 |
6 | // Grays
7 | // -------------------------
8 |
9 | @black: #000;
10 | @grayDarker: #222;
11 | //@grayDark: #333;
12 | @grayDark: #444;
13 | //@gray: #555;
14 | @gray: #666;
15 | @grayLight: #999;
16 | @grayLighter: #eee;
17 | @white: #fff;
18 |
19 |
20 | // Typography
21 | // -------------------------
22 |
23 | @sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif;
24 | @serifFontFamily: Georgia, "Times New Roman", Times, serif;
25 | @monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace;
26 |
27 | //@baseFontSize: 13px;
28 | @baseFontSize: 14px;
29 | @baseFontFamily: @sansFontFamily;
30 | //@baseLineHeight: 18px;
31 | @baseLineHeight: 20px;
32 | @altFontFamily: @serifFontFamily;
33 |
34 | @headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily
35 | @headingsFontWeight: bold; // instead of browser default, bold
36 | @headingsColor: inherit; // empty to use BS default, @textColor
37 |
38 |
39 | // Navbar
40 | // -------------------------
41 |
42 | //@navbarText: @grayLight;
43 | @navbarText: #bbb;
44 | //@navbarLinkColor: @grayLight;
45 | @navbarLinkColor: #bbb;
46 |
47 |
48 | // Links
49 | // -------------------------
50 |
51 | @linkColor: #953B39;
52 |
53 |
54 | // Buttons
55 | // -------------------------
56 |
57 | //@btnBackground: @white;
58 | @btnBackground: darken(@white, 5%);
59 | //@btnBackgroundHighlight: darken(@white, 10%);
60 | @btnBackgroundHighlight: darken(@white, 5%);
61 | @btnBorder: #ccc;
62 |
63 | @btnInfoBackground: #dd4226;
64 | @btnInfoBackgroundHighlight: #ac301a;
65 |
66 |
--------------------------------------------------------------------------------
/bin/font_copy_to_assets.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys
4 | import os
5 | import shutil
6 | import argparse
7 | import yaml
8 |
9 |
10 | error = sys.stderr.write
11 |
12 |
13 | if __name__ == '__main__':
14 | parser = argparse.ArgumentParser(description='Font copier tool')
15 | parser.add_argument('-c', '--config', type=str, required=True,
16 | help='Config example: src/awesome-uni.font/config.yml')
17 | parser.add_argument('-o', '--fonts_dir', type=str, required=True,
18 | help='Output fonts directory')
19 |
20 | args = parser.parse_args()
21 |
22 | try:
23 | config = yaml.load(open(args.config, 'r'))
24 | except IOError as (errno, strerror):
25 | error('Cannot open %s: %s\n' % (args.config, strerror))
26 | sys.exit(1)
27 | except yaml.YAMLError, e:
28 | if hasattr(e, 'problem_mark'):
29 | mark = e.problem_mark
30 | error('YAML parser error in file %s at line %d, col %d\n' %
31 | (args.config, mark.line + 1, mark.column + 1))
32 | else:
33 | error('YAML parser error in file %s: %s\n' % (args.config, e))
34 | sys.exit(1)
35 |
36 | fontname = config.get('font', {}).get('fontname', None)
37 | if not fontname:
38 | error('Error: cannot find "font: fontname" in file %s\n' % args.config)
39 | sys.exit(1)
40 |
41 | if not os.path.exists(args.fonts_dir):
42 | error('Error: directory "%s" does not exist\n' % args.fonts_dir)
43 | sys.exit(1)
44 |
45 | if not os.path.isdir(args.fonts_dir):
46 | error('Error: path "%s" is not a directory\n' % args.fonts_dir)
47 | sys.exit(1)
48 |
49 | ext_list = ('.eot', '.svg', '.ttf', '.woff')
50 | for ext in ext_list:
51 | src = '%s/font/%s%s' % (os.path.dirname(args.config), fontname, ext)
52 | try:
53 | shutil.copy(src, args.fonts_dir)
54 | except IOError as (errno, strerror):
55 | error('Cannot copy "%s" to "%s": %s\n' % (args.config,
56 | args.fonts_dir, strerror))
57 | sys.exit(1)
58 |
59 | sys.exit(0)
60 |
--------------------------------------------------------------------------------
/client/ui/panes/selector_font.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 | "use strict";
4 |
5 | module.exports = Backbone.View.extend({
6 | tagName: "li",
7 |
8 |
9 | initialize: function () {
10 | var self = this;
11 |
12 | this.$el.attr("id", "font-id-" + this.model.id);
13 |
14 | this.model.on("change", this.render, this);
15 | this.model.on("destroy", this.remove, this);
16 |
17 | // activate selectable plugin
18 | this.$el.selectable({
19 | filter: 'li.glyph:visible',
20 | distance: 5,
21 | stop: function () {
22 | var $els = self.$('.glyph.ui-selected');
23 |
24 | // prevent from double-triggering event,
25 | // otherwise click event will be fired as well
26 | if (1 === $els.length) {
27 | return;
28 | }
29 |
30 | self.trigger('before:batch-select');
31 | $els.each(function () {
32 | $(this).data('model').toggle('selected');
33 | });
34 | self.trigger('after:batch-select');
35 | }
36 | });
37 | },
38 |
39 | render: function () {
40 | var $info;
41 |
42 | this.$el.html(nodeca.client.render('selector.font-item', {
43 | id: this.model.id,
44 | fontname: this.model.get("font").fullname,
45 | css_class: "font-embedded-" + this.model.get("id")
46 | }));
47 |
48 | // render info html
49 | $info = $(nodeca.client.render('selector.font-info', this.model.toJSON()));
50 |
51 | // assign modal window popup handler
52 | this.$('.font-info').click(function () {
53 | $info.appendTo(window.document.body).modal();
54 | // prevent default browser behavior - jump to the top
55 | return false;
56 | });
57 |
58 | // process each glyph
59 | this.model.eachGlyph(function (glyph) {
60 | var view = new nodeca.client.ui.panes.selector_glyph({model: glyph});
61 | this.$(".font-glyphs").append(view.render().el);
62 | }, this);
63 |
64 | return this;
65 | },
66 |
67 |
68 | remove: function () {
69 | this.$el.remove();
70 | this.trigger("remove", this.model);
71 | }
72 | });
73 |
--------------------------------------------------------------------------------
/lib/init/server.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // 3rd-party
8 | var Async = require('nlib').Vendor.Async;
9 |
10 |
11 | ////////////////////////////////////////////////////////////////////////////////
12 |
13 |
14 | // helper that starts http server and waits for it to bind to specified host and
15 | // port (see configuration listen section).
16 | //
17 | function start_server(next) {
18 | var server, host, port, err_handler;
19 |
20 | try {
21 | // add support for webkit devtools
22 | require('webkit-devtools-agent');
23 | nodeca.logger.info('webkit-devtools-agent enabled');
24 | } catch (err) {
25 | // do nothing
26 | nodeca.logger.warn('webkit-devtools-agent disabled');
27 | }
28 |
29 | // create server
30 | host = nodeca.config.listen.host || 'localhost';
31 | port = nodeca.config.listen.port || 3000;
32 | server = require('http').createServer();
33 |
34 | err_handler = function (err) {
35 | var err_prefix = "Can't bind to <" + host + "> with port <" + port + ">: ";
36 |
37 | if ('EADDRINUSE' === err.code) {
38 | next(err_prefix + 'Address in use...');
39 | return;
40 | }
41 |
42 | if ('EADDRNOTAVAIL' === err.code) {
43 | // system has no such ip address
44 | next(err_prefix + 'Address is not available...');
45 | return;
46 | }
47 |
48 | if ('ENOENT' === err.code) {
49 | // failed resolve hostname to ip address
50 | next(err_prefix + "Failed to resolve IP address...");
51 | return;
52 | }
53 |
54 | // unexpected / unknown error
55 | next(err_prefix + err);
56 | };
57 |
58 | server.on('error', err_handler);
59 |
60 | // start server
61 | server.listen(port, host, function () {
62 | server.removeListener('error', err_handler);
63 | next(null, server);
64 | });
65 | }
66 |
67 |
68 | // MODULE EXPORTS //////////////////////////////////////////////////////////////
69 |
70 |
71 | // starts http server and attach application HTTP server and Faye realtime
72 | // servers to it
73 | //
74 | module.exports = function (next) {
75 | start_server(function (err, server) {
76 | if (err) {
77 | next(err);
78 | return;
79 | }
80 |
81 | require('./server/http').attach(server, next);
82 | });
83 | };
84 |
--------------------------------------------------------------------------------
/assets/vendor/fontello/src/font/icons.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
43 |
--------------------------------------------------------------------------------
/client/ui/panes/codes_editor_glyph.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 | "use strict";
4 |
5 | module.exports = Backbone.View.extend({
6 | tagName: "div",
7 | className: "result-glyph",
8 |
9 |
10 | initialize: function () {
11 | this.model.on("change", this.render, this);
12 | this.model.on("destroy", this.remove, this);
13 | },
14 |
15 |
16 | render: function () {
17 | var model = this.model,
18 | source = model.get('source'),
19 | font = model.get('font').getName(),
20 | uid = source.uid,
21 | code = nodeca.shared.glyphs_map[font][uid],
22 | char = nodeca.client.util.fixedFromCharCode(model.get("code"));
23 |
24 | this.$el.html(nodeca.client.render('code-editor.glyph', {
25 | top: model.get("code") === 32 ? "space" : char,
26 | chr: nodeca.client.util.fixedFromCharCode(code),
27 | bottom: this.toUnicode(model.get("code")),
28 | css_class: "font-embedded-" + model.get('font').get('id')
29 | }));
30 |
31 | this.$el.find('.char-editable').inplaceEditor({
32 | validateChar: function (char) {
33 | this.setValue(char);
34 | return false;
35 | },
36 | filterValue: function (val) {
37 | var code = nodeca.client.util.fixedCharCodeAt(val);
38 | return nodeca.client.util.fixedFromCharCode(code);
39 | }
40 | }).on('change', function (event, val) {
41 | model.set("code", nodeca.client.util.fixedCharCodeAt(val));
42 | });
43 |
44 | this.$el.find('.code-editable').inplaceEditor({
45 | noPaste: true,
46 | validateChar: function (char) {
47 | return /[0-9a-fA-F]/.test(char) && 6 > this.getValue().length;
48 | }
49 | }).on('change', function (event, val) {
50 | model.set("code", parseInt(val, 16));
51 | });
52 |
53 | this.$el.toggleClass("mapping-matched", model.get("code") === source.code);
54 |
55 | return this;
56 | },
57 |
58 |
59 | // return char in CharRef notation
60 | toCharRef: function (char) {
61 | return "" + char.charCodeAt(0).toString(16) + ";";
62 | },
63 |
64 |
65 | // return unicode code point in U+ notation
66 | toUnicode: function (code) {
67 | var c = code.toString(16).toUpperCase();
68 | return "0000".substr(0, Math.max(4 - c.length, 0)) + c;
69 | }
70 | });
71 |
--------------------------------------------------------------------------------
/assets/stylesheets/app.styl:
--------------------------------------------------------------------------------
1 | //= require bootstrap/bootstrap
2 | //= require bootstrap/bootstrap-responsive
3 | //= require jquery.noty/noty
4 | //= require fontello/icons
5 | //= require fontface-fontello
6 |
7 | @import nib
8 | @import variables
9 | @import bootstrap_override
10 |
11 | html
12 | overflow-y scroll // remove glitch on step 3, when scroller disappears
13 |
14 | body
15 | padding-top 180px // make the container go all the way to the bottom of the topbar
16 | padding-bottom 30px
17 |
18 | .navbar
19 | box-shadow 0 0 4px #444
20 |
21 | .brand
22 | line-height 20px
23 | padding-top 0 !important
24 | padding-bottom 0 !important
25 |
26 | //======== Github ribbon ========
27 | .gh-ribbon
28 | position fixed
29 | right -60px
30 | top 44px
31 | z-index 10000
32 | background-color #686868
33 | padding 1px 0
34 | transform rotate(45deg)
35 | width 230px
36 | box-shadow 0 0 2px #6666
37 | display none
38 | a
39 | display: block;
40 | color #fff
41 | border 1px solid #aaa
42 | font-size 13px
43 | font-weight bold
44 | padding 4px 50px 2px
45 | text-align center
46 | outline none
47 | &:hover
48 | text-decoration none
49 |
50 | // use moderniser to show only fo browsers,
51 | // wich supports rotation
52 | .csstransforms .gh-ribbon
53 | display block
54 |
55 | //======== Social buttons ========
56 | iframe
57 | &.twitter-follow-button
58 | &.twitter-share-button
59 | margin-left 10px
60 | margin-top 9px
61 | &.FlattrButton
62 | margin-top 10px
63 |
64 | .gplus > div
65 | top 9px
66 | position relative
67 |
68 | .nav
69 | .twitter-follow-button
70 | .twitter-share-button
71 | .gplus
72 | .FlattrButton
73 | transition: opacity .5s ease;
74 | opacity: .6
75 |
76 | .nav:hover
77 | .twitter-follow-button
78 | .twitter-share-button
79 | .gplus
80 | .FlattrButton
81 | opacity: 1
82 |
83 | //====== warning for disabled JS ===
84 | .js .jsnotice
85 | display none
86 |
87 |
88 | .no-js .jsnotice
89 | position absolute
90 | left 30%
91 | right 30%
92 | top 90px
93 | z-index 10000
94 | font-size 54px
95 | line-height 81px
96 | font-weight bold
97 |
98 |
99 | p.note
100 | color #888
101 |
102 | @import "ui/tabs"
103 | @import "ui/toolbar"
104 | @import "ui/panes/selector"
105 | @import "ui/panes/preview"
106 | @import "ui/panes/codes_editor"
107 |
--------------------------------------------------------------------------------
/HISTORY.md:
--------------------------------------------------------------------------------
1 | 2.0.4 / Rolling on website
2 | --------------------------
3 |
4 | * ...
5 |
6 |
7 | 2.0.3 / 2012-09-07
8 | ------------------
9 |
10 | * Preview tab content now resizeable too
11 | * You can edit glyph names
12 | * Codes edit improved
13 | * Fixed EOT fonts generation for customised font names
14 | * Added switchable '3D' shadow effect for icons
15 | * Fixed work with Opera 12
16 | * Tweaked styles again :)
17 | * Improved work with proxies (switched back data exchange from realtime to ajax)
18 | * Optimized page loading speed - merged all embedded fonts into single file
19 | * Synked libraries codebase with nodeca mainstream
20 |
21 |
22 | 2.0.2 / 2012-06-27
23 | ------------------
24 |
25 | * Added configuration import/export
26 | * Improved CSS generation
27 | - use escaped chars when possible (for codes <= 0xFFFF)
28 | - add encoding (first line) only when needed
29 | - ie7 support
30 | - plains css with codes only, for automated asset build systems
31 | * Added README & LICENSE files to generated webfonts
32 | * Demo data bundled to single file now
33 | * Minor UI tweaks (inputs, buttons)
34 | * Fixed server stability issues (increased open file descriptors limit)
35 | * Migrated to node.js v0.8
36 |
37 |
38 | 2.0.1 / 2012-06-03
39 | ------------------
40 |
41 | * Reworked interface logic & look
42 | * Added search
43 | * Added multiselect (click+drag)
44 | * Added field to select file name
45 | * Autosave for all changes
46 | * Number of small fixes
47 | * Internal refactoring (continue switching to new nodeca libraries)
48 | * Returned back WebSymbols font
49 | * Added Modern Pictograms font
50 | * Added Typicons font
51 |
52 |
53 | 2.0.0 / 2012-05-08
54 | ------------------
55 |
56 | * Uses new [Font Builder](https://github.com/fontello/font-builder) system
57 | - All your files in single archive - no needs to use fontsquirrel generator.
58 | - Better glyphs mapping: follow Unicode 6.1 standard where possible.
59 | - Embedded fonts realligned to middleline of small letters.
60 | - Integrated ttfautohint, to significantly improve hinting.
61 | * Added `Font Awesome`
62 | * Added `Brandico`
63 | * Removed `WebSymbols`
64 | * Editable glyph codes.
65 | * Auto-generated CSS for bootstrap.
66 | * Nice preview tab & auto-generated demo-page.
67 | * Using @fonf-face instead of cufon to display glyths - mush better quality.
68 | * Removed external font loading, until we do something better.
69 |
70 |
71 | 0.0.1 / 2012-02-23
72 | ------------------
73 |
74 | * First release
75 |
--------------------------------------------------------------------------------
/bin/build_embedded_fonts_css.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys
4 | import os
5 | import argparse
6 | import json
7 | import yaml
8 | import fontforge
9 |
10 |
11 | error = sys.stderr.write
12 |
13 |
14 | if __name__ == '__main__':
15 | parser = argparse.ArgumentParser(description='Css generator')
16 | parser.add_argument('config', nargs='+', type=str,
17 | help='Config example: src/font1/config.yml src/font2/config.yml')
18 | parser.add_argument('-o', '--dst_file', type=str, required=True,
19 | help='Output css file')
20 |
21 | args = parser.parse_args()
22 |
23 | css_class = []
24 | css_fontface = []
25 |
26 | tpl_class = ".font-embedded-{i} {{ font-family: '{fontname}'; }}"
27 | tpl_fontface = """@font-face {{
28 | font-family: '{fontname}';
29 | src: url('<%= asset_path("{fontname}.eot") %>');
30 | src: url('<%= asset_path("{fontname}.eot") %>?#iefix') format('embedded-opentype'),
31 | url('<%= asset_path("{fontname}.woff") %>') format('woff'),
32 | url('<%= asset_path("{fontname}.ttf") %>') format('truetype'),
33 | url('<%= asset_path("{fontname}.svg") %>#{fontname}') format('svg');
34 | font-weight: normal;
35 | font-style: normal;
36 | }}"""
37 |
38 | for i, config_path in enumerate(args.config):
39 | try:
40 | config = yaml.load(open(config_path, 'r'))
41 | except IOError as (errno, strerror):
42 | error('Cannot open %s: %s\n' % (config_path, strerror))
43 | sys.exit(1)
44 | except yaml.YAMLError, e:
45 | if hasattr(e, 'problem_mark'):
46 | mark = e.problem_mark
47 | error('YAML parser error in file %s at line %d, col %d\n' %
48 | (config_path, mark.line + 1, mark.column + 1))
49 | else:
50 | error('YAML parser error in file %s: %s\n' % (config_path, e))
51 | sys.exit(1)
52 |
53 | fontname = config.get('font', {}).get('fontname', None)
54 | if not fontname:
55 | error('Error: cannot find "font: fontname" in file %s\n' %
56 | config_path)
57 | sys.exit(1)
58 |
59 | css_class.append(tpl_class.format(i=i, fontname=fontname))
60 | css_fontface.append(tpl_fontface.format(fontname=fontname))
61 |
62 | css = '\n'.join(css_class) + '\n\n' + '\n\n'.join(css_fontface)
63 |
64 | try:
65 | open(args.dst_file, 'w').write(css)
66 | except:
67 | error('Cannot write to file %s\n' % args.dst_file)
68 | sys.exit(1)
69 |
70 | sys.exit(0)
71 |
--------------------------------------------------------------------------------
/client/ui/toolbar.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | // prevent the event from bubbling to ancestor elements
8 | function stopPropagation(event) {
9 | event.preventDefault();
10 | event.stopPropagation();
11 | }
12 |
13 |
14 | module.exports = Backbone.View.extend({
15 | el: '#toolbar',
16 |
17 |
18 | $download_btn: null,
19 | $glyphs_count: null,
20 | keywords: [],
21 |
22 |
23 | initialize: function () {
24 | var self = this, $glyph_size_value, $search, on_search_change;
25 |
26 | // cache some inner elements
27 | this.$download_btn = this.$('#result-download');
28 | this.$glyphs_count = this.$('#selected-glyphs-count');
29 |
30 | // initialize glyph-size slider
31 | $glyph_size_value = $('#glyph-size-value');
32 | $('#glyph-size-slider').slider({
33 | orientation: 'horizontal',
34 | range: 'min',
35 | value: nodeca.config.app.glyph_size.val,
36 | min: nodeca.config.app.glyph_size.min,
37 | max: nodeca.config.app.glyph_size.max,
38 | slide: function (event, ui) {
39 | /*jshint bitwise:false*/
40 | var val = ~~ui.value;
41 | $glyph_size_value.text(val + 'px');
42 | self.trigger("change:glyph-size", val);
43 | }
44 | });
45 |
46 | // search query change event listener
47 | on_search_change = function (event) {
48 | self.trigger('change:search', $search.val());
49 | };
50 |
51 | // init search input
52 | $search = $('#search')
53 | .on('change', on_search_change)
54 | .on('keyup', _.debounce(on_search_change, 250))
55 | .on('focus keyup', _.debounce(function () {
56 | $search.typeahead('hide');
57 | }, 5000))
58 | .typeahead({
59 | source: this.keywords
60 | });
61 |
62 | // bind download button click event
63 | this.$download_btn.click(function (event) {
64 | event.preventDefault();
65 | self.trigger('click:download');
66 | });
67 |
68 | // initial setup
69 | this.setGlyphsCount(0);
70 | },
71 |
72 |
73 | setGlyphsCount: function (count) {
74 | this.$download_btn.toggleClass('disabled', !count);
75 | this.$download_btn[!count ? 'on' : 'off']('click', stopPropagation);
76 |
77 | this.$glyphs_count.text(+count);
78 | },
79 |
80 | addKeywords: function (tags) {
81 | _.each(tags, function (tag) {
82 | if (_.isString(tag) && !_.include(this.keywords, tag)) {
83 | this.keywords.push(tag);
84 | }
85 | }, this);
86 | }
87 | });
88 |
--------------------------------------------------------------------------------
/lib/init/assets/mincer/environment.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 |
4 | /*global nodeca, _*/
5 |
6 |
7 | // stdlib
8 | var fs = require('fs');
9 | var path = require('path');
10 |
11 |
12 | // 3rd-party
13 | var Mincer = require('mincer');
14 | var JASON = require('nlib').Vendor.JASON;
15 | var treeGet = require('nlib').Support.tree.get;
16 |
17 |
18 | // internal
19 | var compression = require('./compression');
20 |
21 |
22 | ////////////////////////////////////////////////////////////////////////////////
23 |
24 |
25 | // configure(root) -> Mincer.Environment
26 | // - root (String): Root pathname of the environment
27 | //
28 | // Preconfigures Mincer environment
29 | //
30 | function configure(root) {
31 | var environment = new Mincer.Environment(root);
32 |
33 | //
34 | // Provide some helpers to EJS and Stylus
35 | //
36 |
37 | environment.registerHelper({
38 | asset_path: function (pathname) {
39 | var asset = environment.findAsset(pathname);
40 | return !asset ? null : ("/assets/" + asset.digestPath);
41 | },
42 | nodeca: function (path) {
43 | return treeGet(nodeca, path);
44 | },
45 | jason: JASON.stringify
46 | });
47 |
48 | //
49 | // fill in 3rd-party modules paths
50 | //
51 |
52 | environment.appendPath(path.resolve(__dirname, '../../../../node_modules/nlib/node_modules/pointer/browser'));
53 | environment.appendPath(path.resolve(__dirname, '../../../../node_modules/nlib/node_modules/babelfish/browser'));
54 |
55 | //
56 | // fill in base assets (non-themable) of all apps
57 | //
58 |
59 | _.each(nodeca.runtime.apps, function (app) {
60 | environment.appendPath(path.join(app.root, 'assets/javascripts'));
61 | environment.appendPath(path.join(app.root, 'assets/stylesheets'));
62 | environment.appendPath(path.join(app.root, 'assets/vendor'));
63 | });
64 |
65 | //
66 | // add embedded fonts path
67 | //
68 |
69 | environment.appendPath(path.join(
70 | nodeca.runtime.apps[0].root, 'assets/embedded_fonts'
71 | ));
72 |
73 | //
74 | // add root path itself
75 | //
76 |
77 | environment.appendPath('.');
78 |
79 | //
80 | // Set JS/CSS compression if it was not explicitly disabled
81 | // USAGE: SKIP_ASSETS_COMPRESSION=1 ./nodeca.js server
82 | //
83 |
84 | if (!process.env.SKIP_ASSETS_COMPRESSION) {
85 | environment.jsCompressor = compression.js;
86 | environment.cssCompressor = compression.css;
87 | }
88 |
89 | return environment;
90 | }
91 |
92 |
93 | ////////////////////////////////////////////////////////////////////////////////
94 |
95 |
96 | module.exports.configure = configure;
97 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/modals.less:
--------------------------------------------------------------------------------
1 | //
2 | // Modals
3 | // --------------------------------------------------
4 |
5 |
6 | // Recalculate z-index where appropriate,
7 | // but only apply to elements within modal
8 | .modal-open .modal {
9 | .dropdown-menu { z-index: @zindexDropdown + @zindexModal; }
10 | .dropdown.open { *z-index: @zindexDropdown + @zindexModal; }
11 | .popover { z-index: @zindexPopover + @zindexModal; }
12 | .tooltip { z-index: @zindexTooltip + @zindexModal; }
13 | }
14 |
15 | // Background
16 | .modal-backdrop {
17 | position: fixed;
18 | top: 0;
19 | right: 0;
20 | bottom: 0;
21 | left: 0;
22 | z-index: @zindexModalBackdrop;
23 | background-color: @black;
24 | // Fade for backdrop
25 | &.fade { opacity: 0; }
26 | }
27 |
28 | .modal-backdrop,
29 | .modal-backdrop.fade.in {
30 | .opacity(80);
31 | }
32 |
33 | // Base modal
34 | .modal {
35 | position: fixed;
36 | top: 50%;
37 | left: 50%;
38 | z-index: @zindexModal;
39 | overflow: auto;
40 | width: 560px;
41 | margin: -250px 0 0 -280px;
42 | background-color: @white;
43 | border: 1px solid #999;
44 | border: 1px solid rgba(0,0,0,.3);
45 | *border: 1px solid #999; /* IE6-7 */
46 | .border-radius(6px);
47 | .box-shadow(0 3px 7px rgba(0,0,0,0.3));
48 | .background-clip(padding-box);
49 | &.fade {
50 | .transition(e('opacity .3s linear, top .3s ease-out'));
51 | top: -25%;
52 | }
53 | &.fade.in { top: 50%; }
54 | }
55 | .modal-header {
56 | padding: 9px 15px;
57 | border-bottom: 1px solid #eee;
58 | // Close icon
59 | .close { margin-top: 2px; }
60 | // Heading
61 | h3 {
62 | margin: 0;
63 | line-height: 30px;
64 | }
65 | }
66 |
67 | // Body (where all modal content resides)
68 | .modal-body {
69 | overflow-y: auto;
70 | max-height: 400px;
71 | padding: 15px;
72 | }
73 | // Remove bottom margin if need be
74 | .modal-form {
75 | margin-bottom: 0;
76 | }
77 |
78 | // Footer (for actions)
79 | .modal-footer {
80 | padding: 14px 15px 15px;
81 | margin-bottom: 0;
82 | text-align: right; // right align buttons
83 | background-color: #f5f5f5;
84 | border-top: 1px solid #ddd;
85 | .border-radius(0 0 6px 6px);
86 | .box-shadow(inset 0 1px 0 @white);
87 | .clearfix(); // clear it in case folks use .pull-* classes on buttons
88 |
89 | // Properly space out buttons
90 | .btn + .btn {
91 | margin-left: 5px;
92 | margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
93 | }
94 | // but override that for button groups
95 | .btn-group .btn + .btn {
96 | margin-left: -1px;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/shared/render.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /**
5 | * shared
6 | **/
7 |
8 |
9 | /*global nodeca, _*/
10 |
11 |
12 | ////////////////////////////////////////////////////////////////////////////////
13 |
14 |
15 | // get_layout_stack(layout) -> Array
16 | // - layout (string): Full layout path
17 | //
18 | // Returns stack of layouts.
19 | //
20 | // get_layout_stack('foo.bar.baz') // => ['foo', 'foo.bar', 'foo.bar.baz']
21 | //
22 | function get_layout_stack(layout) {
23 | var stack = layout.split('.'), i, l;
24 |
25 | for (i = 1, l = stack.length; i < l; i++) {
26 | stack[i] = stack[i - 1] + '.' + stack[i];
27 | }
28 |
29 | return stack;
30 | }
31 |
32 |
33 | ////////////////////////////////////////////////////////////////////////////////
34 |
35 |
36 | /**
37 | * shared.render(views, path, locals, layout, skipBaseLayout) -> String
38 | * - viewsTree (Object): Views tree (without locale and/or theme subpaths).
39 | * - path (String): View name to render, e.g. `forums.index`
40 | * - locals (Object): Locals data to pass to the renderer function
41 | * - layout (String): Layout to render, e.g. `default.blogs`
42 | * - skipBaseLayout (Boolean): Whenever to skip rendering base layout or not
43 | *
44 | * Renders view registered as `path` with given `layout` and returns result.
45 | *
46 | * render(views, 'blogs.post.show', 'default.blogs');
47 | *
48 | * In the example above, it will render `blogs.post.show` view with given
49 | * `data`, then will render `default.blogs` layout with `data` where `content`
50 | * property will be rendered view, then `default` layout with `data` where
51 | * `content` property will be previously rendered layout.
52 | **/
53 | module.exports = function render(viewsTree, path, locals, layout, skipBaseLayout) {
54 | var html, view = nodeca.shared.getByPath(viewsTree, path);
55 |
56 | if (!!view) {
57 | html = view(locals);
58 | } else {
59 | // Here we just notify that view not found.
60 | // This should never happen - one must check path existance before render()
61 | nodeca.logger.warn("View " + path + " not found");
62 | html = '';
63 | }
64 |
65 | if (layout) {
66 | layout = (_.isArray(layout) ? layout.slice() : get_layout_stack(layout));
67 | layout = (!!skipBaseLayout ? layout.slice(1) : layout).reverse();
68 |
69 | _.each(layout, function (path) {
70 | var fn = nodeca.shared.getByPath(viewsTree.layouts, path);
71 |
72 | if (!_.isFunction(fn)) {
73 | nodeca.logger.warn("Layout " + path + " not found");
74 | return;
75 | }
76 |
77 | locals.content = html;
78 | html = fn(locals);
79 | });
80 | }
81 |
82 | return html;
83 | };
84 |
--------------------------------------------------------------------------------
/assets/vendor/jquery.noty/src/css/jquery.noty.css:
--------------------------------------------------------------------------------
1 |
2 | /* CORE STYLES */
3 |
4 | /* noty bar */
5 | .noty_bar {
6 | position: fixed;
7 | display: none;
8 | z-index: 9999999;
9 | }
10 |
11 | /* noty_message */
12 | .noty_bar .noty_message {
13 | text-align: center;
14 | }
15 |
16 | /* noty close button */
17 | .noty_bar .noty_close {
18 | cursor: pointer;
19 | }
20 |
21 | /* noty modal */
22 | .noty_modal {
23 | position: fixed;
24 | width: 100%;
25 | height: 100%;
26 | background-color: #000;
27 | z-index: 10000;
28 | opacity: 0.6;
29 | display: none;
30 | left: 0;
31 | top: 0;
32 | }
33 |
34 | /* noty container for noty_layout_topLeft & noty_layout_topRight */
35 | ul.noty_cont {
36 | position: fixed;
37 | z-index: 10000000;
38 | margin: 0px;
39 | padding: 0px;
40 | list-style: none;
41 | width: 300px;
42 | }
43 | ul.noty_cont li {
44 | position: relative;
45 | float: left;
46 | clear: both;
47 | list-style: none;
48 | padding: 0px;
49 | margin: 10px 0 0 0;
50 | width: 300px; /* Fix for: http://bugs.jquery.com/ticket/2278 */
51 | }
52 | ul.noty_cont.noty_layout_topLeft {left:20px; top:20px;}
53 | ul.noty_cont.noty_layout_topRight {right:40px; top:20px;}
54 | ul.noty_cont.noty_layout_bottomLeft {left:20px; bottom:20px}
55 | ul.noty_cont.noty_layout_bottomRight {right:40px; bottom:20px}
56 | ul.noty_cont.noty_layout_topRight li {float:right}
57 |
58 | /* LAYOUTS */
59 |
60 | /* noty_layout_top */
61 | .noty_bar.noty_layout_top {
62 | top: 0;
63 | left: 0;
64 | width: 100%;
65 | -webkit-border-radius: 0px;
66 | -moz-border-radius: 0px;
67 | border-radius: 0px;
68 | }
69 |
70 | /* noty_layout_bottom */
71 | .noty_bar.noty_layout_bottom {
72 | bottom: 0;
73 | left: 0;
74 | width: 100%;
75 | -webkit-border-radius: 0px;
76 | -moz-border-radius: 0px;
77 | border-radius: 0px;
78 | }
79 |
80 | /* noty_layout_center */
81 | .noty_bar.noty_layout_center {
82 | top: 40%;
83 | }
84 |
85 | /* noty_layout_topLeft & noty_layout_topRight */
86 | .noty_bar.noty_layout_topLeft,
87 | .noty_bar.noty_layout_topRight,
88 | .noty_bar.noty_layout_bottomLeft,
89 | .noty_bar.noty_layout_bottomRight {
90 | width: 100%;
91 | clear: both;
92 | position: relative;
93 | }
94 |
95 | .noty_bar.noty_layout_topLeft .noty_message,
96 | .noty_bar.noty_layout_topRight .noty_message,
97 | .noty_bar.noty_layout_bottomLeft .noty_message,
98 | .noty_bar.noty_layout_bottomRight .noty_message {
99 | text-align: left;
100 | }
101 |
102 | /* noty_layout_topCenter */
103 | .noty_bar.noty_layout_topCenter {
104 | top: 20px;
105 | }
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/carousel.less:
--------------------------------------------------------------------------------
1 | //
2 | // Carousel
3 | // --------------------------------------------------
4 |
5 |
6 | .carousel {
7 | position: relative;
8 | margin-bottom: @baseLineHeight;
9 | line-height: 1;
10 | }
11 |
12 | .carousel-inner {
13 | overflow: hidden;
14 | width: 100%;
15 | position: relative;
16 | }
17 |
18 | .carousel {
19 |
20 | .item {
21 | display: none;
22 | position: relative;
23 | .transition(.6s ease-in-out left);
24 | }
25 |
26 | // Account for jankitude on images
27 | .item > img {
28 | display: block;
29 | line-height: 1;
30 | }
31 |
32 | .active,
33 | .next,
34 | .prev { display: block; }
35 |
36 | .active {
37 | left: 0;
38 | }
39 |
40 | .next,
41 | .prev {
42 | position: absolute;
43 | top: 0;
44 | width: 100%;
45 | }
46 |
47 | .next {
48 | left: 100%;
49 | }
50 | .prev {
51 | left: -100%;
52 | }
53 | .next.left,
54 | .prev.right {
55 | left: 0;
56 | }
57 |
58 | .active.left {
59 | left: -100%;
60 | }
61 | .active.right {
62 | left: 100%;
63 | }
64 |
65 | }
66 |
67 | // Left/right controls for nav
68 | // ---------------------------
69 |
70 | .carousel-control {
71 | position: absolute;
72 | top: 40%;
73 | left: 15px;
74 | width: 40px;
75 | height: 40px;
76 | margin-top: -20px;
77 | font-size: 60px;
78 | font-weight: 100;
79 | line-height: 30px;
80 | color: @white;
81 | text-align: center;
82 | background: @grayDarker;
83 | border: 3px solid @white;
84 | .border-radius(23px);
85 | .opacity(50);
86 |
87 | // we can't have this transition here
88 | // because webkit cancels the carousel
89 | // animation if you trip this while
90 | // in the middle of another animation
91 | // ;_;
92 | // .transition(opacity .2s linear);
93 |
94 | // Reposition the right one
95 | &.right {
96 | left: auto;
97 | right: 15px;
98 | }
99 |
100 | // Hover state
101 | &:hover {
102 | color: @white;
103 | text-decoration: none;
104 | .opacity(90);
105 | }
106 | }
107 |
108 |
109 | // Caption for text below images
110 | // -----------------------------
111 |
112 | .carousel-caption {
113 | position: absolute;
114 | left: 0;
115 | right: 0;
116 | bottom: 0;
117 | padding: 15px;
118 | background: @grayDark;
119 | background: rgba(0,0,0,.75);
120 | }
121 | .carousel-caption h4,
122 | .carousel-caption p {
123 | color: @white;
124 | line-height: @baseLineHeight;
125 | }
126 | .carousel-caption h4 {
127 | margin: 0 0 5px;
128 | }
129 | .carousel-caption p {
130 | margin-bottom: 0;
131 | }
132 |
--------------------------------------------------------------------------------
/assets/stylesheets/ui/panes/selector.styl:
--------------------------------------------------------------------------------
1 | #selector
2 | margin-top -20px
3 | position relative
4 |
5 | .src-font-head
6 | margin-top 20px
7 | font-size 30px
8 | line-height 45px
9 |
10 | a.font-info
11 | transition all .5s ease
12 | vertical-align top
13 | display inline-block
14 | margin-top 10px
15 | margin-right 5px
16 |
17 | /* Collapser & animations */
18 | a.src-font-name
19 | color inherit
20 | text-decoration none
21 | outline 0 none
22 |
23 | .src-font-name:after
24 | transition all .5s ease
25 | border-left 6px solid transparent
26 | border-right 6px solid transparent
27 | border-bottom 6px solid #333
28 | content ""
29 | display inline-block
30 | height 0
31 | width 0
32 | margin-left 10px
33 | vertical-align middle
34 | margin-left 8px
35 | opacity 0
36 |
37 | .src-font-head:hover .src-font-name:after
38 | opacity 1
39 |
40 | .src-font-head
41 | transition all .5s ease
42 |
43 | ._collapsed .src-font-head
44 | font-size 18px
45 | line-height 24px
46 | opacity .2
47 |
48 | ._collapsed .src-font-head:hover
49 | opacity .7
50 |
51 | ._collapsed .src-font-name:after
52 | border-bottom 0 none
53 | border-top 3px solid #333
54 | border-left 3px solid transparent
55 | border-right 3px solid transparent
56 | margin-left 5px
57 |
58 | ._collapsed a.font-info
59 | margin-top 2px
60 |
61 |
62 |
63 | #local-files
64 | /* chrome/opera doesn't trigger events on "display: none;" elements */
65 | /* so, do some tricks to safely hide element */
66 |
67 | /* display: none; */
68 | width 0px
69 | height 0px
70 | position absolute
71 | top -100px
72 | visibility hidden
73 |
74 | .font-glyphs
75 | display inline-block
76 | user-select none
77 |
78 | .glyph
79 | position relative
80 | float left
81 | border 1px #ccc solid
82 | border-radius 6px
83 | cursor pointer
84 | text-align center
85 | width 48px
86 | height 48px
87 | line-height 48px
88 | margin 0 0 8px 8px
89 | transition all .1s ease
90 | box-shadow 1px 1px 3px #eee
91 |
92 | &:hover
93 | background #333
94 | color #fff
95 | //opacity .8
96 |
97 | &.selected
98 | background-color #fffdfd
99 | border-color #d88
100 | box-shadow 0 0 0px 2px #d88 inset, 1px 1px 3px 1px #eee
101 |
102 | &:hover
103 | background #666
104 |
105 | &.ui-selecting
106 | background-color #eeffee
107 | border-color #8d8
108 | //box-shadow 0 0 3px #ada inset
109 |
110 | &.selected.ui-selecting
111 | background-color #eeffee
112 | border-color #666
113 | box-shadow 0 0 3px #666 inset
114 |
115 | ._3d .glyph
116 | text-shadow 1px 1px 1px rgba(127, 127, 127, 0.3)
117 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/js/bootstrap-alert.js:
--------------------------------------------------------------------------------
1 | /* ==========================================================
2 | * bootstrap-alert.js v2.1.1
3 | * http://twitter.github.com/bootstrap/javascript.html#alerts
4 | * ==========================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ========================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict"; // jshint ;_;
24 |
25 |
26 | /* ALERT CLASS DEFINITION
27 | * ====================== */
28 |
29 | var dismiss = '[data-dismiss="alert"]'
30 | , Alert = function (el) {
31 | $(el).on('click', dismiss, this.close)
32 | }
33 |
34 | Alert.prototype.close = function (e) {
35 | var $this = $(this)
36 | , selector = $this.attr('data-target')
37 | , $parent
38 |
39 | if (!selector) {
40 | selector = $this.attr('href')
41 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
42 | }
43 |
44 | $parent = $(selector)
45 |
46 | e && e.preventDefault()
47 |
48 | $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
49 |
50 | $parent.trigger(e = $.Event('close'))
51 |
52 | if (e.isDefaultPrevented()) return
53 |
54 | $parent.removeClass('in')
55 |
56 | function removeElement() {
57 | $parent
58 | .trigger('closed')
59 | .remove()
60 | }
61 |
62 | $.support.transition && $parent.hasClass('fade') ?
63 | $parent.on($.support.transition.end, removeElement) :
64 | removeElement()
65 | }
66 |
67 |
68 | /* ALERT PLUGIN DEFINITION
69 | * ======================= */
70 |
71 | $.fn.alert = function (option) {
72 | return this.each(function () {
73 | var $this = $(this)
74 | , data = $this.data('alert')
75 | if (!data) $this.data('alert', (data = new Alert(this)))
76 | if (typeof option == 'string') data[option].call($this)
77 | })
78 | }
79 |
80 | $.fn.alert.Constructor = Alert
81 |
82 |
83 | /* ALERT DATA-API
84 | * ============== */
85 |
86 | $(function () {
87 | $('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
88 | })
89 |
90 | }(window.jQuery);
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Fontello - iconic fonts scissors
2 | ================================
3 |
4 | Website: [fontello.com](http://fontello.com/)
5 |
6 | This tool lets you combine iconic webfonts for your own project. With fontello you can:
7 |
8 | 1. shrink glyph collections, minimizing font size
9 | 2. merge symbols from several fonts into a single file
10 | 3. access large sets of professional-grade open source icons
11 |
12 | Now it's trivial to make a custom iconic webfont, exactly for your needs.
13 | First, select the icons you like. Then update glyph codes (optional), and
14 | download your webfont bundle. We generate everything you need, ready for publishing
15 | on your website!
16 |
17 | Don't forget about donations... These are some awesome icons, available with an
18 | open source license :) . A donation is the best way to express gratitude for our work.
19 |
20 |
21 | ## Embedded Fonts
22 |
23 | Fontello comes with the following embedded set of iconic fonts:
24 |
25 | - [__Entypo__](http://www.entypo.com/) by Daniel Bruce (CC BY-SA license)
26 | - [__Font Awesome__](http://fortawesome.github.com/Font-Awesome//) by Dave Gandy (CC BY-SA license)
27 | - [__Iconic__](https://github.com/somerandomdude/Iconic) by P.J. Onori (SIL OFL)
28 | - [__Brandico__](https://github.com/fontello/brandico.font) by... all :) (SIL OFL)
29 |
30 | Please, note that these embedded fonts differ from the original files. We did some
31 | modifications to unify characteristics such as scale, ascent/descent andalignment.
32 | If you need specific details on modifications, take a look into the updated fonts repos
33 | at [github](https://github.com/fontello/).
34 |
35 |
36 | ## Contacts
37 |
38 | - Questions: [Google group](https://groups.google.com/group/fontello/)
39 | - Bug reports: [Issue tracker](https://github.com/nodeca/fontomas/issues)
40 | - Suggestion for adding your OFL fonts or other collaborations: vitaly@rcdesign.ru
41 |
42 |
43 | ## Authors
44 |
45 | - Roman Shmelev ([shmelev](https://github.com/shmelev))
46 | - Vitaly Puzrin ([puzrin](https://github.com/puzrin)).
47 | [Follow](https://twitter.com/puzrin) on twitter.
48 | - Aleksey Zapparov ([ixti](https://github.com/ixti)).
49 | Follow [@zapparov](https://twitter.com/zapparov) on twitter.
50 |
51 |
52 | ## License
53 |
54 | Fontello's code (all files, except fonts) is distributed under MIT license. See
55 | [LICENSE](https://github.com/fontello/fontello/blob/master/LICENSE) file for details.
56 |
57 | Embedded fonts are distributed under their primary licenses (SIL OFL / CC BY / CC BY-SA).
58 | See section [Embedded Fonts](#embedded) above for credits & links to font homepages.
59 |
60 | Generated fonts are intended for web usage, and should not be
61 | considered/distributed as independent artwork. Consider fontello a
62 | font archiver and credit original font creators according to their respective license.
63 |
64 | Crediting fontello is not required :)
65 |
--------------------------------------------------------------------------------
/bin/build_common_font.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import os
4 | import sys
5 | from sys import stderr
6 | import argparse
7 | import yaml
8 | import json
9 | import fontforge
10 | from pprint import pprint
11 |
12 | GLYPHS_CODE_START = 0xE800
13 |
14 | def read_config(config_path):
15 | try:
16 | return yaml.load(open(config_path, 'r'))
17 | except IOError as (errno, strerror):
18 | stderr.write("Cannot open %s: %s\n" % (args.config, strerror))
19 | sys.exit(1)
20 | except yaml.YAMLError, e:
21 | if hasattr(e, 'problem_mark'):
22 | mark = e.problem_mark
23 | stderr.write("YAML parser error in file %s at line %d, col %d\n" %
24 | (args.config, mark.line + 1, mark.column + 1))
25 | else:
26 | stderr.write("YAML parser error in file %s: %s\n" % (args.config, e))
27 | sys.exit(1)
28 |
29 | parser = argparse.ArgumentParser(description='Merge glyphs from '
30 | 'several fonts to single font')
31 | parser.add_argument('-i', '--input_fonts', type=str, required=True,
32 | action='append', nargs='+', help='Input fonts')
33 | parser.add_argument('-o', '--dst_font', type=str, required=True,
34 | help='Output font')
35 | parser.add_argument('-c', '--remap_config', type=argparse.FileType('wb', 0),
36 | required=True,
37 | help='Output font remap config file')
38 |
39 | args = parser.parse_args()
40 |
41 | input_fonts = []
42 | for item in args.input_fonts:
43 | input_fonts += item
44 |
45 | new_font_config = {}
46 |
47 | # init new font
48 | new_font = fontforge.font()
49 | new_font.encoding = 'UnicodeFull'
50 |
51 | new_glyph_code = GLYPHS_CODE_START
52 |
53 | for path in input_fonts:
54 | if os.path.isdir(path):
55 | config = read_config(os.path.join(path, 'config.yml'))
56 |
57 | if not config.get('font', {}).has_key('fontname'):
58 | stderr.write("Bad config format %s: \n" % os.path.join(path, 'config.yml') )
59 |
60 | font_name = config.get('font', {}).get('fontname', None)
61 | font_path = os.path.join(path, 'font', font_name + '.ttf')
62 | src_font = fontforge.open(font_path)
63 |
64 | new_font_config[font_name] = {}
65 |
66 | for glyph in config['glyphs']:
67 | new_font_config[font_name][glyph['uid']] = new_glyph_code
68 |
69 | # cp glyph
70 | src_font.selection.select(("unicode",), glyph['code'])
71 | src_font.copy()
72 | new_font.selection.select(("unicode",), new_glyph_code)
73 | new_font.paste()
74 |
75 | new_glyph_code += 1
76 |
77 | try:
78 | new_font.generate(args.dst_font)
79 | except:
80 | stderr.write("Cannot write to file %s\n" %args.dst_font)
81 | sys.exit(1)
82 |
83 |
84 | json_data = json.dumps(new_font_config, indent = 2)
85 | args.remap_config.write("// THIS IS AUTOGENERATED FILE. DO NOT EDIT\n" +
86 | "module.exports = " + json_data)
87 |
--------------------------------------------------------------------------------
/assets/stylesheets/ui/toolbar.styl:
--------------------------------------------------------------------------------
1 | .toolbar
2 | position relative
3 |
4 | //== Make toolbar background non-transparent
5 | .navbar-fixed-top
6 | background-color #fff
7 |
8 | //== Dirty fix typeahead & tooltip z-index, to be over static container
9 | .typeahead.dropdown-menu
10 | .tooltip
11 | z-index 1050
12 |
13 | #glyph-size-slider
14 | width: 100px
15 | display inline-block
16 | float: left
17 | margin-top 11px
18 | margin-left .5em
19 |
20 | #glyph-size-value
21 | display inline-block
22 | float left
23 | //height 29px
24 | line-height 30px
25 | margin 0 1em
26 | color #888
27 | font-size 11px
28 |
29 | //== "3D" switch
30 | .btn-group .switch-3d
31 | display inline-block
32 | float left
33 | font-size 11px
34 | color grayLight
35 | line-height 30px
36 | input
37 | vertical-align top
38 | margin-top 7px
39 |
40 |
41 | /*
42 | * jQuery UI Slider 1.8.16
43 | *
44 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
45 | * Dual licensed under the MIT or GPL Version 2 licenses.
46 | * http://jquery.org/license
47 | *
48 | * http://docs.jquery.com/UI/Slider#theming
49 | */
50 | .ui-slider
51 | position relative
52 | text-align left
53 |
54 | border 1px solid
55 | border-color #bbb #bbb #ddd #ddd
56 | border-radius 1em
57 | background #ddd
58 | background-image: linear-gradient(top, #bbb 0%, #fff 80%, #ddd 100%);
59 |
60 | // fix toolbar fontsize reset
61 | font-size 14px
62 |
63 | .ui-slider .ui-slider-handle
64 | position absolute
65 | z-index 2
66 | width 1.2em
67 | height 1.2em
68 | cursor default
69 |
70 | border-radius 2em
71 | border 1px solid #aaa
72 | background #aaa
73 | background-image: linear-gradient(top, #fff 0%, #eee 50%, #aaa 100%);
74 |
75 | outline none
76 |
77 | &:after
78 | position absolute
79 | content ""
80 | width .5em
81 | height .5em
82 | top .35em
83 | left .35em
84 | // background-color #000
85 | border-radius 1em
86 | box-shadow 0 0.2em 0.15em #888888 inset
87 |
88 |
89 |
90 | .ui-slider .ui-slider-range
91 | display none;
92 | /*
93 | position: absolute;
94 | z-index: 1;
95 | font-size: .7em;
96 | display: block;
97 | border: 0;
98 | background-position: 0 0
99 | color: #ffffff;
100 | background-color: #0064cd;
101 | background-repeat: repeat-x;
102 | background-image: linear-gradient(top, #049cdb, #0064cd);
103 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
104 | border-color: #0064cd #0064cd #003f81;
105 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
106 | */
107 |
108 | .ui-slider-horizontal
109 | height .4em
110 |
111 | .ui-slider-handle
112 | top -.45em
113 | margin-left -.6em
114 | .ui-slider-range
115 | top 0
116 | height 100%
117 | .ui-slider-range-min
118 | left 0
119 | .ui-slider-range-max
120 | right 0
121 |
122 | .donate
123 | display block
124 | position absolute
125 | right 0
126 | bottom 8px
127 | font-size 12px
128 | opacity .7
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/js/bootstrap-button.js:
--------------------------------------------------------------------------------
1 | /* ============================================================
2 | * bootstrap-button.js v2.1.1
3 | * http://twitter.github.com/bootstrap/javascript.html#buttons
4 | * ============================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ============================================================ */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict"; // jshint ;_;
24 |
25 |
26 | /* BUTTON PUBLIC CLASS DEFINITION
27 | * ============================== */
28 |
29 | var Button = function (element, options) {
30 | this.$element = $(element)
31 | this.options = $.extend({}, $.fn.button.defaults, options)
32 | }
33 |
34 | Button.prototype.setState = function (state) {
35 | var d = 'disabled'
36 | , $el = this.$element
37 | , data = $el.data()
38 | , val = $el.is('input') ? 'val' : 'html'
39 |
40 | state = state + 'Text'
41 | data.resetText || $el.data('resetText', $el[val]())
42 |
43 | $el[val](data[state] || this.options[state])
44 |
45 | // push to event loop to allow forms to submit
46 | setTimeout(function () {
47 | state == 'loadingText' ?
48 | $el.addClass(d).attr(d, d) :
49 | $el.removeClass(d).removeAttr(d)
50 | }, 0)
51 | }
52 |
53 | Button.prototype.toggle = function () {
54 | var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
55 |
56 | $parent && $parent
57 | .find('.active')
58 | .removeClass('active')
59 |
60 | this.$element.toggleClass('active')
61 | }
62 |
63 |
64 | /* BUTTON PLUGIN DEFINITION
65 | * ======================== */
66 |
67 | $.fn.button = function (option) {
68 | return this.each(function () {
69 | var $this = $(this)
70 | , data = $this.data('button')
71 | , options = typeof option == 'object' && option
72 | if (!data) $this.data('button', (data = new Button(this, options)))
73 | if (option == 'toggle') data.toggle()
74 | else if (option) data.setState(option)
75 | })
76 | }
77 |
78 | $.fn.button.defaults = {
79 | loadingText: 'loading...'
80 | }
81 |
82 | $.fn.button.Constructor = Button
83 |
84 |
85 | /* BUTTON DATA-API
86 | * =============== */
87 |
88 | $(function () {
89 | $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
90 | var $btn = $(e.target)
91 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
92 | $btn.button('toggle')
93 | })
94 | })
95 |
96 | }(window.jQuery);
--------------------------------------------------------------------------------
/lib/env.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /**
5 | * lib
6 | **/
7 |
8 |
9 | /*global nodeca, _*/
10 |
11 |
12 | ////////////////////////////////////////////////////////////////////////////////
13 |
14 |
15 | var tzOffset = (new Date).getTimezoneOffset();
16 |
17 |
18 | ////////////////////////////////////////////////////////////////////////////////
19 |
20 |
21 | /**
22 | * lib.env(options) -> Object
23 | * - options (Object): Environment options.
24 | *
25 | * Create new request environment object.
26 | *
27 | *
28 | * ##### Options
29 | *
30 | * - **http**: HTTP origin object that contains `req` and `res`.
31 | * - **rpc**: API3 (Ajax) origin that contains `req` and `res`.
32 | * - **skip**: Array of middlewares to skip
33 | * - **session**: Session object
34 | * - **theme**: Theme name as String
35 | * - **locale**: Locale name as String
36 | * - **method**: Name of the server method, e.g. `'forums.posts.show'`
37 | * - **layout**: Layout name as String
38 | **/
39 | module.exports = function env(options) {
40 | var ctx = {
41 | extras: {},
42 | helpers: {
43 | asset_path: function asset_path(path) {
44 | var asset = nodeca.runtime.assets.manifest.assets[path];
45 | return !asset ? "#" : ("/assets/" + asset);
46 | }
47 | },
48 | origin: {
49 | http: options.http,
50 | rpc: options.rpc
51 | },
52 | skip: (options.skip || []).slice(),
53 | // FIXME: should be filled by session middleware
54 | session: options.session || {
55 | theme: 'desktop',
56 | locale: nodeca.config.locales['default']
57 | },
58 | request: {
59 | // FIXME: should be deprecated in flavour of env.origin
60 | origin: !!options.rpc ? 'RPC' : 'HTTP',
61 | method: options.method,
62 | namespace: String(options.method).split('.').shift()
63 | },
64 | data: {},
65 | response: {
66 | data: {
67 | head: {
68 | title: null, // should be filled with default value
69 | apiPath: options.method,
70 | // List of assets for yepnope,
71 | // Each element is an object with properties:
72 | //
73 | // type: css|js
74 | // link: asset_url
75 | //
76 | // example: assets.push({type: 'js', link: '//example.com/foo.js'});
77 | assets: []
78 | },
79 | menus: {},
80 | widgets: {}
81 | },
82 | headers: {},
83 | // Layouts are supporting "nesting" via `dots:
84 | //
85 | // default.blogs
86 | //
87 | // In the example above, `default.blogs` will be rendered first and the
88 | // result will be provided for rendering to `default`.
89 | layout: options.layout || 'default',
90 | view: options.method
91 | }
92 | };
93 |
94 | //
95 | // env-dependent helper needs to be bounded to env
96 | //
97 |
98 | ctx.helpers.t = function (phrase, params) {
99 | return nodeca.runtime.i18n.t(this.session.locale, phrase, params);
100 | }.bind(ctx);
101 |
102 | return ctx;
103 | };
104 |
--------------------------------------------------------------------------------
/bin/generate_font.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 |
4 | set -e # die on any unexpected error
5 |
6 |
7 | ## INIT ########################################################################
8 |
9 |
10 | FONTNAME=$1
11 | TMPDIR=$2
12 | ZIPBALL=$3
13 |
14 | USER_CONFIG=$TMPDIR/config.json
15 | CONFIG=$TMPDIR/generator-config.json
16 | FONT_TEMPLATES="$PWD/support/font-templates"
17 |
18 |
19 | mkdir $TMPDIR/css $TMPDIR/font
20 |
21 |
22 | ## HELPERS #####################################################################
23 |
24 |
25 | require()
26 | {
27 | if ! $( which $1 > /dev/null ) ; then
28 | echo "Can't find required command: $1" >&2
29 | exit 128
30 | fi
31 | return 0
32 | }
33 |
34 |
35 | ## PREPARE PATHS ###############################################################
36 |
37 |
38 | export PATH="$PWD/bin:$PATH"
39 | export PATH="$PWD/node_modules/.bin:$PATH"
40 | export PATH="$PWD/support/font-builder/bin:$PATH"
41 | export PATH="$PWD/support/font-builder/support/ttf2eot:$PATH"
42 | export PATH="$PWD/support/font-builder/support/ttfautohint/frontend:$PATH"
43 |
44 |
45 | ## CHECK DEPENDENCIES ##########################################################
46 |
47 |
48 | for dep in font_merge.py fontconvert.py fontdemo.py ttfautohint ttf2eot jade zip; do
49 | require $dep
50 | done
51 |
52 |
53 | ## BUILD FONT CONFIG ###########################################################
54 |
55 |
56 | node ./fontello.js font_config --input $USER_CONFIG --output $CONFIG
57 |
58 |
59 | ## BUILD FONT ##################################################################
60 |
61 |
62 | font_merge.py --config "$CONFIG" --dst_font "$TMPDIR/font/$FONTNAME.ttf"
63 | ttfautohint --latin-fallback --hinting-limit=200 --hinting-range-max=50 \
64 | --symbol "$TMPDIR/font/$FONTNAME.ttf" "$TMPDIR/font/$FONTNAME-hinted.ttf"
65 | mv "$TMPDIR/font/$FONTNAME-hinted.ttf" "$TMPDIR/font/$FONTNAME.ttf"
66 | fontconvert.py --src_font "$TMPDIR/font/$FONTNAME.ttf" --fonts_dir "$TMPDIR/font"
67 | ttf2eot < "$TMPDIR/font/$FONTNAME.ttf" > "$TMPDIR/font/$FONTNAME.eot"
68 |
69 |
70 | ## BUILD TEMPLATES #############################################################
71 |
72 |
73 | tpl-render.js --locals "$CONFIG" --input "$FONT_TEMPLATES/demo.jade" \
74 | --output "$TMPDIR/demo.html" --pretty
75 |
76 | tpl-render.js --locals "$CONFIG" --input "$FONT_TEMPLATES/css/css.jade" \
77 | --output "$TMPDIR/css/$FONTNAME.css"
78 |
79 | tpl-render.js --locals "$CONFIG" --input "$FONT_TEMPLATES/css/css-ie7.jade" \
80 | --output "$TMPDIR/css/$FONTNAME-ie7.css"
81 |
82 | tpl-render.js --locals "$CONFIG" --input "$FONT_TEMPLATES/css/css-codes.jade" \
83 | --output "$TMPDIR/css/$FONTNAME-codes.css"
84 |
85 | tpl-render.js --locals "$CONFIG" --input "$FONT_TEMPLATES/css/css-ie7-codes.jade" \
86 | --output "$TMPDIR/css/$FONTNAME-ie7-codes.css"
87 |
88 | tpl-render.js --locals "$CONFIG" --input "$FONT_TEMPLATES/LICENSE.jade" \
89 | --output "$TMPDIR/LICENSE.txt"
90 |
91 | cp "$FONT_TEMPLATES/README.txt" "$TMPDIR/"
92 |
93 |
94 | ## BUILD ZIPBALL ###############################################################
95 |
96 |
97 | MAXLEN=$(expr $(echo -n $TMPDIR | wc -c) - 24)
98 | FIXDIR=$(echo -n $TMPDIR | cut -c-$MAXLEN)
99 |
100 | rm $CONFIG && rm -rf $ZIPBALL && mkdir -p $(dirname $ZIPBALL)
101 | cd $(dirname $TMPDIR)
102 |
103 | cp -r "$TMPDIR" "$FIXDIR"
104 | zip $ZIPBALL -r ./$(basename $FIXDIR)
105 | rm -rf $FIXDIR
106 |
107 | exit 0
108 |
--------------------------------------------------------------------------------
/assets/vendor/jade/runtime.js:
--------------------------------------------------------------------------------
1 |
2 | jade = (function(exports){
3 | /*!
4 | * Jade - runtime
5 | * Copyright(c) 2010 TJ Holowaychuk
6 | * MIT Licensed
7 | */
8 |
9 | /**
10 | * Lame Array.isArray() polyfill for now.
11 | */
12 |
13 | if (!Array.isArray) {
14 | Array.isArray = function(arr){
15 | return '[object Array]' == Object.prototype.toString.call(arr);
16 | };
17 | }
18 |
19 | /**
20 | * Lame Object.keys() polyfill for now.
21 | */
22 |
23 | if (!Object.keys) {
24 | Object.keys = function(obj){
25 | var arr = [];
26 | for (var key in obj) {
27 | if (obj.hasOwnProperty(key)) {
28 | arr.push(key);
29 | }
30 | }
31 | return arr;
32 | }
33 | }
34 |
35 | /**
36 | * Render the given attributes object.
37 | *
38 | * @param {Object} obj
39 | * @param {Object} escaped
40 | * @return {String}
41 | * @api private
42 | */
43 |
44 | exports.attrs = function attrs(obj, escaped){
45 | var buf = []
46 | , terse = obj.terse;
47 |
48 | delete obj.terse;
49 | var keys = Object.keys(obj)
50 | , len = keys.length;
51 |
52 | if (len) {
53 | buf.push('');
54 | for (var i = 0; i < len; ++i) {
55 | var key = keys[i]
56 | , val = obj[key];
57 |
58 | if ('boolean' == typeof val || null == val) {
59 | if (val) {
60 | terse
61 | ? buf.push(key)
62 | : buf.push(key + '="' + key + '"');
63 | }
64 | } else if (0 == key.indexOf('data') && 'string' != typeof val) {
65 | buf.push(key + "='" + JSON.stringify(val) + "'");
66 | } else if ('class' == key && Array.isArray(val)) {
67 | buf.push(key + '="' + exports.escape(val.join(' ')) + '"');
68 | } else if (escaped[key]) {
69 | buf.push(key + '="' + exports.escape(val) + '"');
70 | } else {
71 | buf.push(key + '="' + val + '"');
72 | }
73 | }
74 | }
75 |
76 | return buf.join(' ');
77 | };
78 |
79 | /**
80 | * Escape the given string of `html`.
81 | *
82 | * @param {String} html
83 | * @return {String}
84 | * @api private
85 | */
86 |
87 | exports.escape = function escape(html){
88 | return String(html)
89 | .replace(/&(?!\w+;)/g, '&')
90 | .replace(//g, '>')
92 | .replace(/"/g, '"');
93 | };
94 |
95 | /**
96 | * Re-throw the given `err` in context to the
97 | * the jade in `filename` at the given `lineno`.
98 | *
99 | * @param {Error} err
100 | * @param {String} filename
101 | * @param {String} lineno
102 | * @api private
103 | */
104 |
105 | exports.rethrow = function rethrow(err, filename, lineno){
106 | if (!filename) throw err;
107 |
108 | var context = 3
109 | , str = require('fs').readFileSync(filename, 'utf8')
110 | , lines = str.split('\n')
111 | , start = Math.max(lineno - context, 0)
112 | , end = Math.min(lines.length, lineno + context);
113 |
114 | // Error context
115 | var context = lines.slice(start, end).map(function(line, i){
116 | var curr = i + start + 1;
117 | return (curr == lineno ? ' > ' : ' ')
118 | + curr
119 | + '| '
120 | + line;
121 | }).join('\n');
122 |
123 | // Alter exception message
124 | err.path = filename;
125 | err.message = (filename || 'Jade') + ':' + lineno
126 | + '\n' + context + '\n\n' + err.message;
127 | throw err;
128 | };
129 |
130 | return exports;
131 |
132 | })({});
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/progress-bars.less:
--------------------------------------------------------------------------------
1 | //
2 | // Progress bars
3 | // --------------------------------------------------
4 |
5 |
6 | // ANIMATIONS
7 | // ----------
8 |
9 | // Webkit
10 | @-webkit-keyframes progress-bar-stripes {
11 | from { background-position: 40px 0; }
12 | to { background-position: 0 0; }
13 | }
14 |
15 | // Firefox
16 | @-moz-keyframes progress-bar-stripes {
17 | from { background-position: 40px 0; }
18 | to { background-position: 0 0; }
19 | }
20 |
21 | // IE9
22 | @-ms-keyframes progress-bar-stripes {
23 | from { background-position: 40px 0; }
24 | to { background-position: 0 0; }
25 | }
26 |
27 | // Opera
28 | @-o-keyframes progress-bar-stripes {
29 | from { background-position: 0 0; }
30 | to { background-position: 40px 0; }
31 | }
32 |
33 | // Spec
34 | @keyframes progress-bar-stripes {
35 | from { background-position: 40px 0; }
36 | to { background-position: 0 0; }
37 | }
38 |
39 |
40 |
41 | // THE BARS
42 | // --------
43 |
44 | // Outer container
45 | .progress {
46 | overflow: hidden;
47 | height: @baseLineHeight;
48 | margin-bottom: @baseLineHeight;
49 | #gradient > .vertical(#f5f5f5, #f9f9f9);
50 | .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
51 | .border-radius(4px);
52 | }
53 |
54 | // Bar of progress
55 | .progress .bar {
56 | width: 0%;
57 | height: 100%;
58 | color: @white;
59 | float: left;
60 | font-size: 12px;
61 | text-align: center;
62 | text-shadow: 0 -1px 0 rgba(0,0,0,.25);
63 | #gradient > .vertical(#149bdf, #0480be);
64 | .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));
65 | .box-sizing(border-box);
66 | .transition(width .6s ease);
67 | }
68 | .progress .bar + .bar {
69 | .box-shadow(inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15));
70 | }
71 |
72 | // Striped bars
73 | .progress-striped .bar {
74 | #gradient > .striped(#149bdf);
75 | .background-size(40px 40px);
76 | }
77 |
78 | // Call animation for the active one
79 | .progress.active .bar {
80 | -webkit-animation: progress-bar-stripes 2s linear infinite;
81 | -moz-animation: progress-bar-stripes 2s linear infinite;
82 | -ms-animation: progress-bar-stripes 2s linear infinite;
83 | -o-animation: progress-bar-stripes 2s linear infinite;
84 | animation: progress-bar-stripes 2s linear infinite;
85 | }
86 |
87 |
88 |
89 | // COLORS
90 | // ------
91 |
92 | // Danger (red)
93 | .progress-danger .bar, .progress .bar-danger {
94 | #gradient > .vertical(#ee5f5b, #c43c35);
95 | }
96 | .progress-danger.progress-striped .bar, .progress-striped .bar-danger {
97 | #gradient > .striped(#ee5f5b);
98 | }
99 |
100 | // Success (green)
101 | .progress-success .bar, .progress .bar-success {
102 | #gradient > .vertical(#62c462, #57a957);
103 | }
104 | .progress-success.progress-striped .bar, .progress-striped .bar-success {
105 | #gradient > .striped(#62c462);
106 | }
107 |
108 | // Info (teal)
109 | .progress-info .bar, .progress .bar-info {
110 | #gradient > .vertical(#5bc0de, #339bb9);
111 | }
112 | .progress-info.progress-striped .bar, .progress-striped .bar-info {
113 | #gradient > .striped(#5bc0de);
114 | }
115 |
116 | // Warning (orange)
117 | .progress-warning .bar, .progress .bar-warning {
118 | #gradient > .vertical(lighten(@orange, 15%), @orange);
119 | }
120 | .progress-warning.progress-striped .bar, .progress-striped .bar-warning {
121 | #gradient > .striped(lighten(@orange, 15%));
122 | }
123 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/js/bootstrap-popover.js:
--------------------------------------------------------------------------------
1 | /* ===========================================================
2 | * bootstrap-popover.js v2.1.1
3 | * http://twitter.github.com/bootstrap/javascript.html#popovers
4 | * ===========================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * =========================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict"; // jshint ;_;
24 |
25 |
26 | /* POPOVER PUBLIC CLASS DEFINITION
27 | * =============================== */
28 |
29 | var Popover = function (element, options) {
30 | this.init('popover', element, options)
31 | }
32 |
33 |
34 | /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
35 | ========================================== */
36 |
37 | Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
38 |
39 | constructor: Popover
40 |
41 | , setContent: function () {
42 | var $tip = this.tip()
43 | , title = this.getTitle()
44 | , content = this.getContent()
45 |
46 | $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
47 | $tip.find('.popover-content > *')[this.options.html ? 'html' : 'text'](content)
48 |
49 | $tip.removeClass('fade top bottom left right in')
50 | }
51 |
52 | , hasContent: function () {
53 | return this.getTitle() || this.getContent()
54 | }
55 |
56 | , getContent: function () {
57 | var content
58 | , $e = this.$element
59 | , o = this.options
60 |
61 | content = $e.attr('data-content')
62 | || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
63 |
64 | return content
65 | }
66 |
67 | , tip: function () {
68 | if (!this.$tip) {
69 | this.$tip = $(this.options.template)
70 | }
71 | return this.$tip
72 | }
73 |
74 | , destroy: function () {
75 | this.hide().$element.off('.' + this.type).removeData(this.type)
76 | }
77 |
78 | })
79 |
80 |
81 | /* POPOVER PLUGIN DEFINITION
82 | * ======================= */
83 |
84 | $.fn.popover = function (option) {
85 | return this.each(function () {
86 | var $this = $(this)
87 | , data = $this.data('popover')
88 | , options = typeof option == 'object' && option
89 | if (!data) $this.data('popover', (data = new Popover(this, options)))
90 | if (typeof option == 'string') data[option]()
91 | })
92 | }
93 |
94 | $.fn.popover.Constructor = Popover
95 |
96 | $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
97 | placement: 'right'
98 | , trigger: 'click'
99 | , content: ''
100 | , template: ''
101 | })
102 |
103 | }(window.jQuery);
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/reset.less:
--------------------------------------------------------------------------------
1 | //
2 | // Modals
3 | // Adapted from http://github.com/necolas/normalize.css
4 | // --------------------------------------------------
5 |
6 |
7 | // Display in IE6-9 and FF3
8 | // -------------------------
9 |
10 | article,
11 | aside,
12 | details,
13 | figcaption,
14 | figure,
15 | footer,
16 | header,
17 | hgroup,
18 | nav,
19 | section {
20 | display: block;
21 | }
22 |
23 | // Display block in IE6-9 and FF3
24 | // -------------------------
25 |
26 | audio,
27 | canvas,
28 | video {
29 | display: inline-block;
30 | *display: inline;
31 | *zoom: 1;
32 | }
33 |
34 | // Prevents modern browsers from displaying 'audio' without controls
35 | // -------------------------
36 |
37 | audio:not([controls]) {
38 | display: none;
39 | }
40 |
41 | // Base settings
42 | // -------------------------
43 |
44 | html {
45 | font-size: 100%;
46 | -webkit-text-size-adjust: 100%;
47 | -ms-text-size-adjust: 100%;
48 | }
49 | // Focus states
50 | a:focus {
51 | .tab-focus();
52 | }
53 | // Hover & Active
54 | a:hover,
55 | a:active {
56 | outline: 0;
57 | }
58 |
59 | // Prevents sub and sup affecting line-height in all browsers
60 | // -------------------------
61 |
62 | sub,
63 | sup {
64 | position: relative;
65 | font-size: 75%;
66 | line-height: 0;
67 | vertical-align: baseline;
68 | }
69 | sup {
70 | top: -0.5em;
71 | }
72 | sub {
73 | bottom: -0.25em;
74 | }
75 |
76 | // Img border in a's and image quality
77 | // -------------------------
78 |
79 | img {
80 | /* Responsive images (ensure images don't scale beyond their parents) */
81 | max-width: 100%; /* Part 1: Set a maxium relative to the parent */
82 | width: auto\9; /* IE7-8 need help adjusting responsive images */
83 | height: auto; /* Part 2: Scale the height according to the width, otherwise you get stretching */
84 |
85 | vertical-align: middle;
86 | border: 0;
87 | -ms-interpolation-mode: bicubic;
88 | }
89 |
90 | // Prevent max-width from affecting Google Maps
91 | #map_canvas img {
92 | max-width: none;
93 | }
94 |
95 | // Forms
96 | // -------------------------
97 |
98 | // Font size in all browsers, margin changes, misc consistency
99 | button,
100 | input,
101 | select,
102 | textarea {
103 | margin: 0;
104 | font-size: 100%;
105 | vertical-align: middle;
106 | }
107 | button,
108 | input {
109 | *overflow: visible; // Inner spacing ie IE6/7
110 | line-height: normal; // FF3/4 have !important on line-height in UA stylesheet
111 | }
112 | button::-moz-focus-inner,
113 | input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
114 | padding: 0;
115 | border: 0;
116 | }
117 | button,
118 | input[type="button"],
119 | input[type="reset"],
120 | input[type="submit"] {
121 | cursor: pointer; // Cursors on all buttons applied consistently
122 | -webkit-appearance: button; // Style clickable inputs in iOS
123 | }
124 | input[type="search"] { // Appearance in Safari/Chrome
125 | -webkit-box-sizing: content-box;
126 | -moz-box-sizing: content-box;
127 | box-sizing: content-box;
128 | -webkit-appearance: textfield;
129 | }
130 | input[type="search"]::-webkit-search-decoration,
131 | input[type="search"]::-webkit-search-cancel-button {
132 | -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
133 | }
134 | textarea {
135 | overflow: auto; // Remove vertical scrollbar in IE6-9
136 | vertical-align: top; // Readability and alignment cross-browser
137 | }
138 |
--------------------------------------------------------------------------------
/client/models/glyph.js:
--------------------------------------------------------------------------------
1 | /*global window, nodeca, jQuery, Handlebars, Backbone, $, _*/
2 |
3 |
4 | "use strict";
5 |
6 |
7 | // SEE: http://www.unicode.org/versions/Unicode6.0.0/ch02.pdf
8 | //
9 | // In the Unicode Standard, the codespace consists of the integers
10 | // from 0 to 10FFFF16, comprising 1,114,112 code points available for
11 | // assigning the repertoire of abstract characters.
12 | // ...
13 | // Noncharacters. Sixty-six code points are not used to encode characters.
14 | // Noncharacters consist of U+FDD0..U+FDEF and any code point ending in the
15 | // value FFFE16 or FFFF16- that is, U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, ...
16 | // U+10FFFE, U+10FFFF.
17 | function is_valid_code(code) {
18 | var valid = (0 <= code && code <= 0x10ffff);
19 |
20 | valid = (valid && (0xfdd0 > code || code > 0xfdef));
21 | valid = (valid && code % 0x10000 !== 0xfffe);
22 | valid = (valid && code % 0x10000 !== 0xffff);
23 |
24 | return valid;
25 | }
26 |
27 |
28 | // resets (from source) `name` attribute, if it was provided as null
29 | function preprocess_attribute(source, attrs, name, options) {
30 | if (null === attrs[name]) {
31 | attrs[name] = source[name];
32 | // `options = {unset: true}` when `#unset()`
33 | delete options.unset;
34 | }
35 | }
36 |
37 |
38 | module.exports = Backbone.Model.extend({
39 | defaults: function () {
40 | return {
41 | font : null,
42 | source : null,
43 | code : null,
44 | css : null,
45 | selected : false
46 | };
47 | },
48 |
49 |
50 | idAttribute: 'uid',
51 |
52 |
53 | initialize: function (attributes) {
54 | var tags = (attributes.source || {}).search || attributes.search || [];
55 | this.keywords = tags.join(' ');
56 | },
57 |
58 |
59 | set: function(key, value, options) {
60 | var attrs, source;
61 |
62 | if (_.isObject(key) || null === key) {
63 | attrs = key;
64 | options = value;
65 | } else {
66 | attrs = {};
67 | attrs[key] = value;
68 | }
69 |
70 | // make sure options is an object
71 | options = options || {};
72 |
73 | // reset code and css to source values if unset
74 | source = this.get('source') || attrs.source || {};
75 | preprocess_attribute(source, attrs, 'code', options);
76 | preprocess_attribute(source, attrs, 'css', options);
77 |
78 | return Backbone.Model.prototype.set.call(this, attrs, options);
79 | },
80 |
81 |
82 | isModified: function isModified() {
83 | var source = this.get('source'),
84 | modified = false;
85 |
86 | modified = modified || this.get('code') !== source.code;
87 | modified = modified || this.get('css') !== source.css;
88 |
89 | return modified;
90 | },
91 |
92 |
93 | validate: function validate(attributes) {
94 | if (!is_valid_code(attributes.code)) {
95 | nodeca.logger.debug("models.glyph.validate: bad char code:",
96 | attributes.code);
97 | return "Bad char code: " + attributes.code;
98 | }
99 |
100 | return null;
101 | },
102 |
103 |
104 | toggle: function (key, val) {
105 | if (undefined === val) {
106 | val = !this.get(key);
107 | }
108 |
109 | this.set(key, !!val);
110 | },
111 |
112 |
113 | // Stub to prevent Backbone from reading or saving the model to the server.
114 | // Backbone calls `Backbone.sync()` function (on fetch/save/destroy)
115 | // if model doesn't have own `sync()` method.
116 | sync: function sync() {}
117 | });
118 |
--------------------------------------------------------------------------------
/assets/vendor/bootstrap/src/less/popovers.less:
--------------------------------------------------------------------------------
1 | //
2 | // Popovers
3 | // --------------------------------------------------
4 |
5 |
6 | .popover {
7 | position: absolute;
8 | top: 0;
9 | left: 0;
10 | z-index: @zindexPopover;
11 | display: none;
12 | width: 236px;
13 | padding: 1px;
14 | background-color: @popoverBackground;
15 | -webkit-background-clip: padding-box;
16 | -moz-background-clip: padding;
17 | background-clip: padding-box;
18 | border: 1px solid #ccc;
19 | border: 1px solid rgba(0,0,0,.2);
20 | .border-radius(6px);
21 | .box-shadow(0 5px 10px rgba(0,0,0,.2));
22 |
23 | // Offset the popover to account for the popover arrow
24 | &.top { margin-bottom: 10px; }
25 | &.right { margin-left: 10px; }
26 | &.bottom { margin-top: 10px; }
27 | &.left { margin-right: 10px; }
28 |
29 | }
30 |
31 | .popover-title {
32 | margin: 0; // reset heading margin
33 | padding: 8px 14px;
34 | font-size: 14px;
35 | font-weight: normal;
36 | line-height: 18px;
37 | background-color: @popoverTitleBackground;
38 | border-bottom: 1px solid darken(@popoverTitleBackground, 5%);
39 | .border-radius(5px 5px 0 0);
40 | }
41 |
42 | .popover-content {
43 | padding: 9px 14px;
44 | p, ul, ol {
45 | margin-bottom: 0;
46 | }
47 | }
48 |
49 | // Arrows
50 | .popover .arrow,
51 | .popover .arrow:after {
52 | position: absolute;
53 | display: inline-block;
54 | width: 0;
55 | height: 0;
56 | border-color: transparent;
57 | border-style: solid;
58 | }
59 | .popover .arrow:after {
60 | content: "";
61 | z-index: -1;
62 | }
63 |
64 | .popover {
65 | &.top .arrow {
66 | bottom: -@popoverArrowWidth;
67 | left: 50%;
68 | margin-left: -@popoverArrowWidth;
69 | border-width: @popoverArrowWidth @popoverArrowWidth 0;
70 | border-top-color: @popoverArrowColor;
71 | &:after {
72 | border-width: @popoverArrowOuterWidth @popoverArrowOuterWidth 0;
73 | border-top-color: @popoverArrowOuterColor;
74 | bottom: -1px;
75 | left: -@popoverArrowOuterWidth;
76 | }
77 | }
78 | &.right .arrow {
79 | top: 50%;
80 | left: -@popoverArrowWidth;
81 | margin-top: -@popoverArrowWidth;
82 | border-width: @popoverArrowWidth @popoverArrowWidth @popoverArrowWidth 0;
83 | border-right-color: @popoverArrowColor;
84 | &:after {
85 | border-width: @popoverArrowOuterWidth @popoverArrowOuterWidth @popoverArrowOuterWidth 0;
86 | border-right-color: @popoverArrowOuterColor;
87 | bottom: -@popoverArrowOuterWidth;
88 | left: -1px;
89 | }
90 | }
91 | &.bottom .arrow {
92 | top: -@popoverArrowWidth;
93 | left: 50%;
94 | margin-left: -@popoverArrowWidth;
95 | border-width: 0 @popoverArrowWidth @popoverArrowWidth;
96 | border-bottom-color: @popoverArrowColor;
97 | &:after {
98 | border-width: 0 @popoverArrowOuterWidth @popoverArrowOuterWidth;
99 | border-bottom-color: @popoverArrowOuterColor;
100 | top: -1px;
101 | left: -@popoverArrowOuterWidth;
102 | }
103 | }
104 | &.left .arrow {
105 | top: 50%;
106 | right: -@popoverArrowWidth;
107 | margin-top: -@popoverArrowWidth;
108 | border-width: @popoverArrowWidth 0 @popoverArrowWidth @popoverArrowWidth;
109 | border-left-color: @popoverArrowColor;
110 | &:after {
111 | border-width: @popoverArrowOuterWidth 0 @popoverArrowOuterWidth @popoverArrowOuterWidth;
112 | border-left-color: @popoverArrowOuterColor;
113 | bottom: -@popoverArrowOuterWidth;
114 | right: -1px;
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/assets/embedded_fonts/fontface-embedded.css.ejs:
--------------------------------------------------------------------------------
1 | .font-embedded-0 { font-family: 'entypo'; }
2 | .font-embedded-1 { font-family: 'fontawesome'; }
3 | .font-embedded-2 { font-family: 'iconic'; }
4 | .font-embedded-3 { font-family: 'typicons'; }
5 | .font-embedded-4 { font-family: 'modernpics'; }
6 | .font-embedded-5 { font-family: 'websymbols'; }
7 | .font-embedded-6 { font-family: 'brandico'; }
8 |
9 | @font-face {
10 | font-family: 'entypo';
11 | src: url('<%= asset_path("entypo.eot") %>');
12 | src: url('<%= asset_path("entypo.eot") %>?#iefix') format('embedded-opentype'),
13 | url('<%= asset_path("entypo.woff") %>') format('woff'),
14 | url('<%= asset_path("entypo.ttf") %>') format('truetype'),
15 | url('<%= asset_path("entypo.svg") %>#entypo') format('svg');
16 | font-weight: normal;
17 | font-style: normal;
18 | }
19 |
20 | @font-face {
21 | font-family: 'fontawesome';
22 | src: url('<%= asset_path("fontawesome.eot") %>');
23 | src: url('<%= asset_path("fontawesome.eot") %>?#iefix') format('embedded-opentype'),
24 | url('<%= asset_path("fontawesome.woff") %>') format('woff'),
25 | url('<%= asset_path("fontawesome.ttf") %>') format('truetype'),
26 | url('<%= asset_path("fontawesome.svg") %>#fontawesome') format('svg');
27 | font-weight: normal;
28 | font-style: normal;
29 | }
30 |
31 | @font-face {
32 | font-family: 'iconic';
33 | src: url('<%= asset_path("iconic.eot") %>');
34 | src: url('<%= asset_path("iconic.eot") %>?#iefix') format('embedded-opentype'),
35 | url('<%= asset_path("iconic.woff") %>') format('woff'),
36 | url('<%= asset_path("iconic.ttf") %>') format('truetype'),
37 | url('<%= asset_path("iconic.svg") %>#iconic') format('svg');
38 | font-weight: normal;
39 | font-style: normal;
40 | }
41 |
42 | @font-face {
43 | font-family: 'typicons';
44 | src: url('<%= asset_path("typicons.eot") %>');
45 | src: url('<%= asset_path("typicons.eot") %>?#iefix') format('embedded-opentype'),
46 | url('<%= asset_path("typicons.woff") %>') format('woff'),
47 | url('<%= asset_path("typicons.ttf") %>') format('truetype'),
48 | url('<%= asset_path("typicons.svg") %>#typicons') format('svg');
49 | font-weight: normal;
50 | font-style: normal;
51 | }
52 |
53 | @font-face {
54 | font-family: 'modernpics';
55 | src: url('<%= asset_path("modernpics.eot") %>');
56 | src: url('<%= asset_path("modernpics.eot") %>?#iefix') format('embedded-opentype'),
57 | url('<%= asset_path("modernpics.woff") %>') format('woff'),
58 | url('<%= asset_path("modernpics.ttf") %>') format('truetype'),
59 | url('<%= asset_path("modernpics.svg") %>#modernpics') format('svg');
60 | font-weight: normal;
61 | font-style: normal;
62 | }
63 |
64 | @font-face {
65 | font-family: 'websymbols';
66 | src: url('<%= asset_path("websymbols.eot") %>');
67 | src: url('<%= asset_path("websymbols.eot") %>?#iefix') format('embedded-opentype'),
68 | url('<%= asset_path("websymbols.woff") %>') format('woff'),
69 | url('<%= asset_path("websymbols.ttf") %>') format('truetype'),
70 | url('<%= asset_path("websymbols.svg") %>#websymbols') format('svg');
71 | font-weight: normal;
72 | font-style: normal;
73 | }
74 |
75 | @font-face {
76 | font-family: 'brandico';
77 | src: url('<%= asset_path("brandico.eot") %>');
78 | src: url('<%= asset_path("brandico.eot") %>?#iefix') format('embedded-opentype'),
79 | url('<%= asset_path("brandico.woff") %>') format('woff'),
80 | url('<%= asset_path("brandico.ttf") %>') format('truetype'),
81 | url('<%= asset_path("brandico.svg") %>#brandico') format('svg');
82 | font-weight: normal;
83 | font-style: normal;
84 | }
--------------------------------------------------------------------------------