├── .gitignore ├── .gitmodules ├── Capfile ├── LICENSE ├── README.md ├── TODO ├── config.coffee.sample ├── fu.js ├── logic ├── applications.coffee ├── logic.coffee ├── mailer.coffee ├── records.coffee ├── referrals.coffee ├── sessions.coffee └── templates.coffee ├── migrations └── 110307_add_user_created_at.coffee ├── mongo.coffee ├── script ├── compile └── pushit.sh ├── server.coffee ├── static ├── base64.js ├── client.coffee ├── client.js ├── coffeekup.js ├── jquery-1.4.2.min.js ├── logo.png ├── main.css ├── main.sass ├── markz.coffee ├── markz.js ├── record.coffee ├── record.js ├── shCore.css ├── shCore.js ├── syntax_brushes │ ├── shAutoloader.js │ ├── shBrushAS3.js │ ├── shBrushAppleScript.js │ ├── shBrushBash.js │ ├── shBrushCSharp.js │ ├── shBrushColdFusion.js │ ├── shBrushCpp.js │ ├── shBrushCss.js │ ├── shBrushDelphi.js │ ├── shBrushDiff.js │ ├── shBrushErlang.js │ ├── shBrushGroovy.js │ ├── shBrushJScript.js │ ├── shBrushJava.js │ ├── shBrushJavaFX.js │ ├── shBrushPerl.js │ ├── shBrushPhp.js │ ├── shBrushPlain.js │ ├── shBrushPowerShell.js │ ├── shBrushPython.js │ ├── shBrushRuby.js │ ├── shBrushSass.js │ ├── shBrushScala.js │ ├── shBrushSql.js │ ├── shBrushVb.js │ ├── shBrushXml.js │ ├── shCore.js │ └── shLegacy.js ├── underscore.js └── xregexp.js ├── templates ├── admin │ └── messages.coffee ├── applicants.coffee ├── apply.coffee ├── bookmarklet.coffee ├── inbox.coffee ├── index.coffee ├── layout.coffee ├── login.coffee ├── message.coffee ├── password_reset.coffee ├── record.coffee ├── refer.coffee ├── register.coffee ├── reply.coffee ├── submit.coffee ├── user.coffee └── users.coffee ├── utils.coffee └── vendor └── www-forms └── www-forms.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.bak 3 | .sass-cache 4 | test.* 5 | log/* 6 | config.coffee 7 | config/deploy.rb 8 | config/deploy -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/connect-auth"] 2 | path = vendor/connect-auth 3 | url = http://github.com/ciaranj/connect-auth.git 4 | [submodule "vendor/validator"] 5 | path = vendor/validator 6 | url = https://github.com/chriso/node-validator.git 7 | [submodule "vendor/cookie-node"] 8 | path = vendor/cookie-node 9 | url = https://github.com/jaekwon/cookie-node.git 10 | -------------------------------------------------------------------------------- /Capfile: -------------------------------------------------------------------------------- 1 | load 'deploy' if respond_to?(:namespace) # cap2 differentiator 2 | Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) } 3 | 4 | load 'config/deploy' # remove this line to skip loading any of the default tasks 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DEAD PROJECT 2 | ============ 3 | 4 | This project is dead. A new web framework for node.js+coffeescript is in the works. 5 | 6 | YCatalyst 7 | ========= 8 | 9 | YCatalyst is a Hacker News clone written for Node.js in Coffeescript. 10 | You can view the original site at http://ycatalyst.com. 11 | 12 | Please note that this is alpha quality and very much a work in progress. 13 | If you would like to contribute, please email me at jkwon.work@gmail.com. 14 | 15 | If you want to check out the real-time features, you can create a test 16 | account at our staging server: http://staging.ycatalyst.com:8080/. 17 | Use invite-code 'staging'. 18 | 19 | Features 20 | ======== 21 | 22 | * Real-time updates of comments 23 | * Invite-only membership with an application process 24 | 25 | Dependencies 26 | ============ 27 | 28 | * Node.js v0.3.2 or higher, preferably v0.4.2 29 | * Coffeescript v1.0.1 30 | * Sass (as in Haml/Sass) 31 | 32 | npm install: 33 | 34 | * coffee-script 35 | * node-mongodb-native 36 | * nodemailer 37 | 38 | git submodule init will install more dependencies, some from my personal forks. 39 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | # informal list of TODOs here until the Github Issues page takes off 2 | 3 | - need to fetch some top items and rescore them, otherwise stale items on the front page won't gravitate down as they should 4 | 5 | # keep a todo list of tests to write here 6 | TESTS 7 | - need tests for routing logic in utils 8 | - regression: header parsing in default_wrapper 9 | -------------------------------------------------------------------------------- /config.coffee.sample: -------------------------------------------------------------------------------- 1 | exports.sendgrid_auth = { 2 | user: 'SENDGRID_USER_EMAIL' 3 | password: 'SENDGRID_USER_PASSWORD' 4 | } 5 | 6 | exports.superfeedr_auth = { 7 | user: 'SUPERFEEDR_USER' 8 | password: 'SUPERFEEDR_PASSWORD' 9 | } 10 | 11 | exports.cookie_secret = 'SOME SECRET STRING' 12 | 13 | exports.mongo = { 14 | dbname: 'ycatalyst' 15 | host: 'localhost' 16 | port: 27017 17 | } 18 | 19 | exports.server = { 20 | host: '0.0.0.0' 21 | port: 8126 22 | } 23 | 24 | exports.support_email = 'SUPPORT@YOURDOMAIN.COM' 25 | -------------------------------------------------------------------------------- /logic/applications.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | require.paths.unshift 'vendor' 8 | mongo = require '../mongo' 9 | mailer = require './mailer' 10 | utils = require '../utils' 11 | config = require '../config' 12 | 13 | # members can upvote/downvote, admins can also invite/delete 14 | # vote: 'upvote', 'downvote', 'invite', or 'delete' 15 | exports.vote = (application_id, current_user, vote, cb) -> 16 | switch vote 17 | when 'accept' 18 | update_operation = {$addToSet: {accepted_by: current_user.username}, $pull: {denied_by: current_user.username}} 19 | when 'deny' 20 | update_operation = {$addToSet: {denied_by: current_user.username}, $pull: {accepted_by: current_user.username}} 21 | when 'invite' 22 | if not current_user.is_admin 23 | cb("unauthorized") 24 | return 25 | update_operation = {$set: {invited_at: new Date(), invited_by: current_user.username}} 26 | # also send an invite 27 | do_invite(application_id) 28 | when 'delete' 29 | if not current_user.is_admin 30 | cb("unauthorized") 31 | return 32 | update_operation = {$set: {deleted_at: new Date(), deleted_by: current_user.username}} 33 | mongo.applications.update {_id: application_id}, update_operation, (err, stuff) -> 34 | if err 35 | cb(err) 36 | return 37 | cb() 38 | 39 | # send the newly invited user an email with an invitation code. 40 | do_invite = (application_id) -> 41 | mongo.applications.findOne {_id: application_id}, (err, application) -> 42 | new_invite = _id: utils.randid(), application_id: application_id, created_at: new Date() 43 | mongo.invites.save new_invite, (err, invite) -> 44 | mailer.send_invitation application, invite 45 | -------------------------------------------------------------------------------- /logic/logic.coffee: -------------------------------------------------------------------------------- 1 | exports.records = require './records' 2 | exports.sessions = require './sessions' 3 | exports.mailer = require './mailer' 4 | exports.referrals = require './referrals' 5 | exports.templates = require './templates' 6 | exports.applications = require './applications' 7 | -------------------------------------------------------------------------------- /logic/mailer.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | email = require('nodemailer') 8 | base64 = require('../static/base64') 9 | utils = require('../utils') 10 | mongo = require('../mongo') 11 | config = require('../config') 12 | 13 | # configure nodemailer 14 | # HACK: quick workaround around https://github.com/andris9/Nodemailer/issues/8 15 | oslib = require('os') 16 | if not oslib.hostname? 17 | oslib.hostname = oslib.getHostname 18 | 19 | email.SMTP = { 20 | host: 'smtp.sendgrid.net' 21 | port: 587 22 | use_authentication: true 23 | user: config.sendgrid_auth.user 24 | pass: config.sendgrid_auth.password 25 | } 26 | 27 | # options: 28 | # to, from, subject, body 29 | exports.mail_text = mail_text = (options, cb) -> 30 | if not options.to or not options.from or not options.subject or not options.body 31 | throw 'to/from/subject/body not set in call to mail_text' 32 | email.send_mail 33 | to: options.to 34 | sender: options.from 35 | subject: options.subject 36 | body: options.body 37 | cb 38 | 39 | # set some nonce on the user 40 | exports.send_password = (options, cb) -> 41 | options.user.password_reset_nonce = nonce = utils.randid() 42 | mongo.users.save options.user, (err, stuff) -> 43 | if err 44 | cb(err) if cb 45 | else 46 | body = "To reset your password for YCatalyst, visit this link: http://ycatalyst.com/password_reset?key=#{nonce}&username=#{options.user.username}\n" 47 | mail_text({from: config.support_email, to: options.user.email, subject: "YCatalyst Password Reset", body: body}, cb) 48 | 49 | # send the user a referral 50 | exports.send_referral = (referral, cb) -> 51 | body = """Hello #{referral.first_name}, 52 | 53 | A member of YCatalyst who goes by #{referral.referred_by} referred you to the network. 54 | Please visit this link to continue: http://ycatalyst.com/apply?referral=#{referral._id} 55 | 56 | -ycat """ 57 | mail_text {from: config.support_email, to: referral.email, subject: "You've been referred to YCatalyst by (#{referral.referred_by})", body: body}, (err) -> 58 | if err 59 | referral.err = ''+err 60 | else 61 | referral.emailed_at = new Date() 62 | cb(err) if cb 63 | mongo.referrals.save referral, (err, stuff) -> 64 | if err 65 | console.log "Error in updating referral: #{err}" 66 | 67 | # send the user an invitation email 68 | exports.send_invitation = (application, invite, cb) -> 69 | body = """Hello #{application.first_name}, 70 | 71 | This is your invitation to YCatalyst. 72 | Please visit this link to register: http://ycatalyst.com/register?invite_code=#{invite._id}&email=#{escape(application.email)} 73 | 74 | -ycat """ 75 | mail_text {from: config.support_email, to: application.email, subject: "You've been invited to YCatalyst!", body: body}, (err) -> 76 | if err 77 | update_operation = {$set: {err: ''+err}} 78 | else 79 | update_operation = {$set: {emailed_at: new Date()}} 80 | cb(err) if cb 81 | # update the application. we can't save here because that may trample a prior save. 82 | mongo.applications.update {_id: application._id}, (err, stuff) -> 83 | if err 84 | console.log "Error in updating application: #{err}" 85 | -------------------------------------------------------------------------------- /logic/records.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | mongo = require '../mongo' 8 | utils = require '../utils' 9 | rec = require '../static/record' 10 | 11 | exports.get_records = (root_id, level, fn) -> 12 | now = new Date() 13 | mongo.records.findOne _id: root_id, (err, root) -> 14 | all = {} 15 | if not root? 16 | fn(err, null) 17 | return 18 | all[root_id] = new rec.Record(root) 19 | tofetch = [root_id] 20 | fetchmore = (i) -> 21 | # NOTE: http://talklikeaduck.denhaven2.com/2009/04/15/ordered-hashes-in-ruby-1-9-and-javascript 22 | # and http://ejohn.org/blog/javascript-in-chrome/ 23 | # The side effect of sorting here is that the dangle method will automagically sort the children by score. 24 | mongo.records.find {parent_id: {$in: tofetch}}, {sort: [['score', -1]]}, (err, cursor) -> 25 | cursor.toArray (err, records) -> 26 | tofetch = [] 27 | for record in records 28 | tofetch.push(record._id) 29 | all[record._id] = new rec.Record(record) 30 | if i > 1 31 | fetchmore(i-1) 32 | else 33 | console.log "get_records in #{new Date() - now}" 34 | fn(err, all) 35 | fetchmore(level) 36 | 37 | exports.get_one_record = (rid, fn) -> 38 | mongo.records.findOne _id: rid, (err, recdata) -> 39 | if recdata 40 | fn(err, new rec.Record(recdata)) 41 | else 42 | fn(err, null) 43 | 44 | # given a record object, return an object we can return to the client 45 | # any time you need to send a record to the client through ajax, 46 | # scrub it here 47 | exports.scrubbed_recdata = (record) -> 48 | object = utils.deep_clone(record.recdata) 49 | delete object.upvoters 50 | return object 51 | 52 | # given a record, rescores the record 53 | exports.score_record = (record) -> 54 | # constants 55 | newness_factor = 0.5 # how important is newness in hours? 56 | gravity = 1.8 57 | timebase_hours = 2.0 58 | # variables 59 | t = record.recdata.created_at.getTime() 60 | h = t / (60*60*1000) 61 | d_h = ((new Date()) - record.recdata.created_at) / (60*60*1000) 62 | points = record.recdata.points 63 | score = h*newness_factor + (points-1) / (Math.pow((d_h+timebase_hours),gravity)) 64 | # console.log "t: #{t} h: #{h} d_h: #{d_h} points: #{points} score: #{score}" 65 | record.recdata.score = score 66 | 67 | # recdata: the record data object 68 | # parent: the data object for the parent, may be null or undefined 69 | # returns: a new Record object 70 | exports.create_record = (recdata, parent) -> 71 | parents = [] 72 | if parent? 73 | if not recdata.parent_id? 74 | recdata.parent_id = parent.recdata._id 75 | if parent.recdata.parents? 76 | parents = [parent.recdata._id].concat(parent.recdata.parents[0..5]) 77 | else 78 | parents = [parent.recdata._id] 79 | recdata.parent_followers = parent.recdata.followers if parent.recdata.followers 80 | else 81 | recdata.parent_id = null # need this for mongodb indexing 82 | if not recdata._id? 83 | recdata._id = utils.randid() 84 | recdata.created_at = new Date() 85 | recdata.parents = parents 86 | recdata.points = if recdata.upvoters then recdata.upvoters.length else 0 87 | record = new rec.Record(recdata) 88 | record.is_new = true 89 | exports.score_record(record) 90 | return record 91 | 92 | # given a bunch of records and the root, organize it into a tree 93 | # returns the root, and children can be accessed w/ .children 94 | exports.dangle = (records, root_id) -> 95 | root = records[root_id] 96 | for id, record of records 97 | parent = records[record.recdata.parent_id] 98 | if parent 99 | if not parent.children 100 | parent.children = [] 101 | parent.children.push(record) 102 | # we now have the root... 103 | # pull out poll items and put them in a different spot. 104 | if root.recdata.type == 'poll' 105 | orig_children = root.children 106 | root.children = [] 107 | root.choices = [] 108 | for child in orig_children 109 | if child.recdata.type == 'choice' 110 | root.choices.push(child) 111 | else 112 | root.children.push(child) 113 | return root 114 | 115 | # follow or unfollow the given record... 116 | exports.follow = (rid, user, do_follow, cb) -> 117 | if do_follow 118 | update_operation = {$addToSet: {followers: user._id}} 119 | else 120 | update_operation = {$pull: {followers: user._id}} 121 | mongo.records.update {_id: rid}, update_operation, cb 122 | -------------------------------------------------------------------------------- /logic/referrals.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | require.paths.unshift 'vendor' 8 | mongo = require '../mongo' 9 | mailer = require './mailer' 10 | utils = require '../utils' 11 | config = require '../config' 12 | 13 | # submit/create a new referral. 14 | # referral = :first_name, :last_name, :email, :referred_by 15 | exports.submit = (referral, cb) -> 16 | referral._id = utils.randid() 17 | referral.created_at = new Date() 18 | # look for a previous referral with the same email 19 | mongo.referrals.findOne {email: referral.email}, (err, existing) -> 20 | if err 21 | cb(err) 22 | return 23 | if existing 24 | cb('That user appears to already have been referred') 25 | return 26 | mongo.referrals.save referral, (err, stuff) -> 27 | cb(err) 28 | if not err 29 | # send an email to the email 30 | mailer.send_referral referral, (err) -> 31 | cb(err) 32 | -------------------------------------------------------------------------------- /logic/sessions.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | mongo = require '../mongo' 8 | 9 | # a global hash from record id to {username: {timestamp}} 10 | all_sessions = undefined 11 | mongo.after_open 'app', -> 12 | mongo.app.findOne({_id: 'all_sessions'}, (err, stuff) -> 13 | all_sessions = stuff or {_id: 'all_sessions'} 14 | ) 15 | 16 | # clear old sessions after 60 secondsish 17 | setInterval (-> 18 | now = new Date() 19 | num_cleared = 0 20 | num_seen = 0 21 | for key, sessions of all_sessions 22 | continue if key == '_id' 23 | # we count the number of sessions per key, cuz javascript has no suitable object.length 24 | num_seen_for_key = 0 25 | for username, session of sessions 26 | # TODO this is stupid. replace with a better dict implementation with length 27 | continue if username == '_fake_length' 28 | num_seen_for_key += 1 29 | if now - session.timestamp > 60*1000 30 | num_cleared += 1 31 | delete sessions[username] 32 | sessions._fake_length = num_seen_for_key 33 | # if there are zero sessions on a key, then remove that session 34 | if sessions._fake_length == 0 35 | delete all_sessions[key] 36 | # other 37 | num_seen += num_seen_for_key 38 | if num_cleared > 0 39 | console.log "cleared #{num_cleared} of #{num_seen} in #{new Date() - now} sessions" 40 | # every interval save the sessions object 41 | mongo.app.save all_sessions, (err, stuff) -> 42 | if err? 43 | console.log "error saving all_sessions: " + err 44 | ), 15000 45 | 46 | # create or update the session for key/username 47 | exports.touch_session = (key, username) -> 48 | sessions = all_sessions[key] 49 | if not sessions? 50 | sessions = all_sessions[key] = {} 51 | s = sessions[username] 52 | if not s? 53 | s = sessions[username] = {} 54 | s.timestamp = new Date() 55 | 56 | # get sorted list of [record_id, num views] 57 | exports.get_viewers = -> 58 | views = [] # list of [record id, num viewers] 59 | for key, sessions of all_sessions 60 | continue if key == '_id' 61 | if key != '_fake_length' # not sure why i put this here 62 | views.push( [key, sessions._fake_length] ) 63 | views.sort( (a, b) -> b[1] - a[1] ) 64 | return views 65 | 66 | # get list of usernames watching an item 67 | exports.get_watching = (rid) -> 68 | watching = if all_sessions[rid]? then (username for username, session of (all_sessions[rid] or {})) else [] 69 | return watching 70 | -------------------------------------------------------------------------------- /logic/templates.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | coffeekup = require '../static/coffeekup' 8 | coffeescript = require 'coffee-script' 9 | sass = require 'sass' 10 | utils = require '../utils' 11 | Markz = require('../static/markz').Markz 12 | config = require '../config' 13 | 14 | # autoreloading of templates for development environment 15 | template_mtimes = {} 16 | template_require = (filename) -> 17 | path = require.resolve("../templates/#{filename}.coffee") 18 | if config.env and config.env == 'development' 19 | stat = require('fs').statSync(path) 20 | if not template_mtimes[path] or template_mtimes[path] < stat.mtime 21 | console.log "loading templates/#{filename}.coffee template..." 22 | template_mtimes[path] = stat.mtime 23 | delete require.cache[path] 24 | return require(path) 25 | 26 | exports.render_layout = (template, context, req, res) -> 27 | # helper to render with layout, mind the closure. much like 'render :partial' in rails. 28 | # this way you can always call 'render' from within template code, and 29 | # the closure will be carried through. 30 | _render = (template, context) -> 31 | # these should be rather static entities that extend the language as a DSL. 32 | # typical dynamic parameters should go in 'context'. 33 | locals = 34 | require: require 35 | render: _render 36 | static_file: utils.static_file 37 | Markz: Markz 38 | if req? 39 | context.current_user = req.current_user 40 | tmpl_module = template_require(template) 41 | # compile the coffeekup render fn 42 | if not tmpl_module._compiled_fn? 43 | if not tmpl_module.template? 44 | throw new Error "The template file #{template} does not export a 'template' coffeekup function" 45 | try 46 | tmpl_module._compiled_fn = coffeekup.compile tmpl_module.template, dynamic_locals: true 47 | catch err 48 | console.log "err in compiling #{template}: " + err 49 | throw err 50 | # plugin: sass 51 | if tmpl_module.sass and not tmpl_module["_compiled_sass"]? 52 | try 53 | tmpl_module["_compiled_sass"] = _csass = sass.render(tmpl_module.sass) 54 | if not _csass 55 | console.log "Warning: sass for template is empty: #{template}" 56 | catch err 57 | console.log "err in compiling sass for #{template}: " + err 58 | throw err 59 | # plugin: coffeescript 60 | if tmpl_module.coffeescript and not tmpl_module["_compiled_coffeescript"]? 61 | try 62 | if typeof tmpl_module.coffeescript == 'function' 63 | tmpl_module["_compiled_coffeescript"] = "(#{""+tmpl_module.coffeescript})();" 64 | else 65 | tmpl_module["_compiled_coffeescript"] = coffeescript.compile(tmpl_module.coffeescript) 66 | catch err 67 | console.log "err in compiling coffeescript for #{template}: " + err 68 | throw err 69 | # compile the body 70 | html = '' 71 | try 72 | html += tmpl_module._compiled_fn(context: context, locals: locals) 73 | if tmpl_module._compiled_coffeescript 74 | html += "\n" 75 | if tmpl_module._compiled_sass 76 | html += "\n" 77 | catch err 78 | console.log "err in rendering #{template}: " + err 79 | throw err 80 | return html 81 | 82 | layout_context = {} 83 | layout_context.title = 'YCatalyst' if not context.title? 84 | layout_context.body_template = template 85 | layout_context.body_context = context 86 | layout_context.current_user = req.current_user 87 | html = _render('layout', layout_context) 88 | if res? 89 | res.writeHead 200, status: 'ok' 90 | res.end html 91 | 92 | -------------------------------------------------------------------------------- /migrations/110307_add_user_created_at.coffee: -------------------------------------------------------------------------------- 1 | mongo = require '../mongo' 2 | 3 | mongo.after_open 'users', -> 4 | mongo.users.find {}, (err, cursor) -> 5 | cursor.toArray (err, users) -> 6 | console.log "adding created_at for #{users.length} users" 7 | for user in users 8 | if user.created_at 9 | continue 10 | user.created_at = (new Date()) 11 | mongo.users.save user, (err, stuff) -> 12 | if err 13 | console.log "Error for user #{user._id}: #{err}" 14 | # do nothing 15 | console.log "end" 16 | -------------------------------------------------------------------------------- /mongo.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | Db = require('mongodb').Db 8 | Connection = require('mongodb').Connection 9 | Server = require('mongodb').Server 10 | BSON = require('mongodb').BSONNative 11 | config = require('./config') 12 | 13 | # keep list of callbacks to call after database opens. {name -> [callbacks]} 14 | open_callbacks = {} 15 | did_open = (name, coll) -> 16 | console.log("did_open #{name}") 17 | exports[name] = coll 18 | if open_callbacks[name]? 19 | for callback in open_callbacks[name] 20 | callback() 21 | 22 | # call this function to queue a callback that requires a db collection as soon as the app opens 23 | exports.after_open = (name, cb) -> 24 | if exports[name]? 25 | cb() 26 | else 27 | if open_callbacks[name]? 28 | open_callbacks[name].push(cb) 29 | else 30 | open_callbacks[name] = [cb] 31 | 32 | db_info = { 33 | 'records': [ 34 | [['parent_id', 1], ['score', 1]] 35 | [['parent_followers', 1], ['created_at', -1]]] 36 | 'users': [ 37 | [['email', 1]]] 38 | 'invites': [ 39 | [['user_id', 1]]] 40 | 'referrals': [ 41 | [['email', 1]]] 42 | 'applications': null 43 | 'messages': null 44 | 'diffbot': [ 45 | [['guid', 1]]] 46 | 'diffbot_subscriptions': null 47 | 'app': null 48 | } 49 | 50 | db = exports.db = new Db(config.mongo.dbname, new Server(config.mongo.host, config.mongo.port, {}), {native_parser: true}) 51 | db.open (err, db) -> 52 | for name, indices of db_info 53 | db.collection name, (err, coll) -> 54 | if indices 55 | for index in indices 56 | coll.ensureIndex index, (err, indexName) -> 57 | console.log "ensured index: #{indexName}" 58 | # TODO should call did_open after all indices are ensured, with callback chaining of sorts. 59 | did_open(name, coll) 60 | -------------------------------------------------------------------------------- /script/compile: -------------------------------------------------------------------------------- 1 | cd static 2 | coffee -c client.coffee 3 | coffee -c markz.coffee 4 | coffee -c record.coffee 5 | sass main.sass main.css 6 | -------------------------------------------------------------------------------- /script/pushit.sh: -------------------------------------------------------------------------------- 1 | git add .; git commit -m "."; git push jaekwon; cap $1 deploy 2 | -------------------------------------------------------------------------------- /static/base64.js: -------------------------------------------------------------------------------- 1 | /* adapted by Jed Schmidt for use as a node.js module */ 2 | 3 | exports.encode = base64encode; 4 | exports.decode = base64decode; 5 | this.chars = function( string ) { 6 | base64EncodeChars = string || "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 7 | base64DecodeChars = []; 8 | 9 | for ( var i = 128; i--; ) { 10 | if ( base64DecodeChars[ i ] === undefined ) 11 | base64DecodeChars[ i ] = -1; 12 | 13 | base64DecodeChars[ base64EncodeChars.charCodeAt( i ) ] = i; 14 | } 15 | 16 | return this; 17 | 18 | }; 19 | 20 | this.chars(); 21 | 22 | /* Copyright (C) 1999 Masanao Izumo 23 | * Version: 1.0 24 | * LastModified: Dec 25 1999 25 | * This library is free. You can redistribute it and/or modify it. 26 | */ 27 | 28 | function base64encode( str ) { 29 | var out, i, len; 30 | var c1, c2, c3; 31 | 32 | len = str.length; 33 | i = 0; 34 | out = ""; 35 | while(i < len) { 36 | c1 = str.charCodeAt(i++) & 0xff; 37 | if(i == len) 38 | { 39 | out += base64EncodeChars.charAt(c1 >> 2); 40 | out += base64EncodeChars.charAt((c1 & 0x3) << 4); 41 | out += "=="; 42 | break; 43 | } 44 | c2 = str.charCodeAt(i++); 45 | if(i == len) 46 | { 47 | out += base64EncodeChars.charAt(c1 >> 2); 48 | out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); 49 | out += base64EncodeChars.charAt((c2 & 0xF) << 2); 50 | out += "="; 51 | break; 52 | } 53 | c3 = str.charCodeAt(i++); 54 | out += base64EncodeChars.charAt(c1 >> 2); 55 | out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); 56 | out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)); 57 | out += base64EncodeChars.charAt(c3 & 0x3F); 58 | } 59 | return out; 60 | } 61 | 62 | function base64decode( str ) { 63 | var c1, c2, c3, c4; 64 | var i, len, out; 65 | 66 | len = str.length; 67 | i = 0; 68 | out = ""; 69 | while(i < len) { 70 | /* c1 */ 71 | do { 72 | c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; 73 | } while(i < len && c1 == -1); 74 | if(c1 == -1) 75 | break; 76 | 77 | /* c2 */ 78 | do { 79 | c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; 80 | } while(i < len && c2 == -1); 81 | if(c2 == -1) 82 | break; 83 | 84 | out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4)); 85 | 86 | /* c3 */ 87 | do { 88 | c3 = str.charCodeAt(i++) & 0xff; 89 | if(c3 == 61) 90 | return out; 91 | c3 = base64DecodeChars[c3]; 92 | } while(i < len && c3 == -1); 93 | if(c3 == -1) 94 | break; 95 | 96 | out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2)); 97 | 98 | /* c4 */ 99 | do { 100 | c4 = str.charCodeAt(i++) & 0xff; 101 | if(c4 == 61) 102 | return out; 103 | c4 = base64DecodeChars[c4]; 104 | } while(i < len && c4 == -1); 105 | if(c4 == -1) 106 | break; 107 | out += String.fromCharCode(((c3 & 0x03) << 6) | c4); 108 | } 109 | return out; 110 | } -------------------------------------------------------------------------------- /static/client.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | App = window.App = {} 8 | 9 | # most pages are real time, but the inbox is not. 10 | # this flag determines whether to update records 11 | # from the synchronous response data, or from longpolling. 12 | App.is_longpolling = false 13 | 14 | # gets set at document.ready 15 | App.current_user = null 16 | 17 | # depth of comments to show 18 | App.DEFAULT_DEPTH = 5 19 | 20 | # list of all newly upvoted records 21 | App.upvoted = null 22 | App.following = null 23 | 24 | # include a javascript file TODO support jsonp 25 | App.include = (filename) -> 26 | script = document.createElement('script') 27 | script.src = filename 28 | script.type = 'text/javascript' 29 | $('head').append(script) 30 | 31 | # counter to prevent server flooding 32 | App.poll_errors = 0 33 | 34 | # insert/render or redraw the records based on new/updated recdata from the server 35 | App.handle_updates = (recdatas) -> 36 | for recdata in recdatas 37 | parent = $('#'+recdata.parent_id) 38 | # if we need to insert a new record 39 | if $('#'+recdata.parent_id).length > 0 and $('#'+recdata._id).length == 0 40 | # insert if parent is not a leaf node 41 | if parent.parents('.record').length >= App.DEFAULT_DEPTH 42 | # this is too far. just increment 'xyz more replies' of the parent. 43 | parent.find('>.children>.more').removeClass('hidden').find('>.number').increment() 44 | else 45 | # render it 46 | record = new Record(recdata) 47 | if record.recdata.type == 'choice' 48 | parent.find('>.contents>.choices').append(record.render("default", is_root: false, current_user: App.current_user)) 49 | else 50 | parent.find('>.children').prepend(record.render("default", is_root: false, current_user: App.current_user)) 51 | # otherwise we're updating possibly an existing record 52 | else 53 | record = new Record(recdata) 54 | record.redraw(current_user: App.current_user) 55 | 56 | # poll for updates for root and its near children 57 | App.poll = (root) -> 58 | $.ajax { 59 | cache: false 60 | type: "GET" 61 | url: "/r/#{root.attr('id')}/recv" 62 | dataType: "json" 63 | error: -> 64 | App.poll_errors += 1 65 | console.log "polling again in 10: error" 66 | setTimeout(( -> App.poll(root)), 10*1000) 67 | success: (data) -> 68 | try 69 | App.poll_errors = 0 70 | if data 71 | App.handle_updates data 72 | console.log "polling again immediately" 73 | App.poll(root) 74 | else 75 | # might be a broken connection. 76 | # ajax requests should at least come back with a {status} 77 | App.poll_errors += 1 78 | console.log "polling again in 10: error?" 79 | setTimeout(( -> App.poll(root)), 10*1000) 80 | catch e 81 | console.log(e) 82 | } 83 | 84 | # given an input field or textarea, 85 | # show some default text (gray, italicized) 86 | # input: a single jQuery selection 87 | # default_text: (optional) the default text to show 88 | # if not present, will look for 'data-default-text' html attribute 89 | App.set_default_text = (input, default_text) -> 90 | orig_name = input.attr('name') 91 | default_text ||= input.attr('data-default-text') 92 | on_focus = => 93 | input.removeClass 'default_text' 94 | input.attr('name', orig_name) # to handle synchronous submits 95 | if input.val() == default_text 96 | input.val '' 97 | on_blur = => 98 | if input.val() == default_text or input.val() == '' 99 | input.val(default_text) 100 | input.attr('name', '_not_'+orig_name) # to handle synchronous submits 101 | input.addClass 'default_text' 102 | on_blur() 103 | input.focus(on_focus) 104 | input.blur(on_blur) 105 | input.data('default_text', default_text) 106 | 107 | jQuery.fn.extend( 108 | 'set_default_text': (default_text) -> 109 | this.each (i, thor) -> 110 | elem = $(thor) 111 | App.set_default_text(elem, default_text) 112 | 'get_value': () -> 113 | value = $(this).val() 114 | if $(this).data('default_text') == value 115 | return '' 116 | else 117 | return value 118 | 'increment': () -> 119 | this.text(parseInt(this.text())+1) 120 | 'decrement': () -> 121 | this.text(parseInt(this.text())-1) 122 | 'make_autoresizable': () -> 123 | this.each (i, textarea) -> 124 | textarea = $(textarea) 125 | # we don't use a textarea because chrome has issues with undo's not working 126 | # when you interlace edits on multiple textareas. 127 | cloned_textarea = $(document.createElement('div')); #textarea.clone() 128 | cloned_textarea.attr 129 | cols: textarea.attr('cols') 130 | rows: textarea.attr('rows') 131 | cloned_textarea.css 132 | minHeight: textarea.css('min-height') 133 | minWidth: textarea.css('min-width') 134 | fontFamily: textarea.css('font-family') 135 | fontSize: textarea.css('font-size') 136 | padding: textarea.css('padding') 137 | overflow: 'hidden' # the cloned textarea's scrollbar causes an extra newline at the end sometimes 138 | # hide it but don't actually hide it. 139 | cloned_textarea.css position: 'absolute', left: '-1000000px', disabled: true 140 | $(document.body).prepend cloned_textarea 141 | autoresize = (event) -> 142 | cloned_textarea.css 143 | width: textarea.css('width') 144 | #console.log(textarea.css('height')) 145 | cloned_textarea.text('') 146 | for line in textarea.val().split("\n") 147 | cloned_textarea.append(hE(line)) 148 | cloned_textarea.append('
') 149 | cloned_textarea.append('
') 150 | textarea.css 'height', cloned_textarea[0].scrollHeight 151 | textarea.bind('keyup', autoresize) 152 | # force autoresize right now 153 | setTimeout(autoresize, 0) 154 | ) 155 | 156 | # start longpoll'n 157 | App.start_longpolling = -> 158 | App.is_longpolling = true 159 | if $('[data-root="true"]').length > 0 160 | root = $('[data-root="true"]:eq(0)') 161 | # http://stackoverflow.com/questions/2703861/chromes-loading-indicator-keeps-spinning-during-xmlhttprequest 162 | setTimeout(( -> App.poll(root)), 500) 163 | 164 | $(document).ready -> 165 | # get the id of the current user 166 | App.current_user = 167 | if $('#current_user').length > 0 168 | _id: $("#current_user").attr('data-id'), username: $("#current_user").attr('data-username') 169 | else 170 | null 171 | # find all upvoted records 172 | App.upvoted = $.map($('.record[data-upvoted="true"]'), (e) -> e.id) 173 | # find all following records 174 | App.following = $.map($('.record[data-following="true"]'), (e) -> e.id) 175 | -------------------------------------------------------------------------------- /static/client.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | /* 3 | # YCatalyst 4 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 5 | # MIT Licensed 6 | */ var App; 7 | var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; 8 | App = window.App = {}; 9 | App.is_longpolling = false; 10 | App.current_user = null; 11 | App.DEFAULT_DEPTH = 5; 12 | App.upvoted = null; 13 | App.following = null; 14 | App.include = function(filename) { 15 | var script; 16 | script = document.createElement('script'); 17 | script.src = filename; 18 | script.type = 'text/javascript'; 19 | return $('head').append(script); 20 | }; 21 | App.poll_errors = 0; 22 | App.handle_updates = function(recdatas) { 23 | var parent, recdata, record, _i, _len, _results; 24 | _results = []; 25 | for (_i = 0, _len = recdatas.length; _i < _len; _i++) { 26 | recdata = recdatas[_i]; 27 | parent = $('#' + recdata.parent_id); 28 | _results.push($('#' + recdata.parent_id).length > 0 && $('#' + recdata._id).length === 0 ? parent.parents('.record').length >= App.DEFAULT_DEPTH ? parent.find('>.children>.more').removeClass('hidden').find('>.number').increment() : (record = new Record(recdata), record.recdata.type === 'choice' ? parent.find('>.contents>.choices').append(record.render("default", { 29 | is_root: false, 30 | current_user: App.current_user 31 | })) : parent.find('>.children').prepend(record.render("default", { 32 | is_root: false, 33 | current_user: App.current_user 34 | }))) : (record = new Record(recdata), record.redraw({ 35 | current_user: App.current_user 36 | }))); 37 | } 38 | return _results; 39 | }; 40 | App.poll = function(root) { 41 | return $.ajax({ 42 | cache: false, 43 | type: "GET", 44 | url: "/r/" + (root.attr('id')) + "/recv", 45 | dataType: "json", 46 | error: function() { 47 | App.poll_errors += 1; 48 | console.log("polling again in 10: error"); 49 | return setTimeout((function() { 50 | return App.poll(root); 51 | }), 10 * 1000); 52 | }, 53 | success: function(data) { 54 | try { 55 | App.poll_errors = 0; 56 | if (data) { 57 | App.handle_updates(data); 58 | console.log("polling again immediately"); 59 | return App.poll(root); 60 | } else { 61 | App.poll_errors += 1; 62 | console.log("polling again in 10: error?"); 63 | return setTimeout((function() { 64 | return App.poll(root); 65 | }), 10 * 1000); 66 | } 67 | } catch (e) { 68 | return console.log(e); 69 | } 70 | } 71 | }); 72 | }; 73 | App.set_default_text = function(input, default_text) { 74 | var on_blur, on_focus, orig_name; 75 | orig_name = input.attr('name'); 76 | default_text || (default_text = input.attr('data-default-text')); 77 | on_focus = __bind(function() { 78 | input.removeClass('default_text'); 79 | input.attr('name', orig_name); 80 | if (input.val() === default_text) { 81 | return input.val(''); 82 | } 83 | }, this); 84 | on_blur = __bind(function() { 85 | if (input.val() === default_text || input.val() === '') { 86 | input.val(default_text); 87 | input.attr('name', '_not_' + orig_name); 88 | return input.addClass('default_text'); 89 | } 90 | }, this); 91 | on_blur(); 92 | input.focus(on_focus); 93 | input.blur(on_blur); 94 | return input.data('default_text', default_text); 95 | }; 96 | jQuery.fn.extend({ 97 | 'set_default_text': function(default_text) { 98 | return this.each(function(i, thor) { 99 | var elem; 100 | elem = $(thor); 101 | return App.set_default_text(elem, default_text); 102 | }); 103 | }, 104 | 'get_value': function() { 105 | var value; 106 | value = $(this).val(); 107 | if ($(this).data('default_text') === value) { 108 | return ''; 109 | } else { 110 | return value; 111 | } 112 | }, 113 | 'increment': function() { 114 | return this.text(parseInt(this.text()) + 1); 115 | }, 116 | 'decrement': function() { 117 | return this.text(parseInt(this.text()) - 1); 118 | }, 119 | 'make_autoresizable': function() { 120 | return this.each(function(i, textarea) { 121 | var autoresize, cloned_textarea; 122 | textarea = $(textarea); 123 | cloned_textarea = $(document.createElement('div')); 124 | cloned_textarea.attr({ 125 | cols: textarea.attr('cols'), 126 | rows: textarea.attr('rows') 127 | }); 128 | cloned_textarea.css({ 129 | minHeight: textarea.css('min-height'), 130 | minWidth: textarea.css('min-width'), 131 | fontFamily: textarea.css('font-family'), 132 | fontSize: textarea.css('font-size'), 133 | padding: textarea.css('padding'), 134 | overflow: 'hidden' 135 | }); 136 | cloned_textarea.css({ 137 | position: 'absolute', 138 | left: '-1000000px', 139 | disabled: true 140 | }); 141 | $(document.body).prepend(cloned_textarea); 142 | autoresize = function(event) { 143 | var line, _i, _len, _ref; 144 | cloned_textarea.css({ 145 | width: textarea.css('width') 146 | }); 147 | cloned_textarea.text(''); 148 | _ref = textarea.val().split("\n"); 149 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 150 | line = _ref[_i]; 151 | cloned_textarea.append(hE(line)); 152 | cloned_textarea.append('
'); 153 | } 154 | cloned_textarea.append('
'); 155 | return textarea.css('height', cloned_textarea[0].scrollHeight); 156 | }; 157 | textarea.bind('keyup', autoresize); 158 | return setTimeout(autoresize, 0); 159 | }); 160 | } 161 | }); 162 | App.start_longpolling = function() { 163 | var root; 164 | App.is_longpolling = true; 165 | if ($('[data-root="true"]').length > 0) { 166 | root = $('[data-root="true"]:eq(0)'); 167 | return setTimeout((function() { 168 | return App.poll(root); 169 | }), 500); 170 | } 171 | }; 172 | $(document).ready(function() { 173 | App.current_user = $('#current_user').length > 0 ? { 174 | _id: $("#current_user").attr('data-id'), 175 | username: $("#current_user").attr('data-username') 176 | } : null; 177 | App.upvoted = $.map($('.record[data-upvoted="true"]'), function(e) { 178 | return e.id; 179 | }); 180 | return App.following = $.map($('.record[data-following="true"]'), function(e) { 181 | return e.id; 182 | }); 183 | }); 184 | }).call(this); 185 | -------------------------------------------------------------------------------- /static/coffeekup.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var cache, coffee, coffeekup, skeleton, support, tags; 3 | var __indexOf = Array.prototype.indexOf || function(item) { 4 | for (var i = 0, l = this.length; i < l; i++) { 5 | if (this[i] === item) return i; 6 | } 7 | return -1; 8 | }; 9 | if (typeof window != "undefined" && window !== null) { 10 | coffeekup = window.CoffeeKup = {}; 11 | coffee = typeof CoffeeScript != "undefined" && CoffeeScript !== null ? CoffeeScript : null; 12 | } else { 13 | coffeekup = exports; 14 | coffee = require('coffee-script'); 15 | } 16 | coffeekup.version = '0.2.2'; 17 | skeleton = function(ck_options) { 18 | var ck_buffer, ck_doctypes, ck_esc, ck_indent, ck_render_attrs, ck_repeat, ck_self_closing, ck_tabs, ck_tag, coffeescript, comment, doctype, h, tag, text, _ref, _ref2, _ref3, _ref4; 19 | if (ck_options == null) { 20 | ck_options = {}; 21 | } 22 | (_ref = ck_options.context) != null ? _ref : ck_options.context = {}; 23 | (_ref2 = ck_options.locals) != null ? _ref2 : ck_options.locals = {}; 24 | (_ref3 = ck_options.format) != null ? _ref3 : ck_options.format = false; 25 | (_ref4 = ck_options.autoescape) != null ? _ref4 : ck_options.autoescape = false; 26 | ck_buffer = []; 27 | ck_render_attrs = function(obj) { 28 | var k, str, v; 29 | str = ''; 30 | for (k in obj) { 31 | v = obj[k]; 32 | str += " " + k + "=\"" + (ck_esc(v)) + "\""; 33 | } 34 | return str; 35 | }; 36 | ck_doctypes = { 37 | '5': '', 38 | 'xml': '', 39 | 'default': '', 40 | 'transitional': '', 41 | 'strict': '', 42 | 'frameset': '', 43 | '1.1': '', 44 | 'basic': '', 45 | 'mobile': '' 46 | }; 47 | ck_self_closing = ['area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'link', 'meta', 'param']; 48 | ck_esc = function(txt) { 49 | if (ck_options.autoescape) { 50 | return h(txt); 51 | } else { 52 | return String(txt); 53 | } 54 | }; 55 | ck_tabs = 0; 56 | ck_repeat = function(string, count) { 57 | return Array(count + 1).join(string); 58 | }; 59 | ck_indent = function() { 60 | if (ck_options.format) { 61 | return text(ck_repeat(' ', ck_tabs)); 62 | } 63 | }; 64 | h = function(txt) { 65 | return String(txt).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); 66 | }; 67 | doctype = function(type) { 68 | if (type == null) { 69 | type = 5; 70 | } 71 | text(ck_doctypes[type]); 72 | if (ck_options.format) { 73 | return text('\n'); 74 | } 75 | }; 76 | text = function(txt) { 77 | ck_buffer.push(String(txt)); 78 | return null; 79 | }; 80 | comment = function(cmt) { 81 | text(""); 82 | if (ck_options.format) { 83 | return text('\n'); 84 | } 85 | }; 86 | tag = function() { 87 | var name; 88 | name = arguments[0]; 89 | delete arguments[0]; 90 | return ck_tag(name, arguments); 91 | }; 92 | ck_tag = function(name, opts) { 93 | var o, result, _i, _j, _len, _len2; 94 | ck_indent(); 95 | text("<" + name); 96 | for (_i = 0, _len = opts.length; _i < _len; _i++) { 97 | o = opts[_i]; 98 | if (typeof o === 'object') { 99 | text(ck_render_attrs(o)); 100 | } 101 | } 102 | if (__indexOf.call(ck_self_closing, name) >= 0) { 103 | text(' />'); 104 | if (ck_options.format) { 105 | text('\n'); 106 | } 107 | } else { 108 | text('>'); 109 | for (_j = 0, _len2 = opts.length; _j < _len2; _j++) { 110 | o = opts[_j]; 111 | switch (typeof o) { 112 | case 'string': 113 | case 'number': 114 | text(ck_esc(o)); 115 | break; 116 | case 'function': 117 | if (ck_options.format) { 118 | text('\n'); 119 | } 120 | ck_tabs++; 121 | result = o.call(ck_options.context); 122 | if (typeof result === 'string') { 123 | ck_indent(); 124 | text(ck_esc(result)); 125 | if (ck_options.format) { 126 | text('\n'); 127 | } 128 | } 129 | ck_tabs--; 130 | ck_indent(); 131 | } 132 | } 133 | text(""); 134 | if (ck_options.format) { 135 | text('\n'); 136 | } 137 | } 138 | return null; 139 | }; 140 | coffeescript = function(code) { 141 | return script(";(" + code + ")();"); 142 | }; 143 | return null; 144 | }; 145 | support = 'var __slice = Array.prototype.slice;\nvar __hasProp = Object.prototype.hasOwnProperty;\nvar __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };\nvar __extends = function(child, parent) {\n for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }\n function ctor() { this.constructor = child; }\n ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype;\n return child;\n};\nvar __indexOf = Array.prototype.indexOf || function(item) {\n for (var i = 0, l = this.length; i < l; i++) {\n if (this[i] === item) return i;\n }\n return -1;\n};'; 146 | skeleton = String(skeleton).replace(/function\s*\(ck_options\)\s*\{/, '').replace(/return null;\s*\}$/, ''); 147 | skeleton = support + skeleton; 148 | tags = 'a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdo|big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|keygen|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|source|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|u|ul|video|xmp'.split('|'); 149 | coffeekup.compile = function(template, options) { 150 | var code, k, t, tags_here, v, _i, _j, _len, _len2, _ref, _ref2; 151 | if (options == null) { 152 | options = {}; 153 | } 154 | (_ref = options.locals) != null ? _ref : options.locals = {}; 155 | if (typeof template === 'function') { 156 | template = String(template); 157 | } else if (typeof template === 'string' && (coffee != null)) { 158 | template = coffee.compile(template, { 159 | bare: true 160 | }); 161 | template = "function(){" + template + "}"; 162 | } 163 | tags_here = []; 164 | for (_i = 0, _len = tags.length; _i < _len; _i++) { 165 | t = tags[_i]; 166 | if (template.indexOf(t) > -1) { 167 | tags_here.push(t); 168 | } 169 | } 170 | code = skeleton + ("var " + (tags_here.join(',')) + ";"); 171 | for (_j = 0, _len2 = tags_here.length; _j < _len2; _j++) { 172 | t = tags_here[_j]; 173 | code += "" + t + " = function(){return ck_tag('" + t + "', arguments)};"; 174 | } 175 | _ref2 = options.locals; 176 | for (k in _ref2) { 177 | v = _ref2[k]; 178 | if (typeof v === 'function') { 179 | code += "var " + k + " = " + v + ";"; 180 | } else { 181 | code += "var " + k + " = " + (JSON.stringify(v)) + ";"; 182 | } 183 | } 184 | if (options.dynamic_locals) { 185 | code += 'with(ck_options.locals){'; 186 | } 187 | code += "(" + template + ").call(ck_options.context);"; 188 | if (options.dynamic_locals) { 189 | code += '}'; 190 | } 191 | code += "return ck_buffer.join('');"; 192 | return new Function('ck_options', code); 193 | }; 194 | cache = {}; 195 | coffeekup.render = function(template, options) { 196 | var tpl, _ref, _ref2, _ref3; 197 | if (options == null) { 198 | options = {}; 199 | } 200 | (_ref = options.context) != null ? _ref : options.context = {}; 201 | (_ref2 = options.locals) != null ? _ref2 : options.locals = {}; 202 | (_ref3 = options.cache) != null ? _ref3 : options.cache = true; 203 | if (options.locals.body != null) { 204 | options.context.body = options.locals.body; 205 | delete options.locals.body; 206 | } 207 | if (options.cache && (cache[template] != null)) { 208 | tpl = cache[template]; 209 | } else if (options.cache) { 210 | tpl = cache[template] = coffeekup.compile(template, options); 211 | } else { 212 | tpl = coffeekup.compile(template, options); 213 | } 214 | return tpl(options); 215 | }; 216 | if (typeof window == "undefined" || window === null) { 217 | coffeekup.adapters = { 218 | simple: function(template, data) { 219 | return coffeekup.render(template, { 220 | context: data 221 | }); 222 | } 223 | }; 224 | coffeekup.adapters.meryl = coffeekup.adapters.simple; 225 | } 226 | }).call(this); 227 | -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaekwon/YCatalyst/b35b7918035631a4a5e87e67750ddf128c61d16e/static/logo.png -------------------------------------------------------------------------------- /static/main.css: -------------------------------------------------------------------------------- 1 | /* YCatalyst 2 | * Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 3 | * MIT Licensed 4 | */ 5 | .hidden { 6 | display: none; } 7 | 8 | body { 9 | color: black; 10 | font-family: Verdana, Verdana, Geneva, sans-serif; 11 | font-size: 10pt; } 12 | body a { 13 | color: #333333; } 14 | body a:visited { 15 | color: #999999; } 16 | body #headerbar { 17 | background-color: #3f3f3f; 18 | padding: 4px; 19 | color: white; } 20 | body #headerbar img { 21 | vertical-align: middle; } 22 | body #headerbar .username { 23 | font-weight: 900; } 24 | body #headerbar a { 25 | color: white; 26 | text-decoration: none; } 27 | body #headerbar .logo { 28 | font-weight: 700; } 29 | body #headerbar .links { 30 | margin: 0px 20px; } 31 | body #body_contents { 32 | margin: 10px 0px 0px 10px; } 33 | body img { 34 | border: 0px; 35 | margin: 0px; 36 | padding: 0px; } 37 | body input, body textarea, body button { 38 | margin: 2px 0px; } 39 | body input[type=text], body input[type=password] { 40 | width: 460px; 41 | padding: 2px; 42 | font-family: Verdana, Verdana, Geneva, sans-serif; 43 | font-size: 14px; } 44 | body textarea { 45 | padding: 2px; 46 | min-width: 460px; 47 | min-height: 100px; 48 | font-family: Verdana, Verdana, Geneva, sans-serif; 49 | font-size: 14px; } 50 | body .record { 51 | position: relative; 52 | margin: 10px 0px; 53 | padding-left: 15px; } 54 | body .record h1, body .record h2, body .record h3, body .record h4, body .record h5, body .record h6, body .record pre { 55 | margin: 5px 0px; } 56 | body .record h1.title { 57 | font-size: 12pt; 58 | line-height: 12pt; } 59 | body .record h1.title a.title { 60 | font-size: 12pt; } 61 | body .record a.title { 62 | text-decoration: none; 63 | font-size: 10pt; } 64 | body .record .host { 65 | font-size: 10px; 66 | color: #999999; } 67 | body .record a.upvote { 68 | position: absolute; 69 | left: 0px; 70 | top: 3px; 71 | text-decoration: none; 72 | font-size: 10px; 73 | color: #999999; } 74 | body .record span.self_made { 75 | position: absolute; 76 | left: 0px; 77 | top: 3px; 78 | color: #cc00cc; } 79 | body .record .item_info { 80 | position: relative; 81 | color: #999999; 82 | font-size: 8pt; } 83 | body .record .item_info a { 84 | color: #999999; 85 | text-decoration: none; } 86 | body .record .item_info a:hover { 87 | text-decoration: underline; } 88 | body .record .item_info .unfollow { 89 | color: #ff9999; } 90 | body .record .contents { 91 | color: #333333; 92 | margin: 2px 0px; } 93 | body .record .contents.deleted { 94 | color: gray; } 95 | body .record .reply, body .record .addchoice { 96 | color: #999999; 97 | text-decoration: underline; 98 | margin-right: 1em; 99 | font-size: 0.8em; } 100 | body .record .edit_box { 101 | margin: 10px 0px; } 102 | body .record .edit_box button { 103 | margin: 5px 5px 0px 0px; } 104 | body .record .reply_box { 105 | margin: 10px 0px 10px 5px; 106 | padding-left: 10px; 107 | border-left: 1px solid #eeeeee; } 108 | body .record .reply_box button { 109 | margin: 5px 5px 0px 0px; } 110 | body .record .choices { 111 | border-left: 2px solid #bbbbff; 112 | margin-left: 5px; 113 | padding-left: 5px; 114 | color: #2222aa; } 115 | body .record .children { 116 | border-left: 1px solid #eeeeee; 117 | margin-left: 5px; 118 | padding-left: 5px; } 119 | body .record .children .more { 120 | color: #999999; 121 | text-decoration: none; 122 | font-size: 0.8em; } 123 | body label { 124 | font-size: 0.8em; 125 | color: gray; } 126 | body ol, body ul { 127 | padding-left: 20px; 128 | margin: 0px; 129 | color: #999999; } 130 | body ol li, body ul li { 131 | padding: 0px; 132 | margin: 0px; } 133 | body ol li > .back_to_black, body ul li > .back_to_black { 134 | color: black; } 135 | body ol li > div, body ul li > div { 136 | color: #999999; 137 | position: relative; 138 | padding-left: 15px; 139 | margin: 5px 0px; } 140 | body ol li a, body ul li a { 141 | text-decoration: none; } 142 | body blockquote { 143 | border-left: 2px solid #999999; 144 | margin: 0px 0px 0px 5px; 145 | padding: 0px 0px 0px 5px; 146 | color: #999999; } 147 | body table th { 148 | font-weight: 200; 149 | color: gray; } 150 | body input.default_text, body textarea.default_text { 151 | color: gray; 152 | font-style: italic; 153 | font-size: 0.9em; } 154 | 155 | div.tabs div.choice { 156 | display: inline; 157 | margin: 0px 10px; } 158 | -------------------------------------------------------------------------------- /static/main.sass: -------------------------------------------------------------------------------- 1 | /* 2 | * YCatalyst 3 | * Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | * MIT Licensed 5 | */ 6 | 7 | $dark_text: #333 8 | $light_text: #999 9 | $blue_text: #22A 10 | $light_blue_text: #66F 11 | $the_font: Verdana, Verdana, Geneva, sans-serif 12 | 13 | .hidden 14 | display: none 15 | 16 | body 17 | color: black 18 | font-family: $the_font 19 | font-size: 10pt 20 | 21 | a 22 | color: $dark_text 23 | &:visited 24 | color: $light_text 25 | 26 | #headerbar 27 | img 28 | vertical-align: middle 29 | background-color: #3f3f3f 30 | padding: 4px 31 | color: #FFF 32 | .username 33 | font-weight: 900 34 | a 35 | color: #FFF 36 | text-decoration: none 37 | .logo 38 | font-weight: 700 39 | .links 40 | margin: 0px 20px 41 | 42 | #body_contents 43 | margin: 10px 0px 0px 10px 44 | 45 | img 46 | border: 0px 47 | margin: 0px 48 | padding: 0px 49 | 50 | input, textarea, button 51 | margin: 2px 0px 52 | 53 | input[type=text], input[type=password] 54 | width: 460px 55 | padding: 2px 56 | font-family: $the_font 57 | font-size: 14px 58 | 59 | textarea 60 | padding: 2px 61 | min-width: 460px 62 | min-height: 100px 63 | font-family: $the_font 64 | font-size: 14px 65 | 66 | .record 67 | position: relative 68 | margin: 10px 0px 69 | padding-left: 15px 70 | h1, h2, h3, h4, h5, h6, pre 71 | margin: 5px 0px 72 | h1.title 73 | font-size: 12pt 74 | line-height: 12pt 75 | a.title 76 | font-size: 12pt 77 | a.title 78 | text-decoration: none 79 | font-size: 10pt 80 | .host 81 | font-size: 10px 82 | color: $light_text 83 | // triangle upvote button 84 | a.upvote 85 | position: absolute 86 | left: 0px 87 | top: 3px 88 | text-decoration: none 89 | font-size: 10px 90 | color: $light_text 91 | // the asterisk * when the post/comment is created by current_user 92 | span.self_made 93 | position: absolute 94 | left: 0px 95 | top: 3px 96 | color: #CC00CC 97 | // x points by user xyz ago | link | edit | delete 98 | .item_info 99 | position: relative 100 | color: $light_text 101 | font-size: 8pt 102 | a 103 | color: $light_text 104 | text-decoration: none 105 | &:hover 106 | text-decoration: underline 107 | .unfollow 108 | color: #F99 109 | .contents 110 | color: $dark_text 111 | margin: 2px 0px 112 | &.deleted 113 | color: gray 114 | .reply, .addchoice 115 | color: $light_text 116 | text-decoration: underline 117 | margin-right: 1em 118 | font-size: 0.8em 119 | .edit_box 120 | margin: 10px 0px 121 | button 122 | margin: 5px 5px 0px 0px 123 | .reply_box 124 | margin: 10px 0px 10px 5px 125 | padding-left: 10px 126 | border-left: 1px solid #eee 127 | button 128 | margin: 5px 5px 0px 0px 129 | .choices 130 | border-left: 2px solid #bbf 131 | margin-left: 5px 132 | padding-left: 5px 133 | color: $blue_text 134 | .children 135 | border-left: 1px solid #eee 136 | margin-left: 5px 137 | padding-left: 5px 138 | .more 139 | color: $light_text 140 | text-decoration: none 141 | font-size: 0.8em 142 | 143 | label 144 | font-size: 0.8em 145 | color: gray 146 | 147 | ol, ul 148 | padding-left: 20px 149 | margin: 0px 150 | // make the bullets light colored 151 | color: $light_text 152 | li 153 | // a hack to make just the bullets light 154 | &>.back_to_black 155 | color: black 156 | padding: 0px 157 | margin: 0px 158 | &>div 159 | color: $light_text 160 | position: relative 161 | padding-left: 15px 162 | margin: 5px 0px 163 | a 164 | text-decoration: none 165 | 166 | blockquote 167 | border-left: 2px solid $light_text 168 | margin: 0px 0px 0px 5px 169 | padding: 0px 0px 0px 5px 170 | color: $light_text 171 | 172 | table 173 | th 174 | font-weight: 200 175 | color: gray 176 | 177 | input.default_text, textarea.default_text 178 | color: gray 179 | font-style: italic 180 | font-size: 0.9em 181 | 182 | div.tabs 183 | div.choice 184 | display: inline 185 | margin: 0px 10px 186 | -------------------------------------------------------------------------------- /static/markz.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | coffeekup = if CoffeeKup? then CoffeeKup else require './coffeekup' 8 | 9 | # some regexes ripped from the node.js validator project 10 | # https://github.com/chriso/node-validator.git 11 | # NOTE: > The /m flag is multiline matching. 12 | # > (?!...) is a negative lookahead. 13 | # > The only way to match a multi-line spanning pattern is to use [\s\S] type classes. 14 | # * Try to capture the trailing newline of block elements like codeblocks. 15 | # TODO: possibly convert all to XRegExp for client compatibility, or at least support it. 16 | re_heading = /^(\#{1,6})(.*)$\n?|^(.*)$\n^(={4,}|-{4,})$\n?/m 17 | re_email = /(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))/ 18 | re_url = /((?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?:\w+:\w+@)?((?:(?:[-\w\d{1-3}]+\.)+(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|edu|co\.uk|ac\.uk|it|fr|tv|museum|asia|local|travel|[a-z]{2}))|((\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)(\.(\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)){3}))(?::[\d]{1,5})?(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?:#(?:[-\w~!$ |\/.,*:;=]|%[a-f\d]{2})*)?/ 19 | re_link = /\[([^\n\[\]]+)\] *\(([^\n\[\]]+)(?: +"([^\n\[\]]+)")?\)/ 20 | re_bold = /\*([^\*\n]+)\*/ 21 | re_newline = /\n/ 22 | re_ulbullets = /(?:^\* +.+$\n?){2,}/m 23 | re_olbullets = /(?:^\d{1,2}\.? +.+$\n?){2,}/m 24 | re_blockquote = /(?:^>.*$\n?)+/m 25 | re_codeblock = /([\s\S]*?)<\/code>\n?/ 26 | 27 | hE = (text) -> 28 | text = text.toString() 29 | return text.replace(/&/g, "&") 30 | .replace(//g, ">") 32 | .replace(/"/g, """) 33 | .replace(/'/g, "'") 34 | 35 | REPLACE_LOOKUP = [ 36 | ['heading', re_heading, (match) -> 37 | if match[1] 38 | # is a ### HEADING type heading 39 | "#{hE match[2]}" 40 | else 41 | # is a HEADING 42 | # ====== type heading 43 | heading_type = if match[4][0] == '=' then 'h1' else 'h2' 44 | "<#{heading_type}>#{hE match[3]}" 45 | ] 46 | ['link', re_link, (match) -> 47 | "#{hE match[1]}"] 48 | ['url', re_url, (match) -> 49 | if match[1] and match[1].length > 0 50 | "#{hE match[0]}" 51 | else 52 | "#{hE match[0]}" 53 | ] 54 | ['email', re_email, (match) -> 55 | "#{hE match[0]}"] 56 | ['blockquote', re_blockquote, (match) -> 57 | unquoted = (line.substr(1) for line in match[0].split("\n")).join("\n") 58 | "
#{Markz::markup unquoted}
"] 59 | ['olbullets', re_olbullets, (match) -> 60 | lines = (line.substr(2).trim() for line in match[0].trim().split("\n")) 61 | markup_lines = ("
  • #{Markz::markup(line)}
  • " for line in lines) 62 | "
      #{markup_lines.join('')}
    "] 63 | ['ulbullets', re_ulbullets, (match) -> 64 | lines = (line.substr(1).trim() for line in match[0].trim().split("\n")) 65 | markup_lines = ("
  • #{Markz::markup(line)}
  • " for line in lines) 66 | ""] 67 | ['bold', re_bold, (match) -> 68 | "#{Markz::markup match[1]}"] 69 | ['newline', re_newline, (match) -> 70 | "
    "] 71 | ['codeblock', re_codeblock, (match) -> 72 | "
    #{hE match[2]}
    "] 73 | ] 74 | 75 | class Markz 76 | markup: (text) -> 77 | type2match = {} # type -> {match, func} 78 | 79 | #for l in replace_lookup 80 | # [type, regex, func] = l 81 | 82 | find_next_match = (type2match, text, cursor) -> 83 | # returns {match, func, type, offset} or null 84 | # fill type2match 85 | for type_regex_func in REPLACE_LOOKUP 86 | [type, regex, func] = type_regex_func 87 | # cleanup or prune 88 | if type2match[type]? 89 | if type2match[type].offset < cursor 90 | delete type2match[type] 91 | else 92 | continue 93 | match = text.substr(cursor).match(regex) 94 | if match? 95 | type2match[type] = match: match, func: func, type: type, offset: match.index+cursor 96 | # return the earliest 97 | earliest = null 98 | for type, stuff of type2match 99 | if not earliest? 100 | earliest = stuff 101 | else if stuff.offset < earliest.offset 102 | earliest = stuff 103 | return earliest 104 | 105 | # collect entities 106 | cursor = 0 107 | coll = [] 108 | while true 109 | next_match = find_next_match(type2match, text, cursor) 110 | if not next_match? 111 | break 112 | if next_match.offset > cursor 113 | coll.push(hE(text.substr(cursor, (next_match.offset - cursor)))) 114 | coll.push(next_match.func(next_match.match)) 115 | cursor = next_match.offset + next_match.match[0].length 116 | coll.push(hE(text.substr(cursor))) 117 | 118 | # add breaks 119 | return coll.join(" ") 120 | 121 | 122 | # if server-side 123 | if exports? 124 | exports.Markz = Markz 125 | exports.hE = hE 126 | # if client-side 127 | if window? 128 | window.Markz = Markz 129 | window.hE = hE 130 | -------------------------------------------------------------------------------- /static/markz.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | /* 3 | # YCatalyst 4 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 5 | # MIT Licensed 6 | */ var Markz, REPLACE_LOOKUP, coffeekup, hE, re_blockquote, re_bold, re_codeblock, re_email, re_heading, re_link, re_newline, re_olbullets, re_ulbullets, re_url; 7 | coffeekup = typeof CoffeeKup != "undefined" && CoffeeKup !== null ? CoffeeKup : require('./coffeekup'); 8 | re_heading = /^(\#{1,6})(.*)$\n?|^(.*)$\n^(={4,}|-{4,})$\n?/m; 9 | re_email = /(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))/; 10 | re_url = /((?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?:\w+:\w+@)?((?:(?:[-\w\d{1-3}]+\.)+(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|edu|co\.uk|ac\.uk|it|fr|tv|museum|asia|local|travel|[a-z]{2}))|((\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)(\.(\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)){3}))(?::[\d]{1,5})?(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?:#(?:[-\w~!$ |\/.,*:;=]|%[a-f\d]{2})*)?/; 11 | re_link = /\[([^\n\[\]]+)\] *\(([^\n\[\]]+)(?: +"([^\n\[\]]+)")?\)/; 12 | re_bold = /\*([^\*\n]+)\*/; 13 | re_newline = /\n/; 14 | re_ulbullets = /(?:^\* +.+$\n?){2,}/m; 15 | re_olbullets = /(?:^\d{1,2}\.? +.+$\n?){2,}/m; 16 | re_blockquote = /(?:^>.*$\n?)+/m; 17 | re_codeblock = /([\s\S]*?)<\/code>\n?/; 18 | hE = function(text) { 19 | text = text.toString(); 20 | return text.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); 21 | }; 22 | REPLACE_LOOKUP = [ 23 | [ 24 | 'heading', re_heading, function(match) { 25 | var heading_type; 26 | if (match[1]) { 27 | return "" + (hE(match[2])) + ""; 28 | } else { 29 | heading_type = match[4][0] === '=' ? 'h1' : 'h2'; 30 | return "<" + heading_type + ">" + (hE(match[3])) + ""; 31 | } 32 | } 33 | ], [ 34 | 'link', re_link, function(match) { 35 | return "" + (hE(match[1])) + ""; 36 | } 37 | ], [ 38 | 'url', re_url, function(match) { 39 | if (match[1] && match[1].length > 0) { 40 | return "" + (hE(match[0])) + ""; 41 | } else { 42 | return "" + (hE(match[0])) + ""; 43 | } 44 | } 45 | ], [ 46 | 'email', re_email, function(match) { 47 | return "" + (hE(match[0])) + ""; 48 | } 49 | ], [ 50 | 'blockquote', re_blockquote, function(match) { 51 | var line, unquoted; 52 | unquoted = ((function() { 53 | var _i, _len, _ref, _results; 54 | _ref = match[0].split("\n"); 55 | _results = []; 56 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 57 | line = _ref[_i]; 58 | _results.push(line.substr(1)); 59 | } 60 | return _results; 61 | })()).join("\n"); 62 | return "
    " + (Markz.prototype.markup(unquoted)) + "
    "; 63 | } 64 | ], [ 65 | 'olbullets', re_olbullets, function(match) { 66 | var line, lines, markup_lines; 67 | lines = (function() { 68 | var _i, _len, _ref, _results; 69 | _ref = match[0].trim().split("\n"); 70 | _results = []; 71 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 72 | line = _ref[_i]; 73 | _results.push(line.substr(2).trim()); 74 | } 75 | return _results; 76 | })(); 77 | markup_lines = (function() { 78 | var _i, _len, _results; 79 | _results = []; 80 | for (_i = 0, _len = lines.length; _i < _len; _i++) { 81 | line = lines[_i]; 82 | _results.push("
  • " + (Markz.prototype.markup(line)) + "
  • "); 83 | } 84 | return _results; 85 | })(); 86 | return "
      " + (markup_lines.join('')) + "
    "; 87 | } 88 | ], [ 89 | 'ulbullets', re_ulbullets, function(match) { 90 | var line, lines, markup_lines; 91 | lines = (function() { 92 | var _i, _len, _ref, _results; 93 | _ref = match[0].trim().split("\n"); 94 | _results = []; 95 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 96 | line = _ref[_i]; 97 | _results.push(line.substr(1).trim()); 98 | } 99 | return _results; 100 | })(); 101 | markup_lines = (function() { 102 | var _i, _len, _results; 103 | _results = []; 104 | for (_i = 0, _len = lines.length; _i < _len; _i++) { 105 | line = lines[_i]; 106 | _results.push("
  • " + (Markz.prototype.markup(line)) + "
  • "); 107 | } 108 | return _results; 109 | })(); 110 | return "
      " + (markup_lines.join('')) + "
    "; 111 | } 112 | ], [ 113 | 'bold', re_bold, function(match) { 114 | return "" + (Markz.prototype.markup(match[1])) + ""; 115 | } 116 | ], [ 117 | 'newline', re_newline, function(match) { 118 | return "
    "; 119 | } 120 | ], [ 121 | 'codeblock', re_codeblock, function(match) { 122 | return "
    " + (hE(match[2])) + "
    "; 123 | } 124 | ] 125 | ]; 126 | Markz = (function() { 127 | function Markz() {} 128 | Markz.prototype.markup = function(text) { 129 | var coll, cursor, find_next_match, next_match, type2match; 130 | type2match = {}; 131 | find_next_match = function(type2match, text, cursor) { 132 | var earliest, func, match, regex, stuff, type, type_regex_func, _i, _len; 133 | for (_i = 0, _len = REPLACE_LOOKUP.length; _i < _len; _i++) { 134 | type_regex_func = REPLACE_LOOKUP[_i]; 135 | type = type_regex_func[0], regex = type_regex_func[1], func = type_regex_func[2]; 136 | if (type2match[type] != null) { 137 | if (type2match[type].offset < cursor) { 138 | delete type2match[type]; 139 | } else { 140 | continue; 141 | } 142 | } 143 | match = text.substr(cursor).match(regex); 144 | if (match != null) { 145 | type2match[type] = { 146 | match: match, 147 | func: func, 148 | type: type, 149 | offset: match.index + cursor 150 | }; 151 | } 152 | } 153 | earliest = null; 154 | for (type in type2match) { 155 | stuff = type2match[type]; 156 | if (!(earliest != null)) { 157 | earliest = stuff; 158 | } else if (stuff.offset < earliest.offset) { 159 | earliest = stuff; 160 | } 161 | } 162 | return earliest; 163 | }; 164 | cursor = 0; 165 | coll = []; 166 | while (true) { 167 | next_match = find_next_match(type2match, text, cursor); 168 | if (!(next_match != null)) { 169 | break; 170 | } 171 | if (next_match.offset > cursor) { 172 | coll.push(hE(text.substr(cursor, next_match.offset - cursor))); 173 | } 174 | coll.push(next_match.func(next_match.match)); 175 | cursor = next_match.offset + next_match.match[0].length; 176 | } 177 | coll.push(hE(text.substr(cursor))); 178 | return coll.join(" "); 179 | }; 180 | return Markz; 181 | })(); 182 | if (typeof exports != "undefined" && exports !== null) { 183 | exports.Markz = Markz; 184 | exports.hE = hE; 185 | } 186 | if (typeof window != "undefined" && window !== null) { 187 | window.Markz = Markz; 188 | window.hE = hE; 189 | } 190 | }).call(this); 191 | -------------------------------------------------------------------------------- /static/shCore.css: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | .syntaxhighlighter a, 18 | .syntaxhighlighter div, 19 | .syntaxhighlighter code, 20 | .syntaxhighlighter table, 21 | .syntaxhighlighter table td, 22 | .syntaxhighlighter table tr, 23 | .syntaxhighlighter table tbody, 24 | .syntaxhighlighter table thead, 25 | .syntaxhighlighter table caption, 26 | .syntaxhighlighter textarea { 27 | -moz-border-radius: 0 0 0 0 !important; 28 | -webkit-border-radius: 0 0 0 0 !important; 29 | background: none !important; 30 | border: 0 !important; 31 | bottom: auto !important; 32 | float: none !important; 33 | height: auto !important; 34 | left: auto !important; 35 | line-height: 1.1em !important; 36 | margin: 0 !important; 37 | outline: 0 !important; 38 | overflow: visible !important; 39 | padding: 0 !important; 40 | position: static !important; 41 | right: auto !important; 42 | text-align: left !important; 43 | top: auto !important; 44 | vertical-align: baseline !important; 45 | width: auto !important; 46 | box-sizing: content-box !important; 47 | font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; 48 | font-weight: normal !important; 49 | font-style: normal !important; 50 | font-size: 1em !important; 51 | min-height: inherit !important; 52 | min-height: auto !important; 53 | } 54 | 55 | .syntaxhighlighter { 56 | width: 100% !important; 57 | margin: 1em 0 1em 0 !important; 58 | position: relative !important; 59 | overflow: auto !important; 60 | font-size: 1em !important; 61 | } 62 | .syntaxhighlighter.source { 63 | overflow: hidden !important; 64 | } 65 | .syntaxhighlighter .bold { 66 | font-weight: bold !important; 67 | } 68 | .syntaxhighlighter .italic { 69 | font-style: italic !important; 70 | } 71 | .syntaxhighlighter .line { 72 | white-space: pre !important; 73 | } 74 | .syntaxhighlighter table { 75 | width: 100% !important; 76 | } 77 | .syntaxhighlighter table caption { 78 | text-align: left !important; 79 | padding: .5em 0 0.5em 1em !important; 80 | } 81 | .syntaxhighlighter table td.code { 82 | width: 100% !important; 83 | } 84 | .syntaxhighlighter table td.code .container { 85 | position: relative !important; 86 | } 87 | .syntaxhighlighter table td.code .container textarea { 88 | box-sizing: border-box !important; 89 | position: absolute !important; 90 | left: 0 !important; 91 | top: 0 !important; 92 | width: 100% !important; 93 | height: 100% !important; 94 | border: none !important; 95 | background: white !important; 96 | padding-left: 1em !important; 97 | overflow: hidden !important; 98 | white-space: pre !important; 99 | } 100 | .syntaxhighlighter table td.gutter .line { 101 | text-align: right !important; 102 | padding: 0 0.5em 0 1em !important; 103 | } 104 | .syntaxhighlighter table td.code .line { 105 | padding: 0 1em !important; 106 | } 107 | .syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line { 108 | padding-left: 0em !important; 109 | } 110 | .syntaxhighlighter.show { 111 | display: block !important; 112 | } 113 | .syntaxhighlighter.collapsed table { 114 | display: none !important; 115 | } 116 | .syntaxhighlighter.collapsed .toolbar { 117 | padding: 0.1em 0.8em 0em 0.8em !important; 118 | font-size: 1em !important; 119 | position: static !important; 120 | width: auto !important; 121 | height: auto !important; 122 | } 123 | .syntaxhighlighter.collapsed .toolbar span { 124 | display: inline !important; 125 | margin-right: 1em !important; 126 | } 127 | .syntaxhighlighter.collapsed .toolbar span a { 128 | padding: 0 !important; 129 | display: none !important; 130 | } 131 | .syntaxhighlighter.collapsed .toolbar span a.expandSource { 132 | display: inline !important; 133 | } 134 | .syntaxhighlighter .toolbar { 135 | position: absolute !important; 136 | right: 1px !important; 137 | top: 1px !important; 138 | width: 11px !important; 139 | height: 11px !important; 140 | font-size: 10px !important; 141 | z-index: 10 !important; 142 | } 143 | .syntaxhighlighter .toolbar span.title { 144 | display: inline !important; 145 | } 146 | .syntaxhighlighter .toolbar a { 147 | display: block !important; 148 | text-align: center !important; 149 | text-decoration: none !important; 150 | padding-top: 1px !important; 151 | } 152 | .syntaxhighlighter .toolbar a.expandSource { 153 | display: none !important; 154 | } 155 | .syntaxhighlighter.ie { 156 | font-size: .9em !important; 157 | padding: 1px 0 1px 0 !important; 158 | } 159 | .syntaxhighlighter.ie .toolbar { 160 | line-height: 8px !important; 161 | } 162 | .syntaxhighlighter.ie .toolbar a { 163 | padding-top: 0px !important; 164 | } 165 | .syntaxhighlighter.printing .line.alt1 .content, 166 | .syntaxhighlighter.printing .line.alt2 .content, 167 | .syntaxhighlighter.printing .line.highlighted .number, 168 | .syntaxhighlighter.printing .line.highlighted.alt1 .content, 169 | .syntaxhighlighter.printing .line.highlighted.alt2 .content { 170 | background: none !important; 171 | } 172 | .syntaxhighlighter.printing .line .number { 173 | color: #bbbbbb !important; 174 | } 175 | .syntaxhighlighter.printing .line .content { 176 | color: black !important; 177 | } 178 | .syntaxhighlighter.printing .toolbar { 179 | display: none !important; 180 | } 181 | .syntaxhighlighter.printing a { 182 | text-decoration: none !important; 183 | } 184 | .syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a { 185 | color: black !important; 186 | } 187 | .syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a { 188 | color: #008200 !important; 189 | } 190 | .syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a { 191 | color: blue !important; 192 | } 193 | .syntaxhighlighter.printing .keyword { 194 | color: #006699 !important; 195 | font-weight: bold !important; 196 | } 197 | .syntaxhighlighter.printing .preprocessor { 198 | color: gray !important; 199 | } 200 | .syntaxhighlighter.printing .variable { 201 | color: #aa7700 !important; 202 | } 203 | .syntaxhighlighter.printing .value { 204 | color: #009900 !important; 205 | } 206 | .syntaxhighlighter.printing .functions { 207 | color: #ff1493 !important; 208 | } 209 | .syntaxhighlighter.printing .constants { 210 | color: #0066cc !important; 211 | } 212 | .syntaxhighlighter.printing .script { 213 | font-weight: bold !important; 214 | } 215 | .syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a { 216 | color: gray !important; 217 | } 218 | .syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a { 219 | color: #ff1493 !important; 220 | } 221 | .syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a { 222 | color: red !important; 223 | } 224 | .syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a { 225 | color: black !important; 226 | } 227 | -------------------------------------------------------------------------------- /static/syntax_brushes/shAutoloader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(2(){1 h=5;h.I=2(){2 n(c,a){4(1 d=0;d|<|≥|>=|≤|<=|\*|\+|-|\/|÷|\^)/g, 48 | css: 'color2' }, 49 | 50 | { regex: /\b(?:and|as|div|mod|not|or|return(?!\s&)(ing)?|equals|(is(n't| not)? )?equal( to)?|does(n't| not) equal|(is(n't| not)? )?(greater|less) than( or equal( to)?)?|(comes|does(n't| not) come) (after|before)|is(n't| not)?( in)? (back|front) of|is(n't| not)? behind|is(n't| not)?( (in|contained by))?|does(n't| not) contain|contain(s)?|(start|begin|end)(s)? with|((but|end) )?(consider|ignor)ing|prop(erty)?|(a )?ref(erence)?( to)?|repeat (until|while|with)|((end|exit) )?repeat|((else|end) )?if|else|(end )?(script|tell|try)|(on )?error|(put )?into|(of )?(it|me)|its|my|with (timeout( of)?|transaction)|end (timeout|transaction))\b/g, 51 | css: 'keyword' }, 52 | 53 | { regex: /\b\d+(st|nd|rd|th)\b/g, // ordinals 54 | css: 'keyword' }, 55 | 56 | { regex: /\b(?:about|above|against|around|at|below|beneath|beside|between|by|(apart|aside) from|(instead|out) of|into|on(to)?|over|since|thr(ough|u)|under)\b/g, 57 | css: 'color3' }, 58 | 59 | { regex: /\b(?:adding folder items to|after receiving|choose( ((remote )?application|color|folder|from list|URL))?|clipboard info|set the clipboard to|(the )?clipboard|entire contents|display(ing| (alert|dialog|mode))?|document( (edited|file|nib name))?|file( (name|type))?|(info )?for|giving up after|(name )?extension|quoted form|return(ed)?|second(?! item)(s)?|list (disks|folder)|text item(s| delimiters)?|(Unicode )?text|(disk )?item(s)?|((current|list) )?view|((container|key) )?window|with (data|icon( (caution|note|stop))?|parameter(s)?|prompt|properties|seed|title)|case|diacriticals|hyphens|numeric strings|punctuation|white space|folder creation|application(s( folder)?| (processes|scripts position|support))?|((desktop )?(pictures )?|(documents|downloads|favorites|home|keychain|library|movies|music|public|scripts|sites|system|users|utilities|workflows) )folder|desktop|Folder Action scripts|font(s| panel)?|help|internet plugins|modem scripts|(system )?preferences|printer descriptions|scripting (additions|components)|shared (documents|libraries)|startup (disk|items)|temporary items|trash|on server|in AppleTalk zone|((as|long|short) )?user name|user (ID|locale)|(with )?password|in (bundle( with identifier)?|directory)|(close|open for) access|read|write( permission)?|(g|s)et eof|using( delimiters)?|starting at|default (answer|button|color|country code|entr(y|ies)|identifiers|items|name|location|script editor)|hidden( answer)?|open(ed| (location|untitled))?|error (handling|reporting)|(do( shell)?|load|run|store) script|administrator privileges|altering line endings|get volume settings|(alert|boot|input|mount|output|set) volume|output muted|(fax|random )?number|round(ing)?|up|down|toward zero|to nearest|as taught in school|system (attribute|info)|((AppleScript( Studio)?|system) )?version|(home )?directory|(IPv4|primary Ethernet) address|CPU (type|speed)|physical memory|time (stamp|to GMT)|replacing|ASCII (character|number)|localized string|from table|offset|summarize|beep|delay|say|(empty|multiple) selections allowed|(of|preferred) type|invisibles|showing( package contents)?|editable URL|(File|FTP|News|Media|Web) [Ss]ervers|Telnet hosts|Directory services|Remote applications|waiting until completion|saving( (in|to))?|path (for|to( (((current|frontmost) )?application|resource))?)|POSIX (file|path)|(background|RGB) color|(OK|cancel) button name|cancel button|button(s)?|cubic ((centi)?met(re|er)s|yards|feet|inches)|square ((kilo)?met(re|er)s|miles|yards|feet)|(centi|kilo)?met(re|er)s|miles|yards|feet|inches|lit(re|er)s|gallons|quarts|(kilo)?grams|ounces|pounds|degrees (Celsius|Fahrenheit|Kelvin)|print( (dialog|settings))?|clos(e(able)?|ing)|(de)?miniaturized|miniaturizable|zoom(ed|able)|attribute run|action (method|property|title)|phone|email|((start|end)ing|home) page|((birth|creation|current|custom|modification) )?date|((((phonetic )?(first|last|middle))|computer|host|maiden|related) |nick)?name|aim|icq|jabber|msn|yahoo|address(es)?|save addressbook|should enable action|city|country( code)?|formatte(r|d address)|(palette )?label|state|street|zip|AIM [Hh]andle(s)?|my card|select(ion| all)?|unsaved|(alpha )?value|entr(y|ies)|group|(ICQ|Jabber|MSN) handle|person|people|company|department|icon image|job title|note|organization|suffix|vcard|url|copies|collating|pages (across|down)|request print time|target( printer)?|((GUI Scripting|Script menu) )?enabled|show Computer scripts|(de)?activated|awake from nib|became (key|main)|call method|of (class|object)|center|clicked toolbar item|closed|for document|exposed|(can )?hide|idle|keyboard (down|up)|event( (number|type))?|launch(ed)?|load (image|movie|nib|sound)|owner|log|mouse (down|dragged|entered|exited|moved|up)|move|column|localization|resource|script|register|drag (info|types)|resigned (active|key|main)|resiz(e(d)?|able)|right mouse (down|dragged|up)|scroll wheel|(at )?index|should (close|open( untitled)?|quit( after last window closed)?|zoom)|((proposed|screen) )?bounds|show(n)?|behind|in front of|size (mode|to fit)|update(d| toolbar item)?|was (hidden|miniaturized)|will (become active|close|finish launching|hide|miniaturize|move|open|quit|(resign )?active|((maximum|minimum|proposed) )?size|show|zoom)|bundle|data source|movie|pasteboard|sound|tool(bar| tip)|(color|open|save) panel|coordinate system|frontmost|main( (bundle|menu|window))?|((services|(excluded from )?windows) )?menu|((executable|frameworks|resource|scripts|shared (frameworks|support)) )?path|(selected item )?identifier|data|content(s| view)?|character(s)?|click count|(command|control|option|shift) key down|context|delta (x|y|z)|key( code)?|location|pressure|unmodified characters|types|(first )?responder|playing|(allowed|selectable) identifiers|allows customization|(auto saves )?configuration|visible|image( name)?|menu form representation|tag|user(-| )defaults|associated file name|(auto|needs) display|current field editor|floating|has (resize indicator|shadow)|hides when deactivated|level|minimized (image|title)|opaque|position|release when closed|sheet|title(d)?)\b/g, 60 | css: 'color3' }, 61 | 62 | { regex: new RegExp(this.getKeywords(specials), 'gm'), css: 'color3' }, 63 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, 64 | { regex: new RegExp(this.getKeywords(ordinals), 'gm'), css: 'keyword' } 65 | ]; 66 | }; 67 | 68 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 69 | Brush.aliases = ['applescript']; 70 | 71 | SyntaxHighlighter.brushes.AppleScript = Brush; 72 | 73 | // CommonJS 74 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 75 | })(); 76 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushBash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | var keywords = 'if fi then elif else for do done until while break continue case function return in eq ne ge le'; 25 | var commands = 'alias apropos awk basename bash bc bg builtin bzip2 cal cat cd cfdisk chgrp chmod chown chroot' + 26 | 'cksum clear cmp comm command cp cron crontab csplit cut date dc dd ddrescue declare df ' + 27 | 'diff diff3 dig dir dircolors dirname dirs du echo egrep eject enable env ethtool eval ' + 28 | 'exec exit expand export expr false fdformat fdisk fg fgrep file find fmt fold format ' + 29 | 'free fsck ftp gawk getopts grep groups gzip hash head history hostname id ifconfig ' + 30 | 'import install join kill less let ln local locate logname logout look lpc lpr lprint ' + 31 | 'lprintd lprintq lprm ls lsof make man mkdir mkfifo mkisofs mknod more mount mtools ' + 32 | 'mv netstat nice nl nohup nslookup open op passwd paste pathchk ping popd pr printcap ' + 33 | 'printenv printf ps pushd pwd quota quotacheck quotactl ram rcp read readonly renice ' + 34 | 'remsync rm rmdir rsync screen scp sdiff sed select seq set sftp shift shopt shutdown ' + 35 | 'sleep sort source split ssh strace su sudo sum symlink sync tail tar tee test time ' + 36 | 'times touch top traceroute trap tr true tsort tty type ulimit umask umount unalias ' + 37 | 'uname unexpand uniq units unset unshar useradd usermod users uuencode uudecode v vdir ' + 38 | 'vi watch wc whereis which who whoami Wget xargs yes' 39 | ; 40 | 41 | this.regexList = [ 42 | { regex: /^#!.*$/gm, css: 'preprocessor bold' }, 43 | { regex: /\/[\w-\/]+/gm, css: 'plain' }, 44 | { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' }, // one line comments 45 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings 46 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings 47 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords 48 | { regex: new RegExp(this.getKeywords(commands), 'gm'), css: 'functions' } // commands 49 | ]; 50 | } 51 | 52 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 53 | Brush.aliases = ['bash', 'shell']; 54 | 55 | SyntaxHighlighter.brushes.Bash = Brush; 56 | 57 | // CommonJS 58 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 59 | })(); 60 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushCSharp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | var keywords = 'abstract as base bool break byte case catch char checked class const ' + 25 | 'continue decimal default delegate do double else enum event explicit ' + 26 | 'extern false finally fixed float for foreach get goto if implicit in int ' + 27 | 'interface internal is lock long namespace new null object operator out ' + 28 | 'override params private protected public readonly ref return sbyte sealed set ' + 29 | 'short sizeof stackalloc static string struct switch this throw true try ' + 30 | 'typeof uint ulong unchecked unsafe ushort using virtual void while'; 31 | 32 | function fixComments(match, regexInfo) 33 | { 34 | var css = (match[0].indexOf("///") == 0) 35 | ? 'color1' 36 | : 'comments' 37 | ; 38 | 39 | return [new SyntaxHighlighter.Match(match[0], match.index, css)]; 40 | } 41 | 42 | this.regexList = [ 43 | { regex: SyntaxHighlighter.regexLib.singleLineCComments, func : fixComments }, // one line comments 44 | { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments 45 | { regex: /@"(?:[^"]|"")*"/g, css: 'string' }, // @-quoted strings 46 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings 47 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings 48 | { regex: /^\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion 49 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // c# keyword 50 | { regex: /\bpartial(?=\s+(?:class|interface|struct)\b)/g, css: 'keyword' }, // contextual keyword: 'partial' 51 | { regex: /\byield(?=\s+(?:return|break)\b)/g, css: 'keyword' } // contextual keyword: 'yield' 52 | ]; 53 | 54 | this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); 55 | }; 56 | 57 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 58 | Brush.aliases = ['c#', 'c-sharp', 'csharp']; 59 | 60 | SyntaxHighlighter.brushes.CSharp = Brush; 61 | 62 | // CommonJS 63 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 64 | })(); 65 | 66 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushColdFusion.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Contributed by Jen 25 | // http://www.jensbits.com/2009/05/14/coldfusion-brush-for-syntaxhighlighter-plus 26 | 27 | var funcs = 'Abs ACos AddSOAPRequestHeader AddSOAPResponseHeader AjaxLink AjaxOnLoad ArrayAppend ArrayAvg ArrayClear ArrayDeleteAt ' + 28 | 'ArrayInsertAt ArrayIsDefined ArrayIsEmpty ArrayLen ArrayMax ArrayMin ArraySet ArraySort ArraySum ArraySwap ArrayToList ' + 29 | 'Asc ASin Atn BinaryDecode BinaryEncode BitAnd BitMaskClear BitMaskRead BitMaskSet BitNot BitOr BitSHLN BitSHRN BitXor ' + 30 | 'Ceiling CharsetDecode CharsetEncode Chr CJustify Compare CompareNoCase Cos CreateDate CreateDateTime CreateObject ' + 31 | 'CreateODBCDate CreateODBCDateTime CreateODBCTime CreateTime CreateTimeSpan CreateUUID DateAdd DateCompare DateConvert ' + 32 | 'DateDiff DateFormat DatePart Day DayOfWeek DayOfWeekAsString DayOfYear DaysInMonth DaysInYear DE DecimalFormat DecrementValue ' + 33 | 'Decrypt DecryptBinary DeleteClientVariable DeserializeJSON DirectoryExists DollarFormat DotNetToCFType Duplicate Encrypt ' + 34 | 'EncryptBinary Evaluate Exp ExpandPath FileClose FileCopy FileDelete FileExists FileIsEOF FileMove FileOpen FileRead ' + 35 | 'FileReadBinary FileReadLine FileSetAccessMode FileSetAttribute FileSetLastModified FileWrite Find FindNoCase FindOneOf ' + 36 | 'FirstDayOfMonth Fix FormatBaseN GenerateSecretKey GetAuthUser GetBaseTagData GetBaseTagList GetBaseTemplatePath ' + 37 | 'GetClientVariablesList GetComponentMetaData GetContextRoot GetCurrentTemplatePath GetDirectoryFromPath GetEncoding ' + 38 | 'GetException GetFileFromPath GetFileInfo GetFunctionList GetGatewayHelper GetHttpRequestData GetHttpTimeString ' + 39 | 'GetK2ServerDocCount GetK2ServerDocCountLimit GetLocale GetLocaleDisplayName GetLocalHostIP GetMetaData GetMetricData ' + 40 | 'GetPageContext GetPrinterInfo GetProfileSections GetProfileString GetReadableImageFormats GetSOAPRequest GetSOAPRequestHeader ' + 41 | 'GetSOAPResponse GetSOAPResponseHeader GetTempDirectory GetTempFile GetTemplatePath GetTickCount GetTimeZoneInfo GetToken ' + 42 | 'GetUserRoles GetWriteableImageFormats Hash Hour HTMLCodeFormat HTMLEditFormat IIf ImageAddBorder ImageBlur ImageClearRect ' + 43 | 'ImageCopy ImageCrop ImageDrawArc ImageDrawBeveledRect ImageDrawCubicCurve ImageDrawLine ImageDrawLines ImageDrawOval ' + 44 | 'ImageDrawPoint ImageDrawQuadraticCurve ImageDrawRect ImageDrawRoundRect ImageDrawText ImageFlip ImageGetBlob ImageGetBufferedImage ' + 45 | 'ImageGetEXIFTag ImageGetHeight ImageGetIPTCTag ImageGetWidth ImageGrayscale ImageInfo ImageNegative ImageNew ImageOverlay ImagePaste ' + 46 | 'ImageRead ImageReadBase64 ImageResize ImageRotate ImageRotateDrawingAxis ImageScaleToFit ImageSetAntialiasing ImageSetBackgroundColor ' + 47 | 'ImageSetDrawingColor ImageSetDrawingStroke ImageSetDrawingTransparency ImageSharpen ImageShear ImageShearDrawingAxis ImageTranslate ' + 48 | 'ImageTranslateDrawingAxis ImageWrite ImageWriteBase64 ImageXORDrawingMode IncrementValue InputBaseN Insert Int IsArray IsBinary ' + 49 | 'IsBoolean IsCustomFunction IsDate IsDDX IsDebugMode IsDefined IsImage IsImageFile IsInstanceOf IsJSON IsLeapYear IsLocalHost ' + 50 | 'IsNumeric IsNumericDate IsObject IsPDFFile IsPDFObject IsQuery IsSimpleValue IsSOAPRequest IsStruct IsUserInAnyRole IsUserInRole ' + 51 | 'IsUserLoggedIn IsValid IsWDDX IsXML IsXmlAttribute IsXmlDoc IsXmlElem IsXmlNode IsXmlRoot JavaCast JSStringFormat LCase Left Len ' + 52 | 'ListAppend ListChangeDelims ListContains ListContainsNoCase ListDeleteAt ListFind ListFindNoCase ListFirst ListGetAt ListInsertAt ' + 53 | 'ListLast ListLen ListPrepend ListQualify ListRest ListSetAt ListSort ListToArray ListValueCount ListValueCountNoCase LJustify Log ' + 54 | 'Log10 LSCurrencyFormat LSDateFormat LSEuroCurrencyFormat LSIsCurrency LSIsDate LSIsNumeric LSNumberFormat LSParseCurrency LSParseDateTime ' + 55 | 'LSParseEuroCurrency LSParseNumber LSTimeFormat LTrim Max Mid Min Minute Month MonthAsString Now NumberFormat ParagraphFormat ParseDateTime ' + 56 | 'Pi PrecisionEvaluate PreserveSingleQuotes Quarter QueryAddColumn QueryAddRow QueryConvertForGrid QueryNew QuerySetCell QuotedValueList Rand ' + 57 | 'Randomize RandRange REFind REFindNoCase ReleaseComObject REMatch REMatchNoCase RemoveChars RepeatString Replace ReplaceList ReplaceNoCase ' + 58 | 'REReplace REReplaceNoCase Reverse Right RJustify Round RTrim Second SendGatewayMessage SerializeJSON SetEncoding SetLocale SetProfileString ' + 59 | 'SetVariable Sgn Sin Sleep SpanExcluding SpanIncluding Sqr StripCR StructAppend StructClear StructCopy StructCount StructDelete StructFind ' + 60 | 'StructFindKey StructFindValue StructGet StructInsert StructIsEmpty StructKeyArray StructKeyExists StructKeyList StructKeyList StructNew ' + 61 | 'StructSort StructUpdate Tan TimeFormat ToBase64 ToBinary ToScript ToString Trim UCase URLDecode URLEncodedFormat URLSessionFormat Val ' + 62 | 'ValueList VerifyClient Week Wrap Wrap WriteOutput XmlChildPos XmlElemNew XmlFormat XmlGetNodeType XmlNew XmlParse XmlSearch XmlTransform ' + 63 | 'XmlValidate Year YesNoFormat'; 64 | 65 | var keywords = 'cfabort cfajaximport cfajaxproxy cfapplet cfapplication cfargument cfassociate cfbreak cfcache cfcalendar ' + 66 | 'cfcase cfcatch cfchart cfchartdata cfchartseries cfcol cfcollection cfcomponent cfcontent cfcookie cfdbinfo ' + 67 | 'cfdefaultcase cfdirectory cfdiv cfdocument cfdocumentitem cfdocumentsection cfdump cfelse cfelseif cferror ' + 68 | 'cfexchangecalendar cfexchangeconnection cfexchangecontact cfexchangefilter cfexchangemail cfexchangetask ' + 69 | 'cfexecute cfexit cffeed cffile cfflush cfform cfformgroup cfformitem cfftp cffunction cfgrid cfgridcolumn ' + 70 | 'cfgridrow cfgridupdate cfheader cfhtmlhead cfhttp cfhttpparam cfif cfimage cfimport cfinclude cfindex ' + 71 | 'cfinput cfinsert cfinterface cfinvoke cfinvokeargument cflayout cflayoutarea cfldap cflocation cflock cflog ' + 72 | 'cflogin cfloginuser cflogout cfloop cfmail cfmailparam cfmailpart cfmenu cfmenuitem cfmodule cfNTauthenticate ' + 73 | 'cfobject cfobjectcache cfoutput cfparam cfpdf cfpdfform cfpdfformparam cfpdfparam cfpdfsubform cfpod cfpop ' + 74 | 'cfpresentation cfpresentationslide cfpresenter cfprint cfprocessingdirective cfprocparam cfprocresult ' + 75 | 'cfproperty cfquery cfqueryparam cfregistry cfreport cfreportparam cfrethrow cfreturn cfsavecontent cfschedule ' + 76 | 'cfscript cfsearch cfselect cfset cfsetting cfsilent cfslider cfsprydataset cfstoredproc cfswitch cftable ' + 77 | 'cftextarea cfthread cfthrow cftimer cftooltip cftrace cftransaction cftree cftreeitem cftry cfupdate cfwddx ' + 78 | 'cfwindow cfxml cfzip cfzipparam'; 79 | 80 | var operators = 'all and any between cross in join like not null or outer some'; 81 | 82 | this.regexList = [ 83 | { regex: new RegExp('--(.*)$', 'gm'), css: 'comments' }, // one line and multiline comments 84 | { regex: SyntaxHighlighter.regexLib.xmlComments, css: 'comments' }, // single quoted strings 85 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings 86 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings 87 | { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, // functions 88 | { regex: new RegExp(this.getKeywords(operators), 'gmi'), css: 'color1' }, // operators and such 89 | { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword 90 | ]; 91 | } 92 | 93 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 94 | Brush.aliases = ['coldfusion','cf']; 95 | 96 | SyntaxHighlighter.brushes.ColdFusion = Brush; 97 | 98 | // CommonJS 99 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 100 | })(); 101 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushCpp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Copyright 2006 Shin, YoungJin 25 | 26 | var datatypes = 'ATOM BOOL BOOLEAN BYTE CHAR COLORREF DWORD DWORDLONG DWORD_PTR ' + 27 | 'DWORD32 DWORD64 FLOAT HACCEL HALF_PTR HANDLE HBITMAP HBRUSH ' + 28 | 'HCOLORSPACE HCONV HCONVLIST HCURSOR HDC HDDEDATA HDESK HDROP HDWP ' + 29 | 'HENHMETAFILE HFILE HFONT HGDIOBJ HGLOBAL HHOOK HICON HINSTANCE HKEY ' + 30 | 'HKL HLOCAL HMENU HMETAFILE HMODULE HMONITOR HPALETTE HPEN HRESULT ' + 31 | 'HRGN HRSRC HSZ HWINSTA HWND INT INT_PTR INT32 INT64 LANGID LCID LCTYPE ' + 32 | 'LGRPID LONG LONGLONG LONG_PTR LONG32 LONG64 LPARAM LPBOOL LPBYTE LPCOLORREF ' + 33 | 'LPCSTR LPCTSTR LPCVOID LPCWSTR LPDWORD LPHANDLE LPINT LPLONG LPSTR LPTSTR ' + 34 | 'LPVOID LPWORD LPWSTR LRESULT PBOOL PBOOLEAN PBYTE PCHAR PCSTR PCTSTR PCWSTR ' + 35 | 'PDWORDLONG PDWORD_PTR PDWORD32 PDWORD64 PFLOAT PHALF_PTR PHANDLE PHKEY PINT ' + 36 | 'PINT_PTR PINT32 PINT64 PLCID PLONG PLONGLONG PLONG_PTR PLONG32 PLONG64 POINTER_32 ' + 37 | 'POINTER_64 PSHORT PSIZE_T PSSIZE_T PSTR PTBYTE PTCHAR PTSTR PUCHAR PUHALF_PTR ' + 38 | 'PUINT PUINT_PTR PUINT32 PUINT64 PULONG PULONGLONG PULONG_PTR PULONG32 PULONG64 ' + 39 | 'PUSHORT PVOID PWCHAR PWORD PWSTR SC_HANDLE SC_LOCK SERVICE_STATUS_HANDLE SHORT ' + 40 | 'SIZE_T SSIZE_T TBYTE TCHAR UCHAR UHALF_PTR UINT UINT_PTR UINT32 UINT64 ULONG ' + 41 | 'ULONGLONG ULONG_PTR ULONG32 ULONG64 USHORT USN VOID WCHAR WORD WPARAM WPARAM WPARAM ' + 42 | 'char bool short int __int32 __int64 __int8 __int16 long float double __wchar_t ' + 43 | 'clock_t _complex _dev_t _diskfree_t div_t ldiv_t _exception _EXCEPTION_POINTERS ' + 44 | 'FILE _finddata_t _finddatai64_t _wfinddata_t _wfinddatai64_t __finddata64_t ' + 45 | '__wfinddata64_t _FPIEEE_RECORD fpos_t _HEAPINFO _HFILE lconv intptr_t ' + 46 | 'jmp_buf mbstate_t _off_t _onexit_t _PNH ptrdiff_t _purecall_handler ' + 47 | 'sig_atomic_t size_t _stat __stat64 _stati64 terminate_function ' + 48 | 'time_t __time64_t _timeb __timeb64 tm uintptr_t _utimbuf ' + 49 | 'va_list wchar_t wctrans_t wctype_t wint_t signed'; 50 | 51 | var keywords = 'break case catch class const __finally __exception __try ' + 52 | 'const_cast continue private public protected __declspec ' + 53 | 'default delete deprecated dllexport dllimport do dynamic_cast ' + 54 | 'else enum explicit extern if for friend goto inline ' + 55 | 'mutable naked namespace new noinline noreturn nothrow ' + 56 | 'register reinterpret_cast return selectany ' + 57 | 'sizeof static static_cast struct switch template this ' + 58 | 'thread throw true false try typedef typeid typename union ' + 59 | 'using uuid virtual void volatile whcar_t while'; 60 | 61 | var functions = 'assert isalnum isalpha iscntrl isdigit isgraph islower isprint' + 62 | 'ispunct isspace isupper isxdigit tolower toupper errno localeconv ' + 63 | 'setlocale acos asin atan atan2 ceil cos cosh exp fabs floor fmod ' + 64 | 'frexp ldexp log log10 modf pow sin sinh sqrt tan tanh jmp_buf ' + 65 | 'longjmp setjmp raise signal sig_atomic_t va_arg va_end va_start ' + 66 | 'clearerr fclose feof ferror fflush fgetc fgetpos fgets fopen ' + 67 | 'fprintf fputc fputs fread freopen fscanf fseek fsetpos ftell ' + 68 | 'fwrite getc getchar gets perror printf putc putchar puts remove ' + 69 | 'rename rewind scanf setbuf setvbuf sprintf sscanf tmpfile tmpnam ' + 70 | 'ungetc vfprintf vprintf vsprintf abort abs atexit atof atoi atol ' + 71 | 'bsearch calloc div exit free getenv labs ldiv malloc mblen mbstowcs ' + 72 | 'mbtowc qsort rand realloc srand strtod strtol strtoul system ' + 73 | 'wcstombs wctomb memchr memcmp memcpy memmove memset strcat strchr ' + 74 | 'strcmp strcoll strcpy strcspn strerror strlen strncat strncmp ' + 75 | 'strncpy strpbrk strrchr strspn strstr strtok strxfrm asctime ' + 76 | 'clock ctime difftime gmtime localtime mktime strftime time'; 77 | 78 | this.regexList = [ 79 | { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments 80 | { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments 81 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings 82 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings 83 | { regex: /^ *#.*/gm, css: 'preprocessor' }, 84 | { regex: new RegExp(this.getKeywords(datatypes), 'gm'), css: 'color1 bold' }, 85 | { regex: new RegExp(this.getKeywords(functions), 'gm'), css: 'functions bold' }, 86 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword bold' } 87 | ]; 88 | }; 89 | 90 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 91 | Brush.aliases = ['cpp', 'c']; 92 | 93 | SyntaxHighlighter.brushes.Cpp = Brush; 94 | 95 | // CommonJS 96 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 97 | })(); 98 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushCss.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | function getKeywordsCSS(str) 25 | { 26 | return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b'; 27 | }; 28 | 29 | function getValuesCSS(str) 30 | { 31 | return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b'; 32 | }; 33 | 34 | var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' + 35 | 'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' + 36 | 'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' + 37 | 'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' + 38 | 'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' + 39 | 'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' + 40 | 'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' + 41 | 'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' + 42 | 'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' + 43 | 'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' + 44 | 'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' + 45 | 'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' + 46 | 'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' + 47 | 'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index'; 48 | 49 | var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+ 50 | 'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+ 51 | 'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+ 52 | 'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+ 53 | 'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+ 54 | 'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+ 55 | 'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+ 56 | 'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+ 57 | 'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+ 58 | 'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+ 59 | 'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+ 60 | 'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+ 61 | 'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+ 62 | 'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow'; 63 | 64 | var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif'; 65 | 66 | this.regexList = [ 67 | { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments 68 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings 69 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings 70 | { regex: /\#[a-fA-F0-9]{3,6}/g, css: 'value' }, // html colors 71 | { regex: /(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)/g, css: 'value' }, // sizes 72 | { regex: /!important/g, css: 'color3' }, // !important 73 | { regex: new RegExp(getKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords 74 | { regex: new RegExp(getValuesCSS(values), 'g'), css: 'value' }, // values 75 | { regex: new RegExp(this.getKeywords(fonts), 'g'), css: 'color1' } // fonts 76 | ]; 77 | 78 | this.forHtmlScript({ 79 | left: /(<|<)\s*style.*?(>|>)/gi, 80 | right: /(<|<)\/\s*style\s*(>|>)/gi 81 | }); 82 | }; 83 | 84 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 85 | Brush.aliases = ['css']; 86 | 87 | SyntaxHighlighter.brushes.CSS = Brush; 88 | 89 | // CommonJS 90 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 91 | })(); 92 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushDelphi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | var keywords = 'abs addr and ansichar ansistring array as asm begin boolean byte cardinal ' + 25 | 'case char class comp const constructor currency destructor div do double ' + 26 | 'downto else end except exports extended false file finalization finally ' + 27 | 'for function goto if implementation in inherited int64 initialization ' + 28 | 'integer interface is label library longint longword mod nil not object ' + 29 | 'of on or packed pansichar pansistring pchar pcurrency pdatetime pextended ' + 30 | 'pint64 pointer private procedure program property pshortstring pstring ' + 31 | 'pvariant pwidechar pwidestring protected public published raise real real48 ' + 32 | 'record repeat set shl shortint shortstring shr single smallint string then ' + 33 | 'threadvar to true try type unit until uses val var varirnt while widechar ' + 34 | 'widestring with word write writeln xor'; 35 | 36 | this.regexList = [ 37 | { regex: /\(\*[\s\S]*?\*\)/gm, css: 'comments' }, // multiline comments (* *) 38 | { regex: /{(?!\$)[\s\S]*?}/gm, css: 'comments' }, // multiline comments { } 39 | { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line 40 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings 41 | { regex: /\{\$[a-zA-Z]+ .+\}/g, css: 'color1' }, // compiler Directives and Region tags 42 | { regex: /\b[\d\.]+\b/g, css: 'value' }, // numbers 12345 43 | { regex: /\$[a-zA-Z0-9]+\b/g, css: 'value' }, // numbers $F5D3 44 | { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword 45 | ]; 46 | }; 47 | 48 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 49 | Brush.aliases = ['delphi', 'pascal', 'pas']; 50 | 51 | SyntaxHighlighter.brushes.Delphi = Brush; 52 | 53 | // CommonJS 54 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 55 | })(); 56 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushDiff.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | this.regexList = [ 25 | { regex: /^\+\+\+.*$/gm, css: 'color2' }, 26 | { regex: /^\-\-\-.*$/gm, css: 'color2' }, 27 | { regex: /^\s.*$/gm, css: 'color1' }, 28 | { regex: /^@@.*@@$/gm, css: 'variable' }, 29 | { regex: /^\+[^\+]{1}.*$/gm, css: 'string' }, 30 | { regex: /^\-[^\-]{1}.*$/gm, css: 'comments' } 31 | ]; 32 | }; 33 | 34 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 35 | Brush.aliases = ['diff', 'patch']; 36 | 37 | SyntaxHighlighter.brushes.Diff = Brush; 38 | 39 | // CommonJS 40 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 41 | })(); 42 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushErlang.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Contributed by Jean-Lou Dupont 25 | // http://jldupont.blogspot.com/2009/06/erlang-syntax-highlighter.html 26 | 27 | // According to: http://erlang.org/doc/reference_manual/introduction.html#1.5 28 | var keywords = 'after and andalso band begin bnot bor bsl bsr bxor '+ 29 | 'case catch cond div end fun if let not of or orelse '+ 30 | 'query receive rem try when xor'+ 31 | // additional 32 | ' module export import define'; 33 | 34 | this.regexList = [ 35 | { regex: new RegExp("[A-Z][A-Za-z0-9_]+", 'g'), css: 'constants' }, 36 | { regex: new RegExp("\\%.+", 'gm'), css: 'comments' }, 37 | { regex: new RegExp("\\?[A-Za-z0-9_]+", 'g'), css: 'preprocessor' }, 38 | { regex: new RegExp("[a-z0-9_]+:[a-z0-9_]+", 'g'), css: 'functions' }, 39 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, 40 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, 41 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } 42 | ]; 43 | }; 44 | 45 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 46 | Brush.aliases = ['erl', 'erlang']; 47 | 48 | SyntaxHighlighter.brushes.Erland = Brush; 49 | 50 | // CommonJS 51 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 52 | })(); 53 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushGroovy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Contributed by Andres Almiray 25 | // http://jroller.com/aalmiray/entry/nice_source_code_syntax_highlighter 26 | 27 | var keywords = 'as assert break case catch class continue def default do else extends finally ' + 28 | 'if in implements import instanceof interface new package property return switch ' + 29 | 'throw throws try while public protected private static'; 30 | var types = 'void boolean byte char short int long float double'; 31 | var constants = 'null'; 32 | var methods = 'allProperties count get size '+ 33 | 'collect each eachProperty eachPropertyName eachWithIndex find findAll ' + 34 | 'findIndexOf grep inject max min reverseEach sort ' + 35 | 'asImmutable asSynchronized flatten intersect join pop reverse subMap toList ' + 36 | 'padRight padLeft contains eachMatch toCharacter toLong toUrl tokenize ' + 37 | 'eachFile eachFileRecurse eachB yte eachLine readBytes readLine getText ' + 38 | 'splitEachLine withReader append encodeBase64 decodeBase64 filterLine ' + 39 | 'transformChar transformLine withOutputStream withPrintWriter withStream ' + 40 | 'withStreams withWriter withWriterAppend write writeLine '+ 41 | 'dump inspect invokeMethod print println step times upto use waitForOrKill '+ 42 | 'getText'; 43 | 44 | this.regexList = [ 45 | { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments 46 | { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments 47 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings 48 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings 49 | { regex: /""".*"""/g, css: 'string' }, // GStrings 50 | { regex: new RegExp('\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b', 'gi'), css: 'value' }, // numbers 51 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // goovy keyword 52 | { regex: new RegExp(this.getKeywords(types), 'gm'), css: 'color1' }, // goovy/java type 53 | { regex: new RegExp(this.getKeywords(constants), 'gm'), css: 'constants' }, // constants 54 | { regex: new RegExp(this.getKeywords(methods), 'gm'), css: 'functions' } // methods 55 | ]; 56 | 57 | this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); 58 | } 59 | 60 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 61 | Brush.aliases = ['groovy']; 62 | 63 | SyntaxHighlighter.brushes.Groovy = Brush; 64 | 65 | // CommonJS 66 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 67 | })(); 68 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushJScript.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | var keywords = 'break case catch continue ' + 25 | 'default delete do else false ' + 26 | 'for function if in instanceof ' + 27 | 'new null return super switch ' + 28 | 'this throw true try typeof var while with' 29 | ; 30 | 31 | var r = SyntaxHighlighter.regexLib; 32 | 33 | this.regexList = [ 34 | { regex: r.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings 35 | { regex: r.multiLineSingleQuotedString, css: 'string' }, // single quoted strings 36 | { regex: r.singleLineCComments, css: 'comments' }, // one line comments 37 | { regex: r.multiLineCComments, css: 'comments' }, // multiline comments 38 | { regex: /\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion 39 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keywords 40 | ]; 41 | 42 | this.forHtmlScript(r.scriptScriptTags); 43 | }; 44 | 45 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 46 | Brush.aliases = ['js', 'jscript', 'javascript']; 47 | 48 | SyntaxHighlighter.brushes.JScript = Brush; 49 | 50 | // CommonJS 51 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 52 | })(); 53 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushJava.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | var keywords = 'abstract assert boolean break byte case catch char class const ' + 25 | 'continue default do double else enum extends ' + 26 | 'false final finally float for goto if implements import ' + 27 | 'instanceof int interface long native new null ' + 28 | 'package private protected public return ' + 29 | 'short static strictfp super switch synchronized this throw throws true ' + 30 | 'transient try void volatile while'; 31 | 32 | this.regexList = [ 33 | { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments 34 | { regex: /\/\*([^\*][\s\S]*)?\*\//gm, css: 'comments' }, // multiline comments 35 | { regex: /\/\*(?!\*\/)\*[\s\S]*?\*\//gm, css: 'preprocessor' }, // documentation comments 36 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings 37 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings 38 | { regex: /\b([\d]+(\.[\d]+)?|0x[a-f0-9]+)\b/gi, css: 'value' }, // numbers 39 | { regex: /(?!\@interface\b)\@[\$\w]+\b/g, css: 'color1' }, // annotation @anno 40 | { regex: /\@interface\b/g, css: 'color2' }, // @interface keyword 41 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // java keyword 42 | ]; 43 | 44 | this.forHtmlScript({ 45 | left : /(<|<)%[@!=]?/g, 46 | right : /%(>|>)/g 47 | }); 48 | }; 49 | 50 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 51 | Brush.aliases = ['java']; 52 | 53 | SyntaxHighlighter.brushes.Java = Brush; 54 | 55 | // CommonJS 56 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 57 | })(); 58 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushJavaFX.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Contributed by Patrick Webster 25 | // http://patrickwebster.blogspot.com/2009/04/javafx-brush-for-syntaxhighlighter.html 26 | var datatypes = 'Boolean Byte Character Double Duration ' 27 | + 'Float Integer Long Number Short String Void' 28 | ; 29 | 30 | var keywords = 'abstract after and as assert at before bind bound break catch class ' 31 | + 'continue def delete else exclusive extends false finally first for from ' 32 | + 'function if import in indexof init insert instanceof into inverse last ' 33 | + 'lazy mixin mod nativearray new not null on or override package postinit ' 34 | + 'protected public public-init public-read replace return reverse sizeof ' 35 | + 'step super then this throw true try tween typeof var where while with ' 36 | + 'attribute let private readonly static trigger' 37 | ; 38 | 39 | this.regexList = [ 40 | { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, 41 | { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, 42 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, 43 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, 44 | { regex: /(-?\.?)(\b(\d*\.?\d+|\d+\.?\d*)(e[+-]?\d+)?|0x[a-f\d]+)\b\.?/gi, css: 'color2' }, // numbers 45 | { regex: new RegExp(this.getKeywords(datatypes), 'gm'), css: 'variable' }, // datatypes 46 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } 47 | ]; 48 | this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); 49 | }; 50 | 51 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 52 | Brush.aliases = ['jfx', 'javafx']; 53 | 54 | SyntaxHighlighter.brushes.JavaFX = Brush; 55 | 56 | // CommonJS 57 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 58 | })(); 59 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushPerl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Contributed by David Simmons-Duffin and Marty Kube 25 | 26 | var funcs = 27 | 'abs accept alarm atan2 bind binmode chdir chmod chomp chop chown chr ' + 28 | 'chroot close closedir connect cos crypt defined delete each endgrent ' + 29 | 'endhostent endnetent endprotoent endpwent endservent eof exec exists ' + 30 | 'exp fcntl fileno flock fork format formline getc getgrent getgrgid ' + 31 | 'getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr ' + 32 | 'getnetbyname getnetent getpeername getpgrp getppid getpriority ' + 33 | 'getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid ' + 34 | 'getservbyname getservbyport getservent getsockname getsockopt glob ' + 35 | 'gmtime grep hex index int ioctl join keys kill lc lcfirst length link ' + 36 | 'listen localtime lock log lstat map mkdir msgctl msgget msgrcv msgsnd ' + 37 | 'oct open opendir ord pack pipe pop pos print printf prototype push ' + 38 | 'quotemeta rand read readdir readline readlink readpipe recv rename ' + 39 | 'reset reverse rewinddir rindex rmdir scalar seek seekdir select semctl ' + 40 | 'semget semop send setgrent sethostent setnetent setpgrp setpriority ' + 41 | 'setprotoent setpwent setservent setsockopt shift shmctl shmget shmread ' + 42 | 'shmwrite shutdown sin sleep socket socketpair sort splice split sprintf ' + 43 | 'sqrt srand stat study substr symlink syscall sysopen sysread sysseek ' + 44 | 'system syswrite tell telldir time times tr truncate uc ucfirst umask ' + 45 | 'undef unlink unpack unshift utime values vec wait waitpid warn write'; 46 | 47 | var keywords = 48 | 'bless caller continue dbmclose dbmopen die do dump else elsif eval exit ' + 49 | 'for foreach goto if import last local my next no our package redo ref ' + 50 | 'require return sub tie tied unless untie until use wantarray while'; 51 | 52 | this.regexList = [ 53 | { regex: new RegExp('#[^!].*$', 'gm'), css: 'comments' }, 54 | { regex: new RegExp('^\\s*#!.*$', 'gm'), css: 'preprocessor' }, // shebang 55 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, 56 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, 57 | { regex: new RegExp('(\\$|@|%)\\w+', 'g'), css: 'variable' }, 58 | { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, 59 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } 60 | ]; 61 | 62 | this.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags); 63 | } 64 | 65 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 66 | Brush.aliases = ['perl', 'Perl', 'pl']; 67 | 68 | SyntaxHighlighter.brushes.Perl = Brush; 69 | 70 | // CommonJS 71 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 72 | })(); 73 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushPhp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | var funcs = 'abs acos acosh addcslashes addslashes ' + 25 | 'array_change_key_case array_chunk array_combine array_count_values array_diff '+ 26 | 'array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill '+ 27 | 'array_filter array_flip array_intersect array_intersect_assoc array_intersect_key '+ 28 | 'array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map '+ 29 | 'array_merge array_merge_recursive array_multisort array_pad array_pop array_product '+ 30 | 'array_push array_rand array_reduce array_reverse array_search array_shift '+ 31 | 'array_slice array_splice array_sum array_udiff array_udiff_assoc '+ 32 | 'array_udiff_uassoc array_uintersect array_uintersect_assoc '+ 33 | 'array_uintersect_uassoc array_unique array_unshift array_values array_walk '+ 34 | 'array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert '+ 35 | 'basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress '+ 36 | 'bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir '+ 37 | 'checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists '+ 38 | 'closedir closelog copy cos cosh count count_chars date decbin dechex decoct '+ 39 | 'deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log '+ 40 | 'error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded '+ 41 | 'feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents '+ 42 | 'fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype '+ 43 | 'floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf '+ 44 | 'fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname '+ 45 | 'gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt '+ 46 | 'getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext '+ 47 | 'gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set '+ 48 | 'interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double '+ 49 | 'is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long '+ 50 | 'is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault '+ 51 | 'is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br '+ 52 | 'parse_ini_file parse_str parse_url passthru pathinfo print readlink realpath rewind rewinddir rmdir '+ 53 | 'round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split '+ 54 | 'str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes '+ 55 | 'stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk '+ 56 | 'strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime '+ 57 | 'strtoupper strtr strval substr substr_compare'; 58 | 59 | var keywords = 'abstract and array as break case catch cfunction class clone const continue declare default die do ' + 60 | 'else elseif enddeclare endfor endforeach endif endswitch endwhile extends final for foreach ' + 61 | 'function include include_once global goto if implements interface instanceof namespace new ' + 62 | 'old_function or private protected public return require require_once static switch ' + 63 | 'throw try use var while xor '; 64 | 65 | var constants = '__FILE__ __LINE__ __METHOD__ __FUNCTION__ __CLASS__'; 66 | 67 | this.regexList = [ 68 | { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments 69 | { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments 70 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings 71 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings 72 | { regex: /\$\w+/g, css: 'variable' }, // variables 73 | { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, // common functions 74 | { regex: new RegExp(this.getKeywords(constants), 'gmi'), css: 'constants' }, // constants 75 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keyword 76 | ]; 77 | 78 | this.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags); 79 | }; 80 | 81 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 82 | Brush.aliases = ['php']; 83 | 84 | SyntaxHighlighter.brushes.Php = Brush; 85 | 86 | // CommonJS 87 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 88 | })(); 89 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushPlain.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | }; 25 | 26 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 27 | Brush.aliases = ['text', 'plain']; 28 | 29 | SyntaxHighlighter.brushes.Plain = Brush; 30 | 31 | // CommonJS 32 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 33 | })(); 34 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushPowerShell.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Contributes by B.v.Zanten, Getronics 25 | // http://confluence.atlassian.com/display/CONFEXT/New+Code+Macro 26 | 27 | var keywords = 'Add-Content Add-History Add-Member Add-PSSnapin Clear(-Content)? Clear-Item ' + 28 | 'Clear-ItemProperty Clear-Variable Compare-Object ConvertFrom-SecureString Convert-Path ' + 29 | 'ConvertTo-Html ConvertTo-SecureString Copy(-Item)? Copy-ItemProperty Export-Alias ' + 30 | 'Export-Clixml Export-Console Export-Csv ForEach(-Object)? Format-Custom Format-List ' + 31 | 'Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command ' + 32 | 'Get-Content Get-Credential Get-Culture Get-Date Get-EventLog Get-ExecutionPolicy ' + 33 | 'Get-Help Get-History Get-Host Get-Item Get-ItemProperty Get-Location Get-Member ' + 34 | 'Get-PfxCertificate Get-Process Get-PSDrive Get-PSProvider Get-PSSnapin Get-Service ' + 35 | 'Get-TraceSource Get-UICulture Get-Unique Get-Variable Get-WmiObject Group-Object ' + 36 | 'Import-Alias Import-Clixml Import-Csv Invoke-Expression Invoke-History Invoke-Item ' + 37 | 'Join-Path Measure-Command Measure-Object Move(-Item)? Move-ItemProperty New-Alias ' + 38 | 'New-Item New-ItemProperty New-Object New-PSDrive New-Service New-TimeSpan ' + 39 | 'New-Variable Out-Default Out-File Out-Host Out-Null Out-Printer Out-String Pop-Location ' + 40 | 'Push-Location Read-Host Remove-Item Remove-ItemProperty Remove-PSDrive Remove-PSSnapin ' + 41 | 'Remove-Variable Rename-Item Rename-ItemProperty Resolve-Path Restart-Service Resume-Service ' + 42 | 'Select-Object Select-String Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content ' + 43 | 'Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-Location Set-PSDebug ' + 44 | 'Set-Service Set-TraceSource Set(-Variable)? Sort-Object Split-Path Start-Service ' + 45 | 'Start-Sleep Start-Transcript Stop-Process Stop-Service Stop-Transcript Suspend-Service ' + 46 | 'Tee-Object Test-Path Trace-Command Update-FormatData Update-TypeData Where(-Object)? ' + 47 | 'Write-Debug Write-Error Write(-Host)? Write-Output Write-Progress Write-Verbose Write-Warning'; 48 | var alias = 'ac asnp clc cli clp clv cpi cpp cvpa diff epal epcsv fc fl ' + 49 | 'ft fw gal gc gci gcm gdr ghy gi gl gm gp gps group gsv ' + 50 | 'gsnp gu gv gwmi iex ihy ii ipal ipcsv mi mp nal ndr ni nv oh rdr ' + 51 | 'ri rni rnp rp rsnp rv rvpa sal sasv sc select si sl sleep sort sp ' + 52 | 'spps spsv sv tee cat cd cp h history kill lp ls ' + 53 | 'mount mv popd ps pushd pwd r rm rmdir echo cls chdir del dir ' + 54 | 'erase rd ren type % \\?'; 55 | 56 | this.regexList = [ 57 | { regex: /#.*$/gm, css: 'comments' }, // one line comments 58 | { regex: /\$[a-zA-Z0-9]+\b/g, css: 'value' }, // variables $Computer1 59 | { regex: /\-[a-zA-Z]+\b/g, css: 'keyword' }, // Operators -not -and -eq 60 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings 61 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings 62 | { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' }, 63 | { regex: new RegExp(this.getKeywords(alias), 'gmi'), css: 'keyword' } 64 | ]; 65 | }; 66 | 67 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 68 | Brush.aliases = ['powershell', 'ps']; 69 | 70 | SyntaxHighlighter.brushes.PowerShell = Brush; 71 | 72 | // CommonJS 73 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 74 | })(); 75 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushPython.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Contributed by Gheorghe Milas and Ahmad Sherif 25 | 26 | var keywords = 'and assert break class continue def del elif else ' + 27 | 'except exec finally for from global if import in is ' + 28 | 'lambda not or pass print raise return try yield while'; 29 | 30 | var funcs = '__import__ abs all any apply basestring bin bool buffer callable ' + 31 | 'chr classmethod cmp coerce compile complex delattr dict dir ' + 32 | 'divmod enumerate eval execfile file filter float format frozenset ' + 33 | 'getattr globals hasattr hash help hex id input int intern ' + 34 | 'isinstance issubclass iter len list locals long map max min next ' + 35 | 'object oct open ord pow print property range raw_input reduce ' + 36 | 'reload repr reversed round set setattr slice sorted staticmethod ' + 37 | 'str sum super tuple type type unichr unicode vars xrange zip'; 38 | 39 | var special = 'None True False self cls class_'; 40 | 41 | this.regexList = [ 42 | { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' }, 43 | { regex: /^\s*@\w+/gm, css: 'decorator' }, 44 | { regex: /(['\"]{3})([^\1])*?\1/gm, css: 'comments' }, 45 | { regex: /"(?!")(?:\.|\\\"|[^\""\n])*"/gm, css: 'string' }, 46 | { regex: /'(?!')(?:\.|(\\\')|[^\''\n])*'/gm, css: 'string' }, 47 | { regex: /\+|\-|\*|\/|\%|=|==/gm, css: 'keyword' }, 48 | { regex: /\b\d+\.?\w*/g, css: 'value' }, 49 | { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, 50 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, 51 | { regex: new RegExp(this.getKeywords(special), 'gm'), css: 'color1' } 52 | ]; 53 | 54 | this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); 55 | }; 56 | 57 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 58 | Brush.aliases = ['py', 'python']; 59 | 60 | SyntaxHighlighter.brushes.Python = Brush; 61 | 62 | // CommonJS 63 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 64 | })(); 65 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushRuby.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Contributed by Erik Peterson. 25 | 26 | var keywords = 'alias and BEGIN begin break case class def define_method defined do each else elsif ' + 27 | 'END end ensure false for if in module new next nil not or raise redo rescue retry return ' + 28 | 'self super then throw true undef unless until when while yield'; 29 | 30 | var builtins = 'Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload ' + 31 | 'Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol ' + 32 | 'ThreadGroup Thread Time TrueClass'; 33 | 34 | this.regexList = [ 35 | { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' }, // one line comments 36 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings 37 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings 38 | { regex: /\b[A-Z0-9_]+\b/g, css: 'constants' }, // constants 39 | { regex: /:[a-z][A-Za-z0-9_]*/g, css: 'color2' }, // symbols 40 | { regex: /(\$|@@|@)\w+/g, css: 'variable bold' }, // $global, @instance, and @@class variables 41 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords 42 | { regex: new RegExp(this.getKeywords(builtins), 'gm'), css: 'color1' } // builtins 43 | ]; 44 | 45 | this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); 46 | }; 47 | 48 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 49 | Brush.aliases = ['ruby', 'rails', 'ror', 'rb']; 50 | 51 | SyntaxHighlighter.brushes.Ruby = Brush; 52 | 53 | // CommonJS 54 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 55 | })(); 56 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushSass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | function getKeywordsCSS(str) 25 | { 26 | return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b'; 27 | }; 28 | 29 | function getValuesCSS(str) 30 | { 31 | return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b'; 32 | }; 33 | 34 | var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' + 35 | 'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' + 36 | 'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' + 37 | 'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' + 38 | 'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' + 39 | 'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' + 40 | 'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' + 41 | 'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' + 42 | 'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' + 43 | 'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' + 44 | 'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' + 45 | 'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' + 46 | 'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' + 47 | 'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index'; 48 | 49 | var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+ 50 | 'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+ 51 | 'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero digits disc dotted double '+ 52 | 'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+ 53 | 'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+ 54 | 'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+ 55 | 'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+ 56 | 'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+ 57 | 'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+ 58 | 'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+ 59 | 'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+ 60 | 'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+ 61 | 'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+ 62 | 'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow'; 63 | 64 | var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif'; 65 | 66 | var statements = '!important !default'; 67 | var preprocessor = '@import @extend @debug @warn @if @for @while @mixin @include'; 68 | 69 | var r = SyntaxHighlighter.regexLib; 70 | 71 | this.regexList = [ 72 | { regex: r.multiLineCComments, css: 'comments' }, // multiline comments 73 | { regex: r.singleLineCComments, css: 'comments' }, // singleline comments 74 | { regex: r.doubleQuotedString, css: 'string' }, // double quoted strings 75 | { regex: r.singleQuotedString, css: 'string' }, // single quoted strings 76 | { regex: /\#[a-fA-F0-9]{3,6}/g, css: 'value' }, // html colors 77 | { regex: /\b(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)\b/g, css: 'value' }, // sizes 78 | { regex: /\$\w+/g, css: 'variable' }, // variables 79 | { regex: new RegExp(this.getKeywords(statements), 'g'), css: 'color3' }, // statements 80 | { regex: new RegExp(this.getKeywords(preprocessor), 'g'), css: 'preprocessor' }, // preprocessor 81 | { regex: new RegExp(getKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords 82 | { regex: new RegExp(getValuesCSS(values), 'g'), css: 'value' }, // values 83 | { regex: new RegExp(this.getKeywords(fonts), 'g'), css: 'color1' } // fonts 84 | ]; 85 | }; 86 | 87 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 88 | Brush.aliases = ['sass', 'scss']; 89 | 90 | SyntaxHighlighter.brushes.Sass = Brush; 91 | 92 | // CommonJS 93 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 94 | })(); 95 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushScala.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | // Contributed by Yegor Jbanov and David Bernard. 25 | 26 | var keywords = 'val sealed case def true trait implicit forSome import match object null finally super ' + 27 | 'override try lazy for var catch throw type extends class while with new final yield abstract ' + 28 | 'else do if return protected private this package false'; 29 | 30 | var keyops = '[_:=><%#@]+'; 31 | 32 | this.regexList = [ 33 | { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments 34 | { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments 35 | { regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString, css: 'string' }, // multi-line strings 36 | { regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString, css: 'string' }, // double-quoted string 37 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings 38 | { regex: /0x[a-f0-9]+|\d+(\.\d+)?/gi, css: 'value' }, // numbers 39 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords 40 | { regex: new RegExp(keyops, 'gm'), css: 'keyword' } // scala keyword 41 | ]; 42 | } 43 | 44 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 45 | Brush.aliases = ['scala']; 46 | 47 | SyntaxHighlighter.brushes.Scala = Brush; 48 | 49 | // CommonJS 50 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 51 | })(); 52 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushSql.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | var funcs = 'abs avg case cast coalesce convert count current_timestamp ' + 25 | 'current_user day isnull left lower month nullif replace right ' + 26 | 'session_user space substring sum system_user upper user year'; 27 | 28 | var keywords = 'absolute action add after alter as asc at authorization begin bigint ' + 29 | 'binary bit by cascade char character check checkpoint close collate ' + 30 | 'column commit committed connect connection constraint contains continue ' + 31 | 'create cube current current_date current_time cursor database date ' + 32 | 'deallocate dec decimal declare default delete desc distinct double drop ' + 33 | 'dynamic else end end-exec escape except exec execute false fetch first ' + 34 | 'float for force foreign forward free from full function global goto grant ' + 35 | 'group grouping having hour ignore index inner insensitive insert instead ' + 36 | 'int integer intersect into is isolation key last level load local max min ' + 37 | 'minute modify move name national nchar next no numeric of off on only ' + 38 | 'open option order out output partial password precision prepare primary ' + 39 | 'prior privileges procedure public read real references relative repeatable ' + 40 | 'restrict return returns revoke rollback rollup rows rule schema scroll ' + 41 | 'second section select sequence serializable set size smallint static ' + 42 | 'statistics table temp temporary then time timestamp to top transaction ' + 43 | 'translation trigger true truncate uncommitted union unique update values ' + 44 | 'varchar varying view when where with work'; 45 | 46 | var operators = 'all and any between cross in join like not null or outer some'; 47 | 48 | this.regexList = [ 49 | { regex: /--(.*)$/gm, css: 'comments' }, // one line and multiline comments 50 | { regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings 51 | { regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString, css: 'string' }, // single quoted strings 52 | { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'color2' }, // functions 53 | { regex: new RegExp(this.getKeywords(operators), 'gmi'), css: 'color1' }, // operators and such 54 | { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword 55 | ]; 56 | }; 57 | 58 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 59 | Brush.aliases = ['sql']; 60 | 61 | SyntaxHighlighter.brushes.Sql = Brush; 62 | 63 | // CommonJS 64 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 65 | })(); 66 | 67 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushVb.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | var keywords = 'AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto ' + 25 | 'Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate ' + 26 | 'CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType ' + 27 | 'Date Decimal Declare Default Delegate Dim DirectCast Do Double Each ' + 28 | 'Else ElseIf End Enum Erase Error Event Exit False Finally For Friend ' + 29 | 'Function Get GetType GoSub GoTo Handles If Implements Imports In ' + 30 | 'Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module ' + 31 | 'MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing ' + 32 | 'NotInheritable NotOverridable Object On Option Optional Or OrElse ' + 33 | 'Overloads Overridable Overrides ParamArray Preserve Private Property ' + 34 | 'Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume ' + 35 | 'Return Select Set Shadows Shared Short Single Static Step Stop String ' + 36 | 'Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until ' + 37 | 'Variant When While With WithEvents WriteOnly Xor'; 38 | 39 | this.regexList = [ 40 | { regex: /'.*$/gm, css: 'comments' }, // one line comments 41 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings 42 | { regex: /^\s*#.*$/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion 43 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // vb keyword 44 | ]; 45 | 46 | this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); 47 | }; 48 | 49 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 50 | Brush.aliases = ['vb', 'vbnet']; 51 | 52 | SyntaxHighlighter.brushes.Vb = Brush; 53 | 54 | // CommonJS 55 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 56 | })(); 57 | -------------------------------------------------------------------------------- /static/syntax_brushes/shBrushXml.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 21 | 22 | function Brush() 23 | { 24 | function process(match, regexInfo) 25 | { 26 | var constructor = SyntaxHighlighter.Match, 27 | code = match[0], 28 | tag = new XRegExp('(<|<)[\\s\\/\\?]*(?[:\\w-\\.]+)', 'xg').exec(code), 29 | result = [] 30 | ; 31 | 32 | if (match.attributes != null) 33 | { 34 | var attributes, 35 | regex = new XRegExp('(? [\\w:\\-\\.]+)' + 36 | '\\s*=\\s*' + 37 | '(? ".*?"|\'.*?\'|\\w+)', 38 | 'xg'); 39 | 40 | while ((attributes = regex.exec(code)) != null) 41 | { 42 | result.push(new constructor(attributes.name, match.index + attributes.index, 'color1')); 43 | result.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string')); 44 | } 45 | } 46 | 47 | if (tag != null) 48 | result.push( 49 | new constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword') 50 | ); 51 | 52 | return result; 53 | } 54 | 55 | this.regexList = [ 56 | { regex: new XRegExp('(\\<|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\>|>)', 'gm'), css: 'color2' }, // 57 | { regex: SyntaxHighlighter.regexLib.xmlComments, css: 'comments' }, // 58 | { regex: new XRegExp('(<|<)[\\s\\/\\?]*(\\w+)(?.*?)[\\s\\/\\?]*(>|>)', 'sg'), func: process } 59 | ]; 60 | }; 61 | 62 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 63 | Brush.aliases = ['xml', 'xhtml', 'xslt', 'html']; 64 | 65 | SyntaxHighlighter.brushes.Xml = Brush; 66 | 67 | // CommonJS 68 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 69 | })(); 70 | -------------------------------------------------------------------------------- /static/syntax_brushes/shLegacy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('3 u={8:{}};u.8={A:4(c,k,l,m,n,o){4 d(a,b){2 a!=1?a:b}4 f(a){2 a!=1?a.E():1}c=c.I(":");3 g=c[0],e={};t={"r":K};M=1;5=8.5;9(3 j R c)e[c[j]]="r";k=f(d(k,5.C));l=f(d(l,5.D));m=f(d(m,5.s));o=f(d(o,5.Q));n=f(d(n,5["x-y"]));2{P:g,C:d(t[e.O],k),D:d(t[e.N],l),s:d({"r":r}[e.s],m),"x-y":d(4(a,b){9(3 h=T S("^"+b+"\\\\[(?\\\\w+)\\\\]$","U"),i=1,p=0;p=e.computed&&(e={value:f,computed:g})});return e.value};c.min=function(a,b,d){if(!b&&c.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};k(a,function(f,g,h){g=b?b.call(d,f,g,h):f;gh?1:0}),"value")};c.sortedIndex=function(a,b,d){d=d||c.identity;for(var e=0,f=a.length;e>1;d(a[g])=0})})};c.zip=function(){for(var a=i.call(arguments),b=c.max(c.pluck(a,"length")),d=Array(b),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};c.keys=F||function(a){if(c.isArray(a))return c.range(0,a.length);var b=[],d;for(d in a)if(q.call(a,d))b[b.length]=d;return b}; 19 | c.values=function(a){return c.map(a,c.identity)};c.functions=c.methods=function(a){return c.filter(c.keys(a),function(b){return c.isFunction(a[b])}).sort()};c.extend=function(a){k(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};c.clone=function(a){return c.isArray(a)?a.slice():c.extend({},a)};c.tap=function(a,b){b(a);return a};c.isEqual=function(a,b){if(a===b)return true;var d=typeof a;if(d!=typeof b)return false;if(a==b)return true;if(!a&&b||a&&!b)return false;if(a.isEqual)return a.isEqual(b); 20 | if(c.isDate(a)&&c.isDate(b))return a.getTime()===b.getTime();if(c.isNaN(a)&&c.isNaN(b))return false;if(c.isRegExp(a)&&c.isRegExp(b))return a.source===b.source&&a.global===b.global&&a.ignoreCase===b.ignoreCase&&a.multiline===b.multiline;if(d!=="object")return false;if(a.length&&a.length!==b.length)return false;d=c.keys(a);var e=c.keys(b);if(d.length!=e.length)return false;for(var f in a)if(!(f in b)||!c.isEqual(a[f],b[f]))return false;return true};c.isEmpty=function(a){if(c.isArray(a)||c.isString(a))return a.length=== 21 | 0;for(var b in a)if(q.call(a,b))return false;return true};c.isElement=function(a){return!!(a&&a.nodeType==1)};c.isArray=n||function(a){return!!(a&&a.concat&&a.unshift&&!a.callee)};c.isArguments=function(a){return!!(a&&a.callee)};c.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};c.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};c.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};c.isNaN=function(a){return E.call(a)==="[object Number]"&&isNaN(a)}; 22 | c.isBoolean=function(a){return a===true||a===false};c.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};c.isRegExp=function(a){return!!(a&&a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};c.isNull=function(a){return a===null};c.isUndefined=function(a){return a===void 0};c.noConflict=function(){p._=C;return this};c.identity=function(a){return a};c.times=function(a,b,d){for(var e=0;e/g,interpolate:/<%=([\s\S]+?)%>/g};c.template=function(a,b){var d=c.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,function(e,f){return"',"+f.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(e,f){return"');"+f.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g, 24 | "\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return b?d(b):d};var l=function(a){this._wrapped=a};c.prototype=l.prototype;var r=function(a,b){return b?c(a).chain():a},H=function(a,b){l.prototype[a]=function(){var d=i.call(arguments);D.call(d,this._wrapped);return r(b.apply(c,d),this._chain)}};c.mixin(c);k(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var b=j[a];l.prototype[a]=function(){b.apply(this._wrapped,arguments); 25 | return r(this._wrapped,this._chain)}});k(["concat","join","slice"],function(a){var b=j[a];l.prototype[a]=function(){return r(b.apply(this._wrapped,arguments),this._chain)}});l.prototype.chain=function(){this._chain=true;return this};l.prototype.value=function(){return this._wrapped}})(); 26 | -------------------------------------------------------------------------------- /static/xregexp.js: -------------------------------------------------------------------------------- 1 | //XRegExp 1.5.0 MIT License 2 | var XRegExp;if(XRegExp){throw Error("can't load XRegExp twice in the same frame")}(function(){XRegExp=function(w,r){var q=[],u=XRegExp.OUTSIDE_CLASS,x=0,p,s,v,t,y;if(XRegExp.isRegExp(w)){if(r!==undefined){throw TypeError("can't supply flags when constructing one RegExp from another")}return j(w)}if(g){throw Error("can't call the XRegExp constructor within token definition functions")}r=r||"";p={hasNamedCapture:false,captureNames:[],hasFlag:function(z){return r.indexOf(z)>-1},setFlag:function(z){r+=z}};while(x1&&l(r,"")>-1){p=RegExp(this.source,m.replace.call(d(this),"g",""));m.replace.call(t.slice(r.index),p,function(){for(var u=1;ur.index)){this.lastIndex--}}return r};if(!e){RegExp.prototype.test=function(q){var p=m.exec.call(this,q);if(p&&this.global&&!p[0].length&&(this.lastIndex>p.index)){this.lastIndex--}return !!p}}String.prototype.match=function(q){if(!XRegExp.isRegExp(q)){q=RegExp(q)}if(q.global){var p=m.match.apply(this,arguments);q.lastIndex=0;return p}return q.exec(this)};String.prototype.replace=function(r,s){var t=XRegExp.isRegExp(r),q,p,u;if(t&&typeof s.valueOf()==="string"&&s.indexOf("${")===-1&&f){return m.replace.apply(this,arguments)}if(!t){r=r+""}else{if(r._xregexp){q=r._xregexp.captureNames}}if(typeof s==="function"){p=m.replace.call(this,r,function(){if(q){arguments[0]=new String(arguments[0]);for(var v=0;vv.length-3){y=String.prototype.slice.call(w,-1)+y;w=Math.floor(w/10)}return(w?v[w]||"":"$")+y}}else{var z=+A;if(z<=v.length-3){return v[z]}z=q?l(q,A):-1;return z>-1?v[z+1]:x}})})}if(t&&r.global){r.lastIndex=0}return p};String.prototype.split=function(u,p){if(!XRegExp.isRegExp(u)){return m.split.apply(this,arguments)}var w=this+"",r=[],v=0,t,q;if(p===undefined||+p<0){p=Infinity}else{p=Math.floor(+p);if(!p){return[]}}u=XRegExp.copyAsGlobal(u);while(t=u.exec(w)){if(u.lastIndex>v){r.push(w.slice(v,t.index));if(t.length>1&&t.index=p){break}}if(u.lastIndex===t.index){u.lastIndex++}}if(v===w.length){if(!m.test.call(u,"")||q){r.push("")}}else{r.push(w.slice(v))}return r.length>p?r.slice(0,p):r};function j(r,q){if(!XRegExp.isRegExp(r)){throw TypeError("type RegExp expected")}var p=r._xregexp;r=XRegExp(r.source,d(r)+(q||""));if(p){r._xregexp={source:p.source,captureNames:p.captureNames?p.captureNames.slice(0):null}}return r}function d(p){return(p.global?"g":"")+(p.ignoreCase?"i":"")+(p.multiline?"m":"")+(p.extended?"x":"")+(p.sticky?"y":"")}function o(v,u,w,p){var r=k.length,y,s,x;g=true;try{while(r--){x=k[r];if((w&x.scope)&&(!x.trigger||x.trigger.call(p))){x.pattern.lastIndex=u;s=x.pattern.exec(v);if(s&&s.index===u){y={output:x.handler.call(p,s,w),match:s};break}}}}catch(q){throw q}finally{g=false}return y}function l(s,q,r){if(Array.prototype.indexOf){return s.indexOf(q,r)}for(var p=r||0;p/,function(p){this.captureNames.push(p[1]);this.hasNamedCapture=true;return"("});XRegExp.addToken(/\\k<([\w$]+)>/,function(q){var p=l(this.captureNames,q[1]);return p>-1?"\\"+(p+1)+(isNaN(q.input.charAt(q.index+q[0].length))?"":"(?:)"):q[0]});XRegExp.addToken(/\[\^?]/,function(p){return p[0]==="[]"?"\\b\\B":"[\\s\\S]"});XRegExp.addToken(/^\(\?([imsx]+)\)/,function(p){this.setFlag(p[1]);return""});XRegExp.addToken(/(?:\s+|#.*)+/,function(p){return m.test.call(n,p.input.slice(p.index+p[0].length))?"":"(?:)"},XRegExp.OUTSIDE_CLASS,function(){return this.hasFlag("x")});XRegExp.addToken(/\./,function(){return"[\\s\\S]"},XRegExp.OUTSIDE_CLASS,function(){return this.hasFlag("s")})})(); 3 | if (typeof(window) == 'undefined') { exports.XRegExp = XRegExp; }; 4 | -------------------------------------------------------------------------------- /templates/admin/messages.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | p "Send an email" 3 | 4 | form action: "/admin/messages", method: "POST", -> 5 | input id: "from", type: "text", name: "from", 'data-default-text': "from", value: "jae@ycatalyst.com" 6 | br() 7 | input id: "to", type: "text", name: "to", 'data-default-text': "to" 8 | br() 9 | input id: "subject", type: "text", name: "subject", 'data-default-text': "subject" 10 | br() 11 | textarea id: "body", name: "body", cols: 60, rows: 20, 'data-default-text': "body" 12 | br() 13 | input type: "submit", value: "send" 14 | 15 | exports.coffeescript = -> 16 | $(document).ready -> 17 | $('[data-default-text]').set_default_text() 18 | $('#body').make_autoresizable() 19 | -------------------------------------------------------------------------------- /templates/applicants.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | if @applicants and @applicants.length > 0 3 | p "Recent applicants:" 4 | else 5 | p "No new applicants" 6 | 7 | ol class: "applicants", -> 8 | @applicants.forEach (applicant) -> 9 | li -> 10 | div class: 'applicant', 'data-application-id': applicant._id, -> 11 | span class: 'first_name', -> applicant.first_name 12 | text " " 13 | span class: 'last_name', -> applicant.last_name 14 | if applicant.created_at 15 | span class: 'applied_at', -> " applied #{applicant.created_at.time_ago()}" 16 | br() 17 | if applicant.website 18 | a href: applicant.website, class: "website", -> applicant.website 19 | br() 20 | div class: "comment", -> 21 | text Markz::markup applicant.comment 22 | 23 | # membership voting buttons 24 | text "vote: " 25 | a href: "#", title: applicant.accepted_by.join(' '), class: "vote_accept #{'chosen' if applicant.accepted_by.indexOf(@current_user.username) != -1}", -> 26 | text "accept " 27 | span class: "vote_accept_count", -> "#{applicant.accepted_by.length}" 28 | text " | " 29 | a href: "#", title: applicant.denied_by.join(' '), class: "vote_deny #{'chosen' if applicant.denied_by.indexOf(@current_user.username) != -1}", -> 30 | text "deny " 31 | span class: "vote_deny_count", -> "#{applicant.denied_by.length}" 32 | if @current_user.is_admin 33 | text " | " 34 | a href: "#", class: "invite", -> 35 | text "invite" 36 | text " | " 37 | a href: "#", class: "delete", -> 38 | text "delete" 39 | 40 | 41 | exports.sass = """ 42 | body 43 | .timeago 44 | :font-size 0.8em 45 | a.website 46 | :color #66F 47 | .first_name, .last_name 48 | :color #333 49 | .applied_at 50 | :font-size 0.8em 51 | .comment 52 | :padding 5px 53 | ol>li>div.applicant 54 | :margin-bottom 20px 55 | .vote_accept, .vote_accept:visited 56 | :color green 57 | .vote_deny, .vote_deny:visited 58 | :color red 59 | .chosen 60 | :font-weight bold 61 | """ 62 | 63 | exports.coffeescript = -> 64 | $(document).ready -> 65 | # vote up or down. 66 | # vote_type: 'accept' or 'deny' 67 | vote = (element, vote_type, cb) -> 68 | $.ajax 69 | cache: false 70 | type: "POST" 71 | url: "/applicants/#{element.attr('data-application-id')}/vote" 72 | data: {vote: vote_type} 73 | dataType: "json" 74 | error: -> 75 | alert "Error, please refresh and try again later." 76 | success: (data) -> 77 | # NOTE: requires coffeescript version 1.0.1 78 | switch vote_type 79 | when 'accept' 80 | if not element.find('.vote_accept').hasClass('chosen') 81 | element.find('.vote_accept').addClass('chosen') 82 | element.find('.vote_accept_count').increment() 83 | if element.find('.vote_deny').hasClass('chosen') 84 | element.find('.vote_deny').removeClass('chosen') 85 | element.find('.vote_deny_count').decrement() 86 | when 'deny' 87 | if not element.find('.vote_deny').hasClass('chosen') 88 | element.find('.vote_deny').addClass('chosen') 89 | element.find('.vote_deny_count').increment() 90 | if element.find('.vote_accept').hasClass('chosen') 91 | element.find('.vote_accept').removeClass('chosen') 92 | element.find('.vote_accept_count').decrement() 93 | cb() 94 | # bind events 95 | $('.vote_accept').live 'click', (event) -> 96 | vote $(this).parents('.applicant:eq(0)'), 'accept' 97 | return false 98 | $('.vote_deny').live 'click', (event) -> 99 | vote $(this).parents('.applicant:eq(0)'), 'deny' 100 | return false 101 | $('.invite').live 'click', (event) -> 102 | if confirm 'invite?' 103 | vote $(this).parents('.applicant:eq(0)'), 'invite', -> 104 | window.location.reload(true) 105 | $('.delete').live 'click', (event) -> 106 | if confirm 'delete?' 107 | vote $(this).parents('.applicant:eq(0)'), 'delete', -> 108 | window.location.reload(true) 109 | -------------------------------------------------------------------------------- /templates/apply.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | p "YCatalyst Application" 3 | p "Membership requires screening by existing members. Please fill out the form below." 4 | 5 | form action: "/apply", method: "POST", -> 6 | if typeof application != 'undefined' 7 | input type: "hidden", name: "application_id", value: @application._id 8 | @referral = {} 9 | else 10 | @application = {} 11 | input type: "hidden", name: "referral_id", value: @referral._id 12 | input id: "first_name", type: "text", name: "first_name", 'data-default-text': "first name", value: @referral.first_name or @application.first_name or '' 13 | br() 14 | input id: "last_name", type: "text", name: "last_name", 'data-default-text': "last name", value: @referral.last_name or @application.last_name or '' 15 | br() 16 | input id: "email", type: "text", name: "email", 'data-default-text': "email", value: @referral.email or @application.email or '' 17 | br() 18 | input id: "website", type: "text", name: "website", 'data-default-text': "website" 19 | br() 20 | p "Please explain why you should be granted membership in the field below." 21 | textarea id: "comment", name: "comment", cols: 60, rows: 20, -> @application.comment or '' 22 | br() 23 | input type: "submit", value: "apply" 24 | 25 | exports.sass = """ 26 | #first_name, #last_name, #email 27 | :width 200px 28 | """ 29 | 30 | exports.coffeescript = -> 31 | $(document).ready -> 32 | $('input[data-default-text]').set_default_text() 33 | $('#comment').make_autoresizable() 34 | -------------------------------------------------------------------------------- /templates/bookmarklet.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | p -> 3 | text "Drag the link below to your bookmarks bar." 4 | br() 5 | br() 6 | a id: "bookmarklet", href: "javascript: window.location=%22http://ycatalyst.com/submit?url=%22+encodeURIComponent(document.location)+%22&title=%22+encodeURIComponent(document.title)", -> "YCat Submit" 7 | 8 | exports.sass = """ 9 | #bookmarklet 10 | :font-size 1.3em 11 | """ 12 | -------------------------------------------------------------------------------- /templates/inbox.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | ol class: 'records light_bullets', -> 3 | @records.forEach (record) -> 4 | li -> 5 | record.render "default", current_user: @current_user, is_root: true 6 | 7 | exports.sass = """ 8 | body .record .contents 9 | :margin 2px 0px 10 | """ 11 | -------------------------------------------------------------------------------- /templates/index.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | ol class: 'records light_bullets', -> 3 | @records.forEach (record) -> 4 | li -> 5 | record.render "headline", current_user: @current_user 6 | 7 | exports.sass = """ 8 | body 9 | .record 10 | :margin 0px 0px 11 | .item_info 12 | :position relative 13 | :top -4px 14 | :font-size 7pt 15 | """ 16 | 17 | exports.coffeescript = -> 18 | App.start_longpolling() 19 | -------------------------------------------------------------------------------- /templates/layout.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | doctype 5 3 | html -> 4 | head -> 5 | title @title 6 | #script type: "text/javascript", src: "https://www.google.com/jsapi?key=ABQIAAAAV88HHyf8NBcAL3aio53OixSEBwhbzDd0F998UkbSll3boCkrihTFj2uO3yETr_J5z25r2aIc4YCVpQ" 7 | #script type: "text/javascript", src: "https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" 8 | for file in ["jquery-1.4.2.min.js", "underscore.js", "client.js", "coffeekup.js", "markz.js", "record.js"] 9 | script type: "text/javascript", src: static_file(file) 10 | link type: "text/css", rel: "stylesheet", href: static_file("main.css") 11 | 12 | body -> 13 | div id: "headerbar", -> 14 | if typeof @headerbar_text != "undefined" 15 | span class: "logo", -> @headerbar_text 16 | else 17 | a class: "logo", href: "/", -> 18 | img src: "/static/logo.png" 19 | span class: "links", -> 20 | a href: "/submit", -> "submit" 21 | text " | " 22 | a href: "/submit?type=poll", -> "poll" 23 | if @current_user 24 | text " | " 25 | a href: "/inbox", -> "inbox" 26 | div style: "float: right", -> 27 | if @current_user 28 | a href: "/refer", -> "refer a friend" 29 | text " | " 30 | a href: "/user/#{@current_user.username}", class: "username", -> @current_user.username 31 | text " | " 32 | a href: "/logout", class: "logout", -> "logout" 33 | else 34 | a href: "/apply", -> "apply" 35 | text " | " 36 | span class: "username", -> "anonymous" 37 | text " | " 38 | a href: "/login", class: "login", -> "login" 39 | 40 | div id: "body_contents", -> 41 | text render(@body_template, @body_context) 42 | 43 | if @current_user 44 | div id: 'current_user', style: "display: none", 'data-id': @current_user._id, 'data-username': @current_user.username 45 | -------------------------------------------------------------------------------- /templates/login.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | if typeof message != "undefined" 3 | p message 4 | else 5 | p "Login here" 6 | 7 | form action: "/login", method: "POST", -> 8 | input id: "username", type: "text", name: "username", 'data-default-text': "username" 9 | br() 10 | input id: "password", type: "password", name: "password", 'data-default-text': "****" 11 | label " password" 12 | br() 13 | input type: "submit", value: "login" 14 | 15 | p -> 16 | text "New user?" 17 | br() 18 | text "Please register if you have an invite code. We're in private alpha!" 19 | 20 | form action: "/register", method: "POST", -> 21 | input id: "username", type: "text", name: "username", 'data-default-text': "desired username" 22 | br() 23 | input id: "password", type: "password", name: "password", 'data-default-text': "****" 24 | label " password" 25 | br() 26 | input id: "password2", type: "password", name: "password2", 'data-default-text': "****" 27 | label " password repeat" 28 | br() 29 | input id: "email", type: "text", name: "email", 'data-default-text': "email", value: @email or '' 30 | br() 31 | input id: "invite", type: "text", name: "invite", 'data-default-text': "invite code", value: @invite_code or '' 32 | br() 33 | input type: "submit", value: "register" 34 | 35 | p -> 36 | text "Forgot your password? " 37 | a href: "/password_reset", -> 38 | "Reset it!" 39 | 40 | exports.sass = """ 41 | #username, #password, #password2, #email, #invite 42 | :width 200px 43 | """ 44 | 45 | exports.coffeescript = -> 46 | $(document).ready -> 47 | $('input[data-default-text]').set_default_text() 48 | -------------------------------------------------------------------------------- /templates/message.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | p @message 3 | -------------------------------------------------------------------------------- /templates/password_reset.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | if typeof @user == 'undefined' 3 | p "Enter your email address and we'll send you a password reset link." 4 | 5 | form action: "/password_reset", method: 'POST', -> 6 | table -> 7 | tr -> 8 | td -> 9 | label "email" 10 | td -> 11 | input name: "email" 12 | tr -> 13 | td colspan: 2, -> 14 | input type: "submit", value: "reset" 15 | else 16 | p "Enter your new desired password" 17 | 18 | form action: "/password_reset", method: "POST", -> 19 | input type: "hidden", name: "username", value: user.username 20 | input type: "hidden", name: "password_reset_nonce", value: user.password_reset_nonce 21 | table -> 22 | tr -> 23 | td -> 24 | label "password" 25 | td -> 26 | input name: "password", type: "password" 27 | tr -> 28 | td -> 29 | label "password repeat" 30 | td -> 31 | input name: "password2", type: "password" 32 | tr -> 33 | td colspan: 2, -> 34 | input type: "submit", value: "reset" 35 | -------------------------------------------------------------------------------- /templates/record.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | text @root.render "default", current_user: @current_user, is_root: true, heading_title: true 3 | 4 | # root, or is_root, means that the item is at root level in the DOM. 5 | # when you visit a record using the 'link' URL, it becomes 'root'. 6 | exports.sass = """ 7 | .record[data-root="true"] 8 | &>.contents 9 | :margin 10px 0px 10 | &>.item_info 11 | :font-size 7pt 12 | """ 13 | 14 | exports.coffeescript = -> 15 | App.start_longpolling() 16 | -------------------------------------------------------------------------------- /templates/refer.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | p -> 3 | text """ 4 | Use this form to refer somebody you know into the network. 5 | The referred person still needs to fill out an application. 6 | """ 7 | br() 8 | text " You can view and vote on applicants " 9 | a href: "/applicants", -> "here" 10 | 11 | form action: "/refer", method: "POST", -> 12 | input id: "first_name", type: "text", name: "first_name" 13 | br() 14 | input id: "last_name", type: "text", name: "last_name" 15 | br() 16 | input id: "email", type: "text", name: "email" 17 | br() 18 | input type: "submit", value: "submit" 19 | 20 | exports.sass = """ 21 | #first_name, #last_name, #email 22 | :width 200px 23 | """ 24 | 25 | exports.coffeescript = -> 26 | $(document).ready -> 27 | $('#first_name').set_default_text 'first name' 28 | $('#last_name').set_default_text 'last name' 29 | $('#email').set_default_text 'email' 30 | -------------------------------------------------------------------------------- /templates/register.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | if @invite_code 3 | p "Please register here." 4 | else 5 | p "Please register here if you have an invite code." 6 | 7 | form action: "/register", method: "POST", -> 8 | input id: "username", type: "text", name: "username", 'data-default-text': "desired username" 9 | br() 10 | input id: "password", type: "password", name: "password", 'data-default-text': "****" 11 | label " password" 12 | br() 13 | input id: "password2", type: "password", name: "password2", 'data-default-text': "****" 14 | label " password repeat" 15 | br() 16 | input id: "email", type: "text", name: "email", 'data-default-text': "email", value: @email or '' 17 | br() 18 | input id: "invite", type: "text", name: "invite", 'data-default-text': "invite code", value: @invite_code or '' 19 | br() 20 | input type: "submit", value: "register" 21 | 22 | exports.sass = """ 23 | #username, #password, #password2, #email, #invite 24 | :width 200px 25 | """ 26 | 27 | exports.coffeescript = -> 28 | $(document).ready -> 29 | $('input[data-default-text]').set_default_text() 30 | -------------------------------------------------------------------------------- /templates/reply.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | text @parent.render "default", is_root: true, current_user: @current_user 3 | 4 | form action: @parent.comment_url(), method: "POST", -> 5 | textarea name: "comment" 6 | br() 7 | input type: "submit", value: "add comment" 8 | 9 | exports.sass = """ 10 | .record 11 | :margin-bottom 10px 12 | :padding-left 10px 13 | """ 14 | -------------------------------------------------------------------------------- /templates/submit.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | if @type == 'link' 3 | form action: "/submit", method: "POST", -> 4 | table -> 5 | tr -> 6 | th -> 7 | span "title" 8 | td -> 9 | input type: "text", name: "title", value: @link_title or '' 10 | td -> 11 | i style: "color: gray", -> "required" 12 | tr -> 13 | td colspan: 3, -> 14 | br() 15 | tr -> 16 | th -> 17 | span "url" 18 | td -> 19 | input type: "text", name: "url", value: @link_url or '' 20 | tr -> 21 | th() 22 | td -> 23 | span style: "font-weight: bold; color: gray", -> "and/or" 24 | tr -> 25 | th valign: "top", -> 26 | span "text" 27 | td -> 28 | textarea name: "text" 29 | tr -> 30 | th() 31 | td -> 32 | input type: "submit", value: "submit" 33 | else if @type == 'poll' 34 | form action: "/submit", method: "POST", -> 35 | input type: "hidden", name: "type", value: "poll", -> 36 | table -> 37 | tr -> 38 | th -> 39 | span "title" 40 | td -> 41 | input type: "text", name: "title", value: "Poll: ", -> 42 | td -> 43 | i style: "color: gray", -> "required" 44 | tr -> 45 | th valign: "top", -> 46 | span "text" 47 | td -> 48 | textarea name: "text" 49 | tr -> 50 | th() 51 | td -> 52 | span "Use blank lines to seperate choices" 53 | tr -> 54 | th valign: "top", -> 55 | span "choices" 56 | td -> 57 | textarea name: "choices" 58 | tr -> 59 | th() 60 | td -> 61 | input type: "submit", value: "submit" 62 | 63 | p -> 64 | text "Or, submit via " 65 | a href: "/bookmarklet", -> "bookmarklet" 66 | 67 | exports.coffeescript = -> 68 | $(document).ready -> 69 | $('textarea').make_autoresizable() 70 | -------------------------------------------------------------------------------- /templates/user.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | table -> 3 | tr -> 4 | td -> 5 | label "user" 6 | td -> 7 | text @user.username 8 | tr -> 9 | td -> 10 | label "joined" 11 | td -> 12 | text @user.created_at.time_ago() 13 | tr -> 14 | td valign: "top", -> 15 | label "bio" 16 | td -> 17 | if @is_self 18 | # looking at your own bio 19 | form action: "/user/"+@user.username, method: "POST", -> 20 | textarea id: "bio", name: "bio", -> @user.bio or '' 21 | br() 22 | input type: "submit", value: "update" 23 | else 24 | # looking at someone else's bio 25 | if @user.bio 26 | text Markz::markup @user.bio 27 | else 28 | i "no bio" 29 | 30 | exports.coffeescript = -> 31 | $(document).ready -> 32 | $('#bio').make_autoresizable() 33 | -------------------------------------------------------------------------------- /templates/users.coffee: -------------------------------------------------------------------------------- 1 | exports.template = -> 2 | ol class: "users", -> 3 | @users.forEach (user) -> 4 | li -> 5 | div class: "user", -> 6 | a href: '/user/'+user.username, class: 'username', -> user.username 7 | text " " 8 | span class: 'timeago', -> "joined #{user.created_at.time_ago()}" 9 | 10 | exports.sass = """ 11 | .timeago 12 | :font-size 0.8em 13 | """ 14 | -------------------------------------------------------------------------------- /utils.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # YCatalyst 3 | # Copyright(c) 2011 Jae Kwon (jae@ycatalyst.com) 4 | # MIT Licensed 5 | ### 6 | 7 | require.paths.unshift 'vendor/www-forms' 8 | qs = require 'querystring' 9 | url = require 'url' 10 | www_forms = require 'www-forms' 11 | http = require 'http' 12 | fs = require 'fs' 13 | XRegExp = require('./static/xregexp').XRegExp 14 | 15 | exports.ipRE = (() -> 16 | octet = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])' 17 | ip = '(?:' + octet + '\\.){3}' + octet 18 | quad = '(?:\\[' + ip + '\\])|(?:' + ip + ')' 19 | ipRE = new RegExp( '^(' + quad + ')$' ) 20 | return ipRE 21 | )() 22 | 23 | exports.dir = (object) -> 24 | methods = [] 25 | for z in object 26 | if (typeof(z) != 'number') 27 | methods.push(z) 28 | return methods.join(', ') 29 | 30 | SERVER_LOG = fs.createWriteStream('./log/server.log', flags: 'a', encoding: 'utf8') 31 | 32 | # get current user 33 | # sorry, node doesn't actually have a ServerRequest class?? TODO fix 34 | Object.defineProperty(http.IncomingMessage.prototype, 'current_user', { 35 | get: () -> 36 | if not @_current_user? 37 | user_c = this.getSecureCookie('user') 38 | if user_c? and user_c.length > 0 39 | @_current_user = JSON.parse(user_c) 40 | return @_current_user 41 | }) 42 | 43 | # set current user 44 | Object.defineProperty(http.ServerResponse.prototype, 'current_user', { 45 | set: (user_object) -> 46 | @_current_user = user_object 47 | this.setSecureCookie 'user', JSON.stringify(user_object) 48 | }) 49 | 50 | # respond with JSON 51 | http.ServerResponse.prototype.simpleJSON = (code, obj) -> 52 | body = new Buffer(JSON.stringify(obj)) 53 | this.writeHead(code, { "Content-Type": "text/json", "Content-Length": body.length }) 54 | this.end(body) 55 | 56 | # redirect 57 | http.ServerResponse.prototype.redirect = (url) -> 58 | this.writeHead(302, Location: url) 59 | this.end() 60 | 61 | # emit an event so we can log w/ req below in Rowt 62 | _o_writeHead = http.ServerResponse.prototype.writeHead 63 | http.ServerResponse.prototype.writeHead = (statusCode) -> 64 | this.emit('writeHead', statusCode) 65 | _o_writeHead.apply(this, arguments) 66 | 67 | # ROWTER 68 | # Sets some sensible defaults, 69 | # and also sets req.path_data / req.query_data / req.post_data 70 | # routes: an array of ['/route', fn(req, res)] pairs 71 | exports.Rowter = (routes) -> 72 | # convert [route, fn] to [xregex, fn] 73 | # or, [options, route, fn] to [xregex, fn, options] 74 | parsed = [] 75 | for route_fn in routes 76 | if route_fn.length > 2 77 | [options, route, fn] = route_fn 78 | else 79 | [route, fn] = route_fn 80 | options = undefined 81 | xregex = new XRegExp("^"+route.replace(/:([^\/]+)/g, "(?<$1>[^\/]+)")+"$") 82 | parsed.push([xregex, fn, options]) 83 | 84 | # create a giant function that takes a (req, res) pair and finds the right fn to call. 85 | # we need a giant function for each server because that's how node.js works. 86 | giant_function = (req, res) -> 87 | # find matching route 88 | for [xregex, fn, options] in parsed 89 | matched = xregex.exec(req.url.split("?", 1)) 90 | #console.log "/#{xregex}/ matched #{req.url.split("?", 1)} to get #{matched}" 91 | if not matched? 92 | continue 93 | # otherwise, we found our match. 94 | # construct the req.path_data object 95 | req.path_data = matched 96 | chain = if options and options.wrappers then options.wrappers.slice(0) else [] 97 | chain.push(default_wrapper(fn)) 98 | # This function will get passed through the wrapper chain like a hot potato. 99 | # all wrappers (except the last one) will receive this function as the third parameter, 100 | # and the wrapper is responsible for calling next(req, res) (or not). 101 | # I love closures. 102 | next = (req, res) -> 103 | next_wrapper = chain.shift() 104 | next_wrapper(req, res, next) 105 | # and finally 106 | next(req, res) 107 | return 108 | # if we're here, we failed to find a matching route. 109 | console.log("TODO request to unknown path #{req.url}") 110 | return 111 | 112 | server = http.createServer(giant_function) 113 | server.routes = parsed # you can dynamically alter this array if you want. 114 | return server 115 | 116 | # a default decorator that handles logging and stuff 117 | default_wrapper = (fn) -> 118 | return (req, res) -> 119 | SERVER_LOG.write("#{(''+new Date()).substr(0,24)} #{req.headers['x-real-ip'] or req.connection.remoteAddress} #{req.httpVersion} #{req.method} #{req.url} #{req.headers.referer} \n") 120 | SERVER_LOG.flush() 121 | res.addListener 'writeHead', (statusCode) -> 122 | SERVER_LOG.write("#{(''+new Date()).substr(0,24)} #{req.headers['x-real-ip'] or req.connection.remoteAddress} #{req.httpVersion} #{req.method} #{req.url} --> #{statusCode} \n") 123 | SERVER_LOG.flush() 124 | try 125 | if req.url.indexOf('?') != -1 126 | req.query_data = qs.parse(url.parse(req.url).query) 127 | else 128 | req.query_data = {} 129 | if (req.method == 'POST') 130 | body = '' 131 | req.setEncoding 'utf8' 132 | req.addListener 'data', (chunk) -> 133 | body += chunk 134 | req.addListener 'end', -> 135 | if body 136 | try 137 | if req.headers['content-type'].toLowerCase().indexOf('application/x-www-form-urlencoded') != -1 138 | req.post_data = www_forms.decodeForm(body) 139 | # SCRUB CARRIAGE RETURNS 140 | for key, value of req.post_data 141 | req.post_data[key] = value.replace(/\r\n/g, "\n") 142 | else 143 | req.post_data = body 144 | catch e 145 | console.log e.message 146 | console.log e.stack 147 | console.log "Exception in parsing post data #{body}. Ignoring exception." 148 | req.post_data = body 149 | return fn(req, res) 150 | else 151 | return fn(req, res) 152 | catch e 153 | console.log("error in Rowt: " + e) 154 | console.log(e.stack) 155 | try 156 | res.writeHead(500, status: 'woops') 157 | catch _ 158 | # pass 159 | res.end() 160 | 161 | # other utility stuff 162 | exports.randid = () -> 163 | text = "" 164 | possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" 165 | for i in [1..12] 166 | text += possible.charAt(Math.floor(Math.random() * possible.length)) 167 | return text 168 | 169 | # a function to add a digest nonce parameter to a static file to help with client cache busting 170 | _static_file_cache = {} 171 | exports.static_file = (filepath) -> 172 | if not _static_file_cache[filepath] 173 | fullfilepath = "static/#{filepath}" 174 | nonce = require('hashlib').md5(require('fs').statSync(fullfilepath).mtime)[1..10] 175 | console.log("SYNC CALL: static_file, nonce = #{nonce}") 176 | _static_file_cache[filepath] = "/#{fullfilepath}?v=#{nonce}" 177 | return _static_file_cache[filepath] 178 | 179 | crypto = require('crypto') 180 | exports.passhash = (password, salt, times) -> 181 | hashed = crypto.createHash('md5').update(password).digest('base64') 182 | for i in [1..times] 183 | hashed = crypto.createHash('md5').update(hashed).digest('base64') 184 | return hashed 185 | 186 | # clone nested objects, though 187 | # it gets tricky with special objects like Date... 188 | # add extensions here. 189 | exports.deep_clone = deep_clone = (obj) -> 190 | if obj == null 191 | return null 192 | newObj = if (obj instanceof Array) then (new Array()) else {} 193 | for own key, value of obj 194 | if value instanceof Date 195 | newObj[key] = value 196 | else if typeof value == 'object' 197 | newObj[key] = deep_clone(value) 198 | else 199 | newObj[key] = value 200 | return newObj 201 | 202 | # for displaying the hostname in parentheses 203 | exports.url_hostname = (url) -> 204 | try 205 | host = require('url').parse(url).hostname 206 | if host.substr(0, 4) == 'www.' and host.length > 7 207 | host = host.substr(4) 208 | catch e 209 | throw 'invalid url?' 210 | return host 211 | 212 | # sometimes you want to call a second block of code synchronously or asynchronously depending 213 | # on the first block of code. In this case, use the 'compose' method. 214 | # 215 | # compose (next) -> 216 | # if(synchronous?) 217 | # next("some_arg") 218 | # else 219 | # db.asynchronous_call (err, values) -> 220 | # next("other_arg") 221 | # , (arg) -> 222 | # console.log arg 223 | # 224 | # You can chain many functions together. 225 | # 226 | # compose (next) -> 227 | # console.log "this is the first line" 228 | # next("this is the second line") 229 | # 230 | # , (next, line) -> 231 | # console.log line 232 | # next("this is", "the third line") 233 | # 234 | # , (part1, part2) -> 235 | # console.log "#{part1} {part2}" 236 | 237 | compose = (fns...) -> 238 | _this = if (typeof(fns[0]) == 'function') then null else fns.shift() 239 | # return a function that calls the index'th function in fns 240 | next_gen = (index) -> 241 | () -> 242 | if not (0 <= index < fns.length) 243 | throw new Error "should not happen: 0 <= #{index} < #{fns.length}" 244 | next_block = fns[index] 245 | if index < fns.length - 1 246 | Array::unshift.call(arguments, next_gen(index+1)) 247 | return next_block.apply(_this, arguments) 248 | return next_gen(0)() 249 | -------------------------------------------------------------------------------- /vendor/www-forms/www-forms.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Hagen Overdick 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | function decode(token) { 24 | return decodeURIComponent(token.replace(/\+/g, " ")); 25 | } 26 | 27 | function parseToken(token) { 28 | return token.split("=").map(decode); 29 | } 30 | 31 | function internalSetValue(target, key, value, force) { 32 | var arrayTest = key.match(/(.+?)\[(.*)\]/); 33 | if (arrayTest) { 34 | target = (target[arrayTest[1]] = target[arrayTest[1]] || []); 35 | target = target[arrayTest[2]] = value; 36 | } else { 37 | target = (target[key] = force ? value : target[key] || value); 38 | } 39 | return target; 40 | } 41 | 42 | function setValue(target, key, value) { 43 | var subkeys = key.split("."); 44 | var valueKey = subkeys.pop(); 45 | 46 | for (var ii = 0; ii < subkeys.length; ii++) { 47 | target = internalSetValue(target, subkeys[ii], {}, false); 48 | } 49 | 50 | internalSetValue(target, valueKey, value, true); 51 | } 52 | 53 | exports.decodeForm = function(data) { 54 | var result = {}; 55 | if (data && data.split) { 56 | data.split("&").map(parseToken).forEach(function(token) { 57 | setValue(result, token[0], token[1]); 58 | }) 59 | } 60 | return result; 61 | } 62 | --------------------------------------------------------------------------------