caveat_patch_kids 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in caveat_patch_kids.gemspec
4
+ gemspec
5
+
6
+ gem 'pry'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Josh Nichols
2
+
3
+ MIT License
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
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # CaveatPatchKids
2
+
3
+ CaveatPatchKids is a tool for generating caveatPatchor.js files and for easily sharing snippets for use in caveatPatchor.js
4
+
5
+ ## Installation
6
+
7
+ Install in the usual way:
8
+
9
+ $ gem install caveat_patch_kids
10
+
11
+ ## Usage
12
+
13
+ To start, plant a cavet patch:
14
+
15
+ $ caveat-patch-kids plant
16
+ create /Users/yourface/.caveat_patch_kids/caveatPatchor.js
17
+
18
+ This creates a basic caveatPatchor.js you can customize. Either drop you code at the bottom, or require scripts provided by CaveatPatchKids (see below).
19
+
20
+ When you are happy with the results, bloom it:
21
+
22
+ $ caveat-patch-kids bloom
23
+ bloom /Users/yourface/Library/Application Support/Propane/unsupported/caveatPatchor.js
24
+
25
+ Now you can quit Propane, and launch it again. Hopefully nothing breaks...
26
+
27
+ If something does break, and you really need to get back into Propane, you can till:
28
+
29
+ $ caveat-patch-kids till
30
+ remove /Users/technicalpickles/Library/Application Support/Propane/unsupported/caveatPatchor.js
31
+
32
+ ### Scripts
33
+
34
+ These scripts are provided by CaveatPatchKids. Include them by updating ~/.caveat_patch_kids/caveatPatchor.js like:
35
+
36
+ //= require caveat_patch_kids/the_scripts
37
+
38
+ * caveat_patch_kids/display_avatars: display gravatars next to user's
39
+ * caveat_patch_kids/embiggen_message_history: increase message history
40
+ * caveat_patch_kids/stylize_diffs: colorize diffs with red/green
41
+ * caveat_patch_kids/stylize_diffs: colorize nagios alerts
42
+
43
+ The original caveatPatchor.js had a lot of mysterious and odd things. Those weren't included by default, but could be of use to someone, somewhere, or maybe just need some cleanup and documentation. See `scripts/caveat_patch_kids/unsupported` for the good.
44
+
45
+ ### Bundles
46
+
47
+ For convience, a full bundles with several scripts are included. Require them like any other script:
48
+
49
+ * caveat_patch_kids/bundles/all: all scripts (that aren't unsupported)
50
+ * caveat_patch_kids/bundles/unsupported: all scripts, even ones unsupported. you probably shouldn't do this unless you are a crazy person
51
+
52
+ ## Thanks
53
+
54
+ * [@protocool](https://github.com/protocool) for releasing Propane with caveatPatchor.js support
55
+ * [@wfarr](https://github.com/wfarr) for convincing someone to share their caveatPatchor.js
56
+ * [@sstephenson](https://github.com/sstephenson) for sprockets
57
+ * [@weppos](https://github.com/weppos) for [blogging about using sprockets outside of the context of a webapp](http://www.simonecarletti.com/blog/2011/09/using-sprockets-without-a-railsrack-project/)
58
+ * Maybe you? If you wrote a script here, and it's uncredited, please let me know
59
+
60
+ ## TODO
61
+
62
+ * make it easy for other people to release their own scripts as gems, and be able to load them
63
+ * include screenshots of scripts in action
64
+ * review unsupported stuff more closely
65
+
66
+ ## Contributing
67
+
68
+ 1. Fork it
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'caveat_patch_kids'
4
+ CaveatPatchKids::App.start
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'caveat_patch_kids/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "caveat_patch_kids"
8
+ gem.version = CaveatPatchKids::VERSION
9
+ gem.authors = ["Josh Nichols"]
10
+ gem.email = ["josh@technicalpickles.com"]
11
+ gem.description = %q{Manage caveatPatchor.js files for Propane}
12
+ gem.summary = %q{CaveatPatchKids is a tool for generating, sharing, and maintaing caveatPatchor.js files for use with Propane, powered by sprockets and other fun stuff}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.add_dependency 'sprockets', '>= 0'
20
+ gem.add_dependency 'thor', '>= 0'
21
+ gem.add_dependency 'coffee-script', '>= 0'
22
+ end
@@ -0,0 +1,57 @@
1
+ require "caveat_patch_kids/version"
2
+
3
+ require 'sprockets'
4
+ require 'pathname'
5
+ require 'logger'
6
+ require 'fileutils'
7
+
8
+ require 'thor'
9
+
10
+ module CaveatPatchKids
11
+
12
+ class App < Thor
13
+ include Thor::Actions
14
+ desc "plant", "Plant a basic ~/.caveat_patch_kids"
15
+ def plant
16
+ create_file "~/.caveat_patch_kids/caveatPatchor.js", <<END
17
+ //= require caveat_patch_kids
18
+ //
19
+ //= require caveat_patch_kids/display_avatars
20
+ //= require caveat_patch_kids/stylize_diffs
21
+ //
22
+ //= require_self
23
+ END
24
+ end
25
+
26
+ desc "bloom", "bloom a caveatPatchor.js using your planted ~/.caveat_patch_kids"
27
+ def bloom
28
+ root_dir = Pathname.new(__FILE__).basename + '..'
29
+ sprockets = Sprockets::Environment.new(root_dir)
30
+
31
+ vendor_assets_dir = root_dir + 'vendor/assets'
32
+ scripts_dir = root_dir + 'scripts'
33
+ home_dir = Pathname.new("~/.caveat_patch_kids")
34
+ unsupported_dir = Pathname.new("~/Library/Application Support/Propane/unsupported/").expand_path
35
+
36
+ sprockets.append_path vendor_assets_dir.to_s
37
+ sprockets.append_path scripts_dir.to_s
38
+ sprockets.append_path home_dir.expand_path.to_s
39
+
40
+ caveat_patchor = sprockets.find_asset('caveatPatchor.js')
41
+
42
+ prefix, basename = caveat_patchor.pathname.to_s.split('/')[-2..-1]
43
+
44
+ FileUtils.mkdir_p(unsupported_dir.to_s)
45
+
46
+ say_status "bloom", "#{unsupported_dir}/#{basename}"
47
+ caveat_patchor.write_to "#{unsupported_dir}/#{basename}"
48
+ end
49
+
50
+ desc "till", "till planted ~/.caveat_patch_kids"
51
+ def till
52
+ caveat_patchor = Pathname.new("~/Library/Application Support/Propane/unsupported/caveatPatchor.js").expand_path
53
+
54
+ remove_file caveat_patchor.to_s
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module CaveatPatchKids
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1 @@
1
+ //= require md5
@@ -0,0 +1,6 @@
1
+ //= require caveat_patch_kids
2
+ //
3
+ //= require caveat_patch_kids/display_avatars
4
+ //= require caveat_patch_kids/embiggen_message_history
5
+ //= require caveat_patch_kids/stylize_nagios
6
+ //= require caveat_patch_kids/stylize_diffs
@@ -0,0 +1,12 @@
1
+ //= require caveat_patch_kids/bundles/all
2
+ //
3
+ //= require caveat_patch_kids/unsupported/display_emoji
4
+ //= require caveat_patch_kids/unsupported/display_githubs
5
+ //= require caveat_patch_kids/unsupported/display_html
6
+ //= require caveat_patch_kids/unsupported/display_musics
7
+ //= require caveat_patch_kids/unsupported/display_newrelic_charts
8
+ //= require caveat_patch_kids/unsupported/display_stars
9
+ //= require caveat_patch_kids/unsupported/focus_scroll_hax
10
+ //= require caveat_patch_kids/unsupported/stylize_builds
11
+ //= require caveat_patch_kids/unsupported/stylize_commits_and_deploys
12
+ //= require caveat_patch_kids/unsupported/stylize_pivotal_tracker
@@ -0,0 +1,106 @@
1
+ var USER_ACTIONS = ['enter','leave','kick','conference_created','lock','unlock'];
2
+
3
+ Object.extend(Campfire.Message.prototype, {
4
+ authorID: function() {
5
+ if (Element.hasClassName(this.element, 'you'))
6
+ return this.chat.userID;
7
+
8
+ var idtext = (this.element.className.match(/\s*user_(\d+)\s*/) || [])[1];
9
+ return parseInt(idtext) || 0;
10
+ },
11
+
12
+ addAvatar: function() {
13
+ var
14
+ author = this.authorElement(),
15
+ body = this.bodyCell,
16
+ email,
17
+ avatar, name, imgSize = 32, img;
18
+
19
+ email = author.getAttribute('data-email')
20
+ if (email) {
21
+ var hash = calcMD5(email.trim().toLowerCase())
22
+ avatar = "http://gravatar.com/avatar/"+hash
23
+ } else {
24
+ // avatar = author.getAttribute('data-avatar') || 'http://asset1.37img.com/global/missing/avatar.png?r=3';
25
+ avatar = 'http://globase.heroku.com/redirect/gh.gravatars.' + this.authorID() + '?default=http://github.com/images/gravatars/gravatar-140.png';
26
+ }
27
+ name = '<strong class="authorName" style="color:#333;">'+author.textContent+'</strong>'
28
+
29
+ if (USER_ACTIONS.include(this.kind)) {
30
+ imgSize = 16
31
+ if ('conference_created' != this.kind)
32
+ body = body.select('div:first')[0]
33
+ name += ' '
34
+ } else if (this.actsLikeTextMessage()) {
35
+ name += '<br>'
36
+ } else {
37
+ return;
38
+ }
39
+
40
+ img = '<img alt="'+this.author()+'" width="'+imgSize+'" height="'+imgSize+'" align="absmiddle" style="opacity: 1.0; margin: 0px; border-radius:3px" src="'+avatar+'">'
41
+
42
+ if (USER_ACTIONS.include(this.kind)) {
43
+ name = img + '&nbsp;&nbsp;' + name;
44
+ img = ''
45
+ }
46
+
47
+ if (author.visible()) {
48
+ author.hide();
49
+
50
+ if (body.select('strong.authorName').length === 0) {
51
+ body.insert({top: name});
52
+ if (img)
53
+ author.insert({after: img});
54
+ }
55
+ }
56
+ }
57
+ });
58
+
59
+ /* if you can wrap rather than rewrite, use swizzle like this: */
60
+ swizzle(Campfire.Message, {
61
+ setAuthorVisibilityInRelationTo: function($super, message) {
62
+ $super(message);
63
+ this.addAvatar();
64
+ },
65
+ authorElement: function($super) {
66
+ if (USER_ACTIONS.include(this.kind)) {
67
+ return $super().select('span.author')[0]
68
+ } else {
69
+ return $super()
70
+ }
71
+ }
72
+ });
73
+
74
+
75
+ /* defining a new responder is probably the best way to insulate your hacks from Campfire and Propane */
76
+ Campfire.AvatarMangler = Class.create({
77
+ initialize: function(chat) {
78
+ this.chat = chat;
79
+
80
+ var messages = this.chat.transcript.messages;
81
+ for (var i = 0; i < messages.length; i++) {
82
+ var message = messages[i];
83
+ message.addAvatar();
84
+ }
85
+
86
+ this.chat.layoutmanager.layout();
87
+ this.chat.windowmanager.scrollToBottom();
88
+ },
89
+
90
+ onMessagesInserted: function(messages) {
91
+ var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
92
+
93
+ for (var i = 0; i < messages.length; i++) {
94
+ var message = messages[i];
95
+ message.addAvatar();
96
+ }
97
+
98
+ if (scrolledToBottom) {
99
+ this.chat.windowmanager.scrollToBottom();
100
+ }
101
+ }
102
+ });
103
+
104
+ /* Here is how to install your responder into the running chat */
105
+ Campfire.Responders.push("AvatarMangler");
106
+ window.chat.installPropaneResponder("AvatarMangler", "avatarmangler");
@@ -0,0 +1,73 @@
1
+ Campfire.GitHubExpander = Class.create({
2
+ initialize: function(chat) {
3
+ this.chat = chat;
4
+ var messages = this.chat.transcript.messages;
5
+ for (var i = 0; i < messages.length; i++) {
6
+ this.detectGitHubURL(messages[i]);
7
+ }
8
+ this.chat.windowmanager.scrollToBottom();
9
+ },
10
+
11
+ detectGitHubURL: function(message) {
12
+ if (!message.pending() && message.kind === 'text') {
13
+ var iframe = null, elem, height = 150;
14
+
15
+ var gists = message.bodyElement().select('a[href*="gist.github.com"]');
16
+ if (gists.length == 1) {
17
+ elem = gists[0];
18
+ var href = elem.getAttribute('href');
19
+ var match = href.match(/^https?:\/\/gist.github.com\/([A-Fa-f0-9]+)/);
20
+ if (match) {
21
+ iframe = 'https://gist.github.com/'+match[1]+'.pibb';
22
+ }
23
+ }
24
+
25
+ var blobs = message.bodyElement().select('a[href*="#L"]');
26
+ if (blobs.length == 1) {
27
+ elem = blobs[0];
28
+ var href = elem.getAttribute('href');
29
+ iframe = href;
30
+ }
31
+
32
+ var blobs = message.bodyElement().select('a[href*="/blob/"]');
33
+ if (!iframe && blobs.length == 1) {
34
+ elem = blobs[0];
35
+ var href = elem.getAttribute('href');
36
+ if (href.indexOf('#') > -1)
37
+ iframe = href;
38
+ else
39
+ iframe = href + '#L1';
40
+ }
41
+
42
+ // var commits = message.bodyElement().select('a[href*=/commit/]')
43
+ // if (!iframe && commits.length == 1 && message.author() != 'Mister Robot' && message.author() != 'Git') {
44
+ // elem = commits[0];
45
+ // var href = elem.getAttribute('href');
46
+ // if (href.indexOf('#') > -1)
47
+ // iframe = href;
48
+ // else
49
+ // iframe = href + '#diff-stat';
50
+ // }
51
+
52
+ if (!iframe || IFRAME_HATERS.include(this.chat.username)) return;
53
+ message.bodyElement().insert({bottom:"<iframe style='border:0; margin-top: 5px' height='"+height+"' width='98%' src='"+iframe+"'></iframe>"});
54
+ }
55
+ },
56
+
57
+ onMessagesInsertedBeforeDisplay: function(messages) {
58
+ var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
59
+ for (var i = 0; i < messages.length; i++) {
60
+ this.detectGitHubURL(messages[i]);
61
+ }
62
+ if (scrolledToBottom) {
63
+ this.chat.windowmanager.scrollToBottom();
64
+ }
65
+ },
66
+
67
+ onMessageAccepted: function(message, messageID) {
68
+ this.detectGitHubURL(message);
69
+ }
70
+ });
71
+
72
+ Campfire.Responders.push("GitHubExpander");
73
+ window.chat.installPropaneResponder("GitHubExpander", "githubexpander");
@@ -0,0 +1 @@
1
+ window.chat.messageHistory = 1600;
@@ -0,0 +1,52 @@
1
+ Campfire.DiffExpander = Class.create({
2
+ initialize: function(chat) {
3
+ this.chat = chat;
4
+ var messages = this.chat.transcript.messages;
5
+ for (var i = 0; i < messages.length; i++) {
6
+ this.detectDiff(messages[i]);
7
+ }
8
+ this.chat.windowmanager.scrollToBottom();
9
+ },
10
+
11
+ detectDiff: function(message) {
12
+ if (message.kind === 'paste') {
13
+ var code = message.bodyCell.select('pre code')
14
+ if (code.length) {
15
+ var diff = code[0].innerText
16
+ if (diff.match(/^\+\+\+/m)) {
17
+ var lines = diff.split("\n").map(function(line){
18
+ if (line.match(/^(diff|index)/)) {
19
+ return "<b>"+line.escapeHTML()+"</b>"
20
+ } else if (match = line.match(/^(@@.+?@@)(.*)$/)) {
21
+ return "<b>"+match[1]+"</b> " + match[2].escapeHTML()
22
+ } else if (line.match(/^\+/)) {
23
+ return "<font style='color:green'>"+line.escapeHTML()+"</font>"
24
+ } else if (line.match(/^\-/)) {
25
+ return "<font style='color:red'>"+line.escapeHTML()+"</font>"
26
+ } else {
27
+ return line.escapeHTML()
28
+ }
29
+ })
30
+ code[0].innerHTML = lines.join("\n")
31
+ }
32
+ }
33
+ }
34
+ },
35
+
36
+ onMessagesInsertedBeforeDisplay: function(messages) {
37
+ var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
38
+ for (var i = 0; i < messages.length; i++) {
39
+ this.detectDiff(messages[i]);
40
+ }
41
+ if (scrolledToBottom) {
42
+ this.chat.windowmanager.scrollToBottom();
43
+ }
44
+ },
45
+
46
+ onMessageAccepted: function(message, messageID) {
47
+ this.detectDiff(message);
48
+ }
49
+ });
50
+
51
+ Campfire.Responders.push("DiffExpander");
52
+ window.chat.installPropaneResponder("DiffExpander", "diffexpander");
@@ -0,0 +1,45 @@
1
+ Campfire.NagiosExpander = Class.create({
2
+ initialize: function(chat) {
3
+ this.chat = chat;
4
+ var messages = this.chat.transcript.messages;
5
+ for (var i = 0; i < messages.length; i++) {
6
+ this.detectNagios(messages[i]);
7
+ }
8
+ },
9
+
10
+ detectNagios: function(message) {
11
+ if (!message.pending() && message.kind === 'text') {
12
+ var body = message.bodyElement()
13
+ var author = message.author();
14
+ var email = message.authorElement().getAttribute('data-email');
15
+ if (body.innerText.match(/^Nagios : /) || (email && email.match(/nagios/i))) {
16
+ if (body.innerText.match(/PROBLEM/)) {
17
+ message.bodyCell.setStyle({
18
+ color: "#ef2929"
19
+ })
20
+ } else if (body.innerText.match(/WARNING/)) {
21
+ message.bodyCell.setStyle({
22
+ color: "#fce94f"
23
+ })
24
+ } else if (body.innerText.match(/RECOVERY/)) {
25
+ message.bodyCell.setStyle({
26
+ color: "#4e9a06"
27
+ })
28
+ }
29
+ }
30
+ }
31
+ },
32
+
33
+ onMessagesInsertedBeforeDisplay: function(messages) {
34
+ for (var i = 0; i < messages.length; i++) {
35
+ this.detectNagios(messages[i]);
36
+ }
37
+ },
38
+
39
+ onMessageAccepted: function(message, messageID) {
40
+ this.detectNagios(message);
41
+ }
42
+ });
43
+
44
+ Campfire.Responders.push("NagiosExpander");
45
+ window.chat.installPropaneResponder("NagiosExpander", "nagiosexpander");
@@ -0,0 +1,53 @@
1
+ Autolink['Emoji']['bear'] = '1f40b'
2
+ CAMPFIRE_EMOJI = new Hash(Autolink.Emoji).inject({}, function(hash,v){ hash[v[1]]=v[0]; return hash })
3
+ // from GitHub::HTML::EmojiFilter::EmojiPattern
4
+ GITHUB_EMOJI = /:(sparkles|key|scissors|octocat|warning|heart|clap|airplane|leaves|new|broken_heart|ok|couple|fire|iphone|sunny|rainbow|email|book|mag|koala|mega|apple|dog|princess|rose|calling|tophat|beer|art|v|cat|ski|thumbsup|punch|dolphin|cloud|zap|bear|fist|horse|lock|smoking|moneybag|computer|cake|taxi|cool|feet|tm|kiss|train|bulb|thumbsdown|sunflower|nail_care|bike|hammer|gift|lipstick|fish|zzz|lips|bus|star|cop|pencil|bomb|vs|memo|\-1|\+1|runner|wheelchair):/g
5
+
6
+ Campfire.EmojiExpander = Class.create({
7
+ initialize: function(chat) {
8
+ this.chat = chat;
9
+ var messages = this.chat.transcript.messages;
10
+ for (var i = 0; i < messages.length; i++) {
11
+ this.detectEmoji(messages[i]);
12
+ }
13
+ this.chat.windowmanager.scrollToBottom();
14
+ },
15
+
16
+ detectEmoji: function(message) {
17
+ if (message.kind == 'text') {
18
+ var body = message.bodyElement()
19
+ var emoji = body.select('span.emoji');
20
+ emoji.each(function(e){
21
+ var code = e.className.match(/emoji([\da-f]+)/)[1]
22
+ e.replace(':' + CAMPFIRE_EMOJI[code] + ':')
23
+ })
24
+ var html = body.innerHTML
25
+ var match = html.match(GITHUB_EMOJI)
26
+ if (match) {
27
+ body.innerHTML = html.replace(GITHUB_EMOJI, function(all, e){
28
+ var size = 28
29
+ if (e == 'octocat') size = 40
30
+ if (message.author() == 'Mister Robot') size = 18
31
+ return "<img title=':"+e+":' alt=':"+e+":' src='http://d3nwyuy0nl342s.cloudfront.net/images/icons/emoji/v2/"+e+".png' height='"+size+"' width='"+size+"' align='absmiddle'/>"
32
+ })
33
+ }
34
+ }
35
+ },
36
+
37
+ onMessagesInsertedBeforeDisplay: function(messages) {
38
+ var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
39
+ for (var i = 0; i < messages.length; i++) {
40
+ this.detectEmoji(messages[i]);
41
+ }
42
+ if (scrolledToBottom) {
43
+ this.chat.windowmanager.scrollToBottom();
44
+ }
45
+ },
46
+
47
+ onMessageAccepted: function(message, messageID) {
48
+ this.detectEmoji(message);
49
+ }
50
+ });
51
+
52
+ Campfire.Responders.push("EmojiExpander");
53
+ window.chat.installPropaneResponder("EmojiExpander", "emojiexpander");
@@ -0,0 +1,42 @@
1
+ Campfire.HTMLExpander = Class.create({
2
+ initialize: function(chat) {
3
+ this.chat = chat;
4
+ // var messages = this.chat.transcript.messages;
5
+ // for (var i = 0; i < messages.length; i++) {
6
+ // this.detectHTML(messages[i]);
7
+ // }
8
+ // this.chat.windowmanager.scrollToBottom();
9
+ },
10
+
11
+ detectHTML: function(message) {
12
+ if (!message.pending() && ['text','paste'].include(message.kind)) {
13
+ var body = message.bodyElement()
14
+ var match = body.innerText.match(/^HTML!\s+(.+)$/m);
15
+
16
+ // Some people can't handle this much fun
17
+ var halt = SOUND_HATERS.include(this.chat.username) && body.innerText.match(/<audio/)
18
+
19
+ if (!halt && match && !body.innerText.match(/<\s*script/)) {
20
+ body.update(match[1])
21
+ }
22
+ }
23
+ },
24
+
25
+ onMessagesInsertedBeforeDisplay: function(messages) {
26
+ var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
27
+ for (var i = 0; i < messages.length; i++) {
28
+ this.detectHTML(messages[i]);
29
+ }
30
+ if (scrolledToBottom) {
31
+ this.chat.windowmanager.scrollToBottom();
32
+ }
33
+ },
34
+
35
+ onMessageAccepted: function(message, messageID) {
36
+ this.detectHTML(message);
37
+ }
38
+ });
39
+
40
+ Campfire.Responders.push("HTMLExpander");
41
+ window.chat.installPropaneResponder("HTMLExpander", "htmlexpander");
42
+
@@ -0,0 +1,57 @@
1
+ Campfire.MusicExpander = Class.create({
2
+ initialize: function(chat) {
3
+ this.chat = chat;
4
+ var messages = this.chat.transcript.messages;
5
+ for (var i = 0; i < messages.length; i++) {
6
+ this.detectMusic(messages[i]);
7
+ }
8
+ this.chat.windowmanager.scrollToBottom();
9
+ },
10
+
11
+ detectMusic: function(message) {
12
+ if (message.actsLikeTextMessage()) {
13
+ var body = message.bodyElement()
14
+ var html = body.innerHTML
15
+
16
+ var match = html.match(/(Now playing|is listening to|Queued up) "(.*)" by (.*), from(?: the album)? "(.*)"/i)
17
+ if (match) {
18
+ var text = match[1]
19
+ var song = match[2], artist = match[3], album = match[4]
20
+ var url = "http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Ddigital-music&x=8&y=16&field-keywords="
21
+ var linkify = function(text, query){
22
+ if (!query) query = text
23
+ return new Element('a', {target:'_blank',href:url+encodeURI(query)}).update(text).outerHTML;
24
+ }
25
+
26
+ html = text + ' "'
27
+ if (song)
28
+ html += linkify(song, song+" "+artist+" "+album)
29
+ html += '" by '
30
+ if (artist)
31
+ html += linkify(artist)
32
+ html += ', from the album "'
33
+ if (album)
34
+ html += linkify(album, artist+" "+album)
35
+ html += '"'
36
+ body.innerHTML = html
37
+ }
38
+ }
39
+ },
40
+
41
+ onMessagesInsertedBeforeDisplay: function(messages) {
42
+ var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
43
+ for (var i = 0; i < messages.length; i++) {
44
+ this.detectMusic(messages[i]);
45
+ }
46
+ if (scrolledToBottom) {
47
+ this.chat.windowmanager.scrollToBottom();
48
+ }
49
+ },
50
+
51
+ onMessageAccepted: function(message, messageID) {
52
+ this.detectMusic(message);
53
+ }
54
+ });
55
+
56
+ Campfire.Responders.push("MusicExpander");
57
+ window.chat.installPropaneResponder("MusicExpander", "musicexpander");
@@ -0,0 +1,44 @@
1
+ Campfire.NewRelicChartExpander = Class.create({
2
+ initialize: function(chat) {
3
+ this.chat = chat;
4
+ var messages = this.chat.transcript.messages;
5
+ for (var i = 0; i < messages.length; i++) {
6
+ this.detectNewRelicChartURL(messages[i]);
7
+ }
8
+ this.chat.windowmanager.scrollToBottom();
9
+ },
10
+
11
+ detectNewRelicChartURL: function(message) {
12
+ if (!message.pending() && message.kind === 'text') {
13
+ var iframe = null, elem, height = 200;
14
+
15
+ var charts = message.bodyElement().select('a[href*="rpm.newrelic.com/public/charts"]');
16
+
17
+ if (charts.length == 1) {
18
+ elem = charts[0];
19
+ var href = elem.getAttribute('href');
20
+ iframe = href;
21
+ }
22
+
23
+ if (!iframe || IFRAME_HATERS.include(this.chat.username)) return;
24
+ message.bodyCell.insert({bottom:"<iframe style='border:0; margin-top: 5px' height='"+height+"' width='98%' src='"+iframe+"'></iframe>"});
25
+ }
26
+ },
27
+
28
+ onMessagesInsertedBeforeDisplay: function(messages) {
29
+ var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
30
+ for (var i = 0; i < messages.length; i++) {
31
+ this.detectNewRelicChartURL(messages[i]);
32
+ }
33
+ if (scrolledToBottom) {
34
+ this.chat.windowmanager.scrollToBottom();
35
+ }
36
+ },
37
+
38
+ onMessageAccepted: function(message, messageID) {
39
+ this.detectNewRelicChartURL(message);
40
+ }
41
+ });
42
+
43
+ Campfire.Responders.push("NewRelicChartExpander");
44
+ window.chat.installPropaneResponder("NewRelicChartExpander", "newrelicchartexpander");
@@ -0,0 +1,29 @@
1
+ swizzle(Campfire.StarManager, {
2
+ toggle: function($super, element) {
3
+ $super(element);
4
+
5
+ var star = $(element).up('span.star'),
6
+ message = this.chat.findMessage(element)
7
+ if (star.hasClassName('starred')) {
8
+ trackStar(message);
9
+ }
10
+ }
11
+ });
12
+
13
+ // 5490ef76-50fa-11e0-8fed-2495f6688d41
14
+ // bb628a4e-5199-11e0-949d-2e03dd584bf3 is a test cluster
15
+ function trackStar(message) {
16
+ var id = message.id()
17
+ , url = "http://allofthestars.com/clusters/.../campfire" +
18
+ "?message=" + encodeURIComponent(message.bodyElement().innerText) +
19
+ "&message_id=" + encodeURIComponent(id.toString()) +
20
+ "&url=" + encodeURIComponent(starPermalink(id)) +
21
+ "&author=" + encodeURIComponent(message.author()) +
22
+ "&room=" + encodeURIComponent($('room_name').innerText)
23
+ window.propane.requestJSON(id, url)
24
+ }
25
+
26
+ function starPermalink(id) {
27
+ return location.href.toString().replace(/#.*/, '') +
28
+ "transcript/message/" + id + "#message_" + id
29
+ }
@@ -0,0 +1,9 @@
1
+ /* focus/scroll hax */
2
+ // var $focused = true;
3
+ // window.onfocus = function(){ alert(1); $focused = true }
4
+ // window.onblur = function(){ $focused = false }
5
+ // swizzle(Campfire.WindowManager, {
6
+ // isScrolledToBottom: function($super) {
7
+ // return $focused ? $super() : false;
8
+ // }
9
+ // });
@@ -0,0 +1,60 @@
1
+ Campfire.BuildExpander = Class.create({
2
+ initialize: function(chat) {
3
+ this.chat = chat;
4
+ var messages = this.chat.transcript.messages;
5
+ for (var i = 0; i < messages.length; i++) {
6
+ this.detectBuild(messages[i]);
7
+ }
8
+ },
9
+
10
+ detectBuild: function(message) {
11
+ if (!message.pending() && message.kind === 'text') {
12
+ var body = message.bodyElement()
13
+ if (body.innerText.match(/^Build #(\d+) \([0-9a-zA-Z]+\) of (github-)?([-_0-9a-zA-Z]+)/)) {
14
+ var failed_p = body.innerText.match(/failed/);
15
+ var success_p = body.innerText.match(/success/);
16
+ var color = failed_p ? '#ff0000' : '#00941f';
17
+ if (failed_p || success_p)
18
+ message.bodyCell.setStyle({
19
+ color: color,
20
+ fontWeight: 'bold'
21
+ })
22
+
23
+ var sha = body.innerText.match(/\(([0-9a-z]+)\)/i)[1]
24
+ var build;
25
+ if (body.outerHTML.match(/^github-(?!services)/)) {
26
+ build = body.outerHTML.replace(/#(\d+) \(([0-9a-zA-Z]+)\) of (?:github-)?([-_0-9a-zA-Z]+)/, '<a target="_blank" href="http://ci2.rs.github.com:8080/job/github-$3/$1/console">#$1</a> ($2) of github-$3')
27
+ } else {
28
+ build = body.outerHTML.replace(/#(\d+) \(([0-9a-zA-Z]+)\) of ([-_0-9a-zA-Z]+)/, '<a target="_blank" href="https://janky.rs.github.com/$1/output">#$1</a> ($2) of $3')
29
+ }
30
+ var btime = build.match(/\d+s/)
31
+ body.replace(build)
32
+ build = build.replace(/^.*?<a/,'<a').replace(/<\/a>.*/, '</a>')
33
+
34
+ var msgIndex = this.chat.transcript.messages.indexOf(message);
35
+ if (msgIndex > -1) {
36
+ for (var i=msgIndex; i > 0 && i > msgIndex - 5; i--) {
37
+ var otherMsg = this.chat.transcript.messages[i]
38
+ if (otherMsg.element.innerHTML.match("/commit/" + sha)) {
39
+ build = build.replace(/<\/a>.*$/, '</a>').replace('Build ','');
40
+ if (btime) build += "] [" + btime;
41
+ otherMsg.bodyElement().insert({bottom: " ["+build+"]"})
42
+ otherMsg.bodyCell.setStyle({color:color,fontWeight:'bold'})
43
+ message.element.remove()
44
+ break
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+ },
51
+
52
+ onMessagesInsertedBeforeDisplay: function(messages) {
53
+ for (var i = 0; i < messages.length; i++) {
54
+ this.detectBuild(messages[i]);
55
+ }
56
+ }
57
+ });
58
+
59
+ Campfire.Responders.push("BuildExpander");
60
+ window.chat.installPropaneResponder("BuildExpander", "buildexpander");
@@ -0,0 +1,36 @@
1
+ Campfire.CommitExpander = Class.create({
2
+ initialize: function(chat) {
3
+ this.chat = chat;
4
+ var messages = this.chat.transcript.messages;
5
+ for (var i = 0; i < messages.length; i++) {
6
+ this.detectCommit(messages[i]);
7
+ }
8
+ },
9
+
10
+ detectCommit: function(message) {
11
+ if (!message.pending() && message.kind === 'text') {
12
+ var body = message.bodyElement()
13
+ if (body.innerText.match(/^\[[\w-\.]+(\/|\])/) || body.innerText.match(/(is deploying|deployment of)/)) {
14
+ message.bodyCell.setStyle({
15
+ color: '#888888'
16
+ })
17
+ }
18
+ else if (body.innerText.match(/^\w+'s deploy of (.*) failed$/)) {
19
+ message.bodyCell.setStyle({
20
+ color: '#ff0000',
21
+ fontWeight: 'bold'
22
+ })
23
+ }
24
+ }
25
+ },
26
+
27
+ onMessagesInsertedBeforeDisplay: function(messages) {
28
+ for (var i = 0; i < messages.length; i++) {
29
+ this.detectCommit(messages[i]);
30
+ }
31
+ }
32
+ });
33
+
34
+ Campfire.Responders.push("CommitExpander");
35
+ window.chat.installPropaneResponder("CommitExpander", "commitexpander");
36
+
@@ -0,0 +1,70 @@
1
+ Campfire.PivotalTrackerExpander = Class.create({
2
+ initialize: function(chat) {
3
+ this.chat = chat;
4
+ var messages = this.chat.transcript.messages;
5
+ for (var i = 0; i < messages.length; i++) {
6
+ this.detectPivotalTracker(messages[i]);
7
+ }
8
+ },
9
+
10
+ detectPivotalTracker: function(message) {
11
+ if (!message.pending() && message.kind === 'text') {
12
+ var body = message.bodyElement()
13
+ if (body.innerText.match(/(in|to) project/i)) {
14
+ if (body.innerText.match(/pivotaltracker.com/i)) {
15
+
16
+ if (colorizePivotalTracker) {
17
+ if (body.innerText.match(/added/g)) {
18
+ message.bodyCell.setStyle({
19
+ color: pivotalTrackerAddedColor
20
+ })
21
+ } else if (body.innerText.match(/started/g)) {
22
+ message.bodyCell.setStyle({
23
+ color: pivotalTrackerStartedColor
24
+ })
25
+ } else if (body.innerText.match(/finished/g)) {
26
+ message.bodyCell.setStyle({
27
+ color: pivotalTrackerFinishedColor
28
+ })
29
+ } else if (body.innerText.match(/delivered/g)) {
30
+ message.bodyCell.setStyle({
31
+ color: pivotalTrackerDeliveredColor
32
+ })
33
+ } else if (body.innerText.match(/accepted/g)) {
34
+ message.bodyCell.setStyle({
35
+ color: pivotalTrackerAcceptedColor
36
+ })
37
+ } else if (body.innerText.match(/rejected/g)) {
38
+ message.bodyCell.setStyle({
39
+ color: pivotalTrackerRejectedColor
40
+ })
41
+ }
42
+ }
43
+
44
+ if (shortenPivotalName) {
45
+ matches = body.innerText.match(/^((?:[A-Z]{1}[a-z]* ?){2,3}) (?:added|started|finished|delivered|accepted|rejected)/)
46
+ body.innerHTML = body.innerHTML.replace(/^((?:[A-Z]{1}[a-z]* ?){2,3})/, "<strong>" + matches[1].replace(/[^A-Z]/g, '') + "</strong> ")
47
+ }
48
+
49
+ if (linkifyPivotalStories) {
50
+ matches = body.innerText.match(/"(.*)" \((.*)\)/)
51
+ body.innerHTML = body.innerHTML.replace(/(".*" \(.*\))/, "\"<a href='" + matches[2] + "' target='_blank'>" + matches[1] + "</a>\"");
52
+ }
53
+ }
54
+ }
55
+ }
56
+ },
57
+
58
+ onMessagesInsertedBeforeDisplay: function(messages) {
59
+ for (var i = 0; i < messages.length; i++) {
60
+ this.detectPivotalTracker(messages[i]);
61
+ }
62
+ },
63
+
64
+ onMessageAccepted: function(message, messageID) {
65
+ this.detectPivotalTracker(message);
66
+ }
67
+ });
68
+
69
+ Campfire.Responders.push("PivotalTrackerExpander");
70
+ window.chat.installPropaneResponder("PivotalTrackerExpander", "pivotaltrackerexpander");
@@ -0,0 +1,176 @@
1
+ /* MD5 LIB */
2
+ /*
3
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
4
+ * Digest Algorithm, as defined in RFC 1321.
5
+ * Copyright (C) Paul Johnston 1999 - 2000.
6
+ * Updated by Greg Holt 2000 - 2001.
7
+ * See http://pajhome.org.uk/site/legal.html for details.
8
+ */
9
+
10
+ /*
11
+ * Convert a 32-bit number to a hex string with ls-byte first
12
+ */
13
+ var hex_chr = "0123456789abcdef";
14
+ function rhex(num)
15
+ {
16
+ str = "";
17
+ for(j = 0; j <= 3; j++)
18
+ str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) +
19
+ hex_chr.charAt((num >> (j * 8)) & 0x0F);
20
+ return str;
21
+ }
22
+
23
+ /*
24
+ * Convert a string to a sequence of 16-word blocks, stored as an array.
25
+ * Append padding bits and the length, as described in the MD5 standard.
26
+ */
27
+ function str2blks_MD5(str)
28
+ {
29
+ nblk = ((str.length + 8) >> 6) + 1;
30
+ blks = new Array(nblk * 16);
31
+ for(i = 0; i < nblk * 16; i++) blks[i] = 0;
32
+ for(i = 0; i < str.length; i++)
33
+ blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
34
+ blks[i >> 2] |= 0x80 << ((i % 4) * 8);
35
+ blks[nblk * 16 - 2] = str.length * 8;
36
+ return blks;
37
+ }
38
+
39
+ /*
40
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
41
+ * to work around bugs in some JS interpreters.
42
+ */
43
+ function add(x, y)
44
+ {
45
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
46
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
47
+ return (msw << 16) | (lsw & 0xFFFF);
48
+ }
49
+
50
+ /*
51
+ * Bitwise rotate a 32-bit number to the left
52
+ */
53
+ function rol(num, cnt)
54
+ {
55
+ return (num << cnt) | (num >>> (32 - cnt));
56
+ }
57
+
58
+ /*
59
+ * These functions implement the basic operation for each round of the
60
+ * algorithm.
61
+ */
62
+ function cmn(q, a, b, x, s, t)
63
+ {
64
+ return add(rol(add(add(a, q), add(x, t)), s), b);
65
+ }
66
+ function ff(a, b, c, d, x, s, t)
67
+ {
68
+ return cmn((b & c) | ((~b) & d), a, b, x, s, t);
69
+ }
70
+ function gg(a, b, c, d, x, s, t)
71
+ {
72
+ return cmn((b & d) | (c & (~d)), a, b, x, s, t);
73
+ }
74
+ function hh(a, b, c, d, x, s, t)
75
+ {
76
+ return cmn(b ^ c ^ d, a, b, x, s, t);
77
+ }
78
+ function ii(a, b, c, d, x, s, t)
79
+ {
80
+ return cmn(c ^ (b | (~d)), a, b, x, s, t);
81
+ }
82
+
83
+ /*
84
+ * Take a string and return the hex representation of its MD5.
85
+ */
86
+ function calcMD5(str)
87
+ {
88
+ x = str2blks_MD5(str);
89
+ a = 1732584193;
90
+ b = -271733879;
91
+ c = -1732584194;
92
+ d = 271733878;
93
+
94
+ for(i = 0; i < x.length; i += 16)
95
+ {
96
+ olda = a;
97
+ oldb = b;
98
+ oldc = c;
99
+ oldd = d;
100
+
101
+ a = ff(a, b, c, d, x[i+ 0], 7 , -680876936);
102
+ d = ff(d, a, b, c, x[i+ 1], 12, -389564586);
103
+ c = ff(c, d, a, b, x[i+ 2], 17, 606105819);
104
+ b = ff(b, c, d, a, x[i+ 3], 22, -1044525330);
105
+ a = ff(a, b, c, d, x[i+ 4], 7 , -176418897);
106
+ d = ff(d, a, b, c, x[i+ 5], 12, 1200080426);
107
+ c = ff(c, d, a, b, x[i+ 6], 17, -1473231341);
108
+ b = ff(b, c, d, a, x[i+ 7], 22, -45705983);
109
+ a = ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
110
+ d = ff(d, a, b, c, x[i+ 9], 12, -1958414417);
111
+ c = ff(c, d, a, b, x[i+10], 17, -42063);
112
+ b = ff(b, c, d, a, x[i+11], 22, -1990404162);
113
+ a = ff(a, b, c, d, x[i+12], 7 , 1804603682);
114
+ d = ff(d, a, b, c, x[i+13], 12, -40341101);
115
+ c = ff(c, d, a, b, x[i+14], 17, -1502002290);
116
+ b = ff(b, c, d, a, x[i+15], 22, 1236535329);
117
+
118
+ a = gg(a, b, c, d, x[i+ 1], 5 , -165796510);
119
+ d = gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
120
+ c = gg(c, d, a, b, x[i+11], 14, 643717713);
121
+ b = gg(b, c, d, a, x[i+ 0], 20, -373897302);
122
+ a = gg(a, b, c, d, x[i+ 5], 5 , -701558691);
123
+ d = gg(d, a, b, c, x[i+10], 9 , 38016083);
124
+ c = gg(c, d, a, b, x[i+15], 14, -660478335);
125
+ b = gg(b, c, d, a, x[i+ 4], 20, -405537848);
126
+ a = gg(a, b, c, d, x[i+ 9], 5 , 568446438);
127
+ d = gg(d, a, b, c, x[i+14], 9 , -1019803690);
128
+ c = gg(c, d, a, b, x[i+ 3], 14, -187363961);
129
+ b = gg(b, c, d, a, x[i+ 8], 20, 1163531501);
130
+ a = gg(a, b, c, d, x[i+13], 5 , -1444681467);
131
+ d = gg(d, a, b, c, x[i+ 2], 9 , -51403784);
132
+ c = gg(c, d, a, b, x[i+ 7], 14, 1735328473);
133
+ b = gg(b, c, d, a, x[i+12], 20, -1926607734);
134
+
135
+ a = hh(a, b, c, d, x[i+ 5], 4 , -378558);
136
+ d = hh(d, a, b, c, x[i+ 8], 11, -2022574463);
137
+ c = hh(c, d, a, b, x[i+11], 16, 1839030562);
138
+ b = hh(b, c, d, a, x[i+14], 23, -35309556);
139
+ a = hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
140
+ d = hh(d, a, b, c, x[i+ 4], 11, 1272893353);
141
+ c = hh(c, d, a, b, x[i+ 7], 16, -155497632);
142
+ b = hh(b, c, d, a, x[i+10], 23, -1094730640);
143
+ a = hh(a, b, c, d, x[i+13], 4 , 681279174);
144
+ d = hh(d, a, b, c, x[i+ 0], 11, -358537222);
145
+ c = hh(c, d, a, b, x[i+ 3], 16, -722521979);
146
+ b = hh(b, c, d, a, x[i+ 6], 23, 76029189);
147
+ a = hh(a, b, c, d, x[i+ 9], 4 , -640364487);
148
+ d = hh(d, a, b, c, x[i+12], 11, -421815835);
149
+ c = hh(c, d, a, b, x[i+15], 16, 530742520);
150
+ b = hh(b, c, d, a, x[i+ 2], 23, -995338651);
151
+
152
+ a = ii(a, b, c, d, x[i+ 0], 6 , -198630844);
153
+ d = ii(d, a, b, c, x[i+ 7], 10, 1126891415);
154
+ c = ii(c, d, a, b, x[i+14], 15, -1416354905);
155
+ b = ii(b, c, d, a, x[i+ 5], 21, -57434055);
156
+ a = ii(a, b, c, d, x[i+12], 6 , 1700485571);
157
+ d = ii(d, a, b, c, x[i+ 3], 10, -1894986606);
158
+ c = ii(c, d, a, b, x[i+10], 15, -1051523);
159
+ b = ii(b, c, d, a, x[i+ 1], 21, -2054922799);
160
+ a = ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
161
+ d = ii(d, a, b, c, x[i+15], 10, -30611744);
162
+ c = ii(c, d, a, b, x[i+ 6], 15, -1560198380);
163
+ b = ii(b, c, d, a, x[i+13], 21, 1309151649);
164
+ a = ii(a, b, c, d, x[i+ 4], 6 , -145523070);
165
+ d = ii(d, a, b, c, x[i+11], 10, -1120210379);
166
+ c = ii(c, d, a, b, x[i+ 2], 15, 718787259);
167
+ b = ii(b, c, d, a, x[i+ 9], 21, -343485551);
168
+
169
+ a = add(a, olda);
170
+ b = add(b, oldb);
171
+ c = add(c, oldc);
172
+ d = add(d, oldd);
173
+ }
174
+ return rhex(a) + rhex(b) + rhex(c) + rhex(d);
175
+ }
176
+ /* END MD5 LIB */
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: caveat_patch_kids
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Josh Nichols
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sprockets
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: thor
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: coffee-script
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Manage caveatPatchor.js files for Propane
63
+ email:
64
+ - josh@technicalpickles.com
65
+ executables:
66
+ - caveat-patch-kids
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - bin/caveat-patch-kids
76
+ - caveat_patch_kids.gemspec
77
+ - lib/caveat_patch_kids.rb
78
+ - lib/caveat_patch_kids/version.rb
79
+ - scripts/caveat_patch_kids.js
80
+ - scripts/caveat_patch_kids/bundles/all.js
81
+ - scripts/caveat_patch_kids/bundles/unsupported.js
82
+ - scripts/caveat_patch_kids/display_avatars.js
83
+ - scripts/caveat_patch_kids/display_githubs.js
84
+ - scripts/caveat_patch_kids/embiggen_message_history.js
85
+ - scripts/caveat_patch_kids/stylize_diffs.js
86
+ - scripts/caveat_patch_kids/stylize_nagios.js
87
+ - scripts/caveat_patch_kids/unsupported/display_emoji.js
88
+ - scripts/caveat_patch_kids/unsupported/display_html.js
89
+ - scripts/caveat_patch_kids/unsupported/display_musics.js
90
+ - scripts/caveat_patch_kids/unsupported/display_newrelic_charts.js
91
+ - scripts/caveat_patch_kids/unsupported/display_stars.js
92
+ - scripts/caveat_patch_kids/unsupported/focus_scroll_hax.js
93
+ - scripts/caveat_patch_kids/unsupported/stylize_builds.js
94
+ - scripts/caveat_patch_kids/unsupported/stylize_commits_and_deploys.js
95
+ - scripts/caveat_patch_kids/unsupported/stylize_pivotal_tracker.js
96
+ - vendor/assets/md5.js
97
+ homepage: ''
98
+ licenses: []
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 1.8.23
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: CaveatPatchKids is a tool for generating, sharing, and maintaing caveatPatchor.js
121
+ files for use with Propane, powered by sprockets and other fun stuff
122
+ test_files: []
123
+ has_rdoc: