ruby-clean-css 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. data/.gitmodules +3 -0
  2. data/EXAMPLE.md +25 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +30 -0
  5. data/LICENSE +19 -0
  6. data/README.md +106 -0
  7. data/lib/javascript/clean-css/.gitignore +4 -0
  8. data/lib/javascript/clean-css/.jshintignore +3 -0
  9. data/lib/javascript/clean-css/.jshintrc +14 -0
  10. data/lib/javascript/clean-css/.travis.yml +11 -0
  11. data/lib/javascript/clean-css/History.md +556 -0
  12. data/lib/javascript/clean-css/LICENSE +19 -0
  13. data/lib/javascript/clean-css/README.md +218 -0
  14. data/lib/javascript/clean-css/bin/cleancss +157 -0
  15. data/lib/javascript/clean-css/index.js +1 -0
  16. data/lib/javascript/clean-css/lib/clean.js +426 -0
  17. data/lib/javascript/clean-css/lib/colors/hsl-to-hex.js +64 -0
  18. data/lib/javascript/clean-css/lib/colors/long-to-short-hex.js +12 -0
  19. data/lib/javascript/clean-css/lib/colors/rgb-to-hex.js +14 -0
  20. data/lib/javascript/clean-css/lib/colors/shortener.js +174 -0
  21. data/lib/javascript/clean-css/lib/images/url-rebase.js +32 -0
  22. data/lib/javascript/clean-css/lib/images/url-rewriter.js +60 -0
  23. data/lib/javascript/clean-css/lib/imports/inliner.js +319 -0
  24. data/lib/javascript/clean-css/lib/properties/optimizer.js +276 -0
  25. data/lib/javascript/clean-css/lib/properties/override-compactor.js +116 -0
  26. data/lib/javascript/clean-css/lib/properties/processable.js +859 -0
  27. data/lib/javascript/clean-css/lib/properties/scanner.js +20 -0
  28. data/lib/javascript/clean-css/lib/properties/shorthand-compactor.js +244 -0
  29. data/lib/javascript/clean-css/lib/properties/token.js +184 -0
  30. data/lib/javascript/clean-css/lib/properties/validator.js +140 -0
  31. data/lib/javascript/clean-css/lib/selectors/empty-removal.js +30 -0
  32. data/lib/javascript/clean-css/lib/selectors/optimizer.js +341 -0
  33. data/lib/javascript/clean-css/lib/selectors/tokenizer.js +168 -0
  34. data/lib/javascript/clean-css/lib/text/comments.js +83 -0
  35. data/lib/javascript/clean-css/lib/text/escape-store.js +32 -0
  36. data/lib/javascript/clean-css/lib/text/expressions.js +73 -0
  37. data/lib/javascript/clean-css/lib/text/free.js +26 -0
  38. data/lib/javascript/clean-css/lib/text/name-quotes.js +37 -0
  39. data/lib/javascript/clean-css/lib/text/quote-scanner.js +91 -0
  40. data/lib/javascript/clean-css/lib/text/splitter.js +35 -0
  41. data/lib/javascript/clean-css/lib/text/urls.js +41 -0
  42. data/lib/javascript/clean-css/package.json +50 -0
  43. data/lib/javascript/clean-css/test/batch-test.js +56 -0
  44. data/lib/javascript/clean-css/test/bench.js +11 -0
  45. data/lib/javascript/clean-css/test/binary-test.js +323 -0
  46. data/lib/javascript/clean-css/test/data-bench/_partial.css +1 -0
  47. data/lib/javascript/clean-css/test/data-bench/complex.css +4 -0
  48. data/lib/javascript/clean-css/test/data/129-assets/assets/ui.css +2 -0
  49. data/lib/javascript/clean-css/test/data/129-assets/components/bootstrap/css/bootstrap.css +3 -0
  50. data/lib/javascript/clean-css/test/data/129-assets/components/bootstrap/images/glyphs.gif +0 -0
  51. data/lib/javascript/clean-css/test/data/129-assets/components/jquery-ui/css/style.css +6 -0
  52. data/lib/javascript/clean-css/test/data/129-assets/components/jquery-ui/images/next.gif +0 -0
  53. data/lib/javascript/clean-css/test/data/129-assets/components/jquery-ui/images/prev.gif +0 -0
  54. data/lib/javascript/clean-css/test/data/960-min.css +125 -0
  55. data/lib/javascript/clean-css/test/data/960.css +602 -0
  56. data/lib/javascript/clean-css/test/data/big-min.css +2984 -0
  57. data/lib/javascript/clean-css/test/data/big.css +13794 -0
  58. data/lib/javascript/clean-css/test/data/blueprint-min.css +245 -0
  59. data/lib/javascript/clean-css/test/data/blueprint.css +556 -0
  60. data/lib/javascript/clean-css/test/data/charset-mixed-with-fonts-min.css +3 -0
  61. data/lib/javascript/clean-css/test/data/charset-mixed-with-fonts.css +14 -0
  62. data/lib/javascript/clean-css/test/data/font-awesome-ie7-min.css +392 -0
  63. data/lib/javascript/clean-css/test/data/font-awesome-ie7.css +1203 -0
  64. data/lib/javascript/clean-css/test/data/font-awesome-min.css +319 -0
  65. data/lib/javascript/clean-css/test/data/font-awesome.css +540 -0
  66. data/lib/javascript/clean-css/test/data/imports-min.css +5 -0
  67. data/lib/javascript/clean-css/test/data/imports.css +4 -0
  68. data/lib/javascript/clean-css/test/data/issue-117-snippet-min.css +3 -0
  69. data/lib/javascript/clean-css/test/data/issue-117-snippet.css +19 -0
  70. data/lib/javascript/clean-css/test/data/issue-159-snippet-min.css +7 -0
  71. data/lib/javascript/clean-css/test/data/issue-159-snippet.css +7 -0
  72. data/lib/javascript/clean-css/test/data/issue-192-min.css +1 -0
  73. data/lib/javascript/clean-css/test/data/issue-192.css +8 -0
  74. data/lib/javascript/clean-css/test/data/issue-198-min.css +3 -0
  75. data/lib/javascript/clean-css/test/data/issue-198.css +4 -0
  76. data/lib/javascript/clean-css/test/data/issue-232-min.css +2 -0
  77. data/lib/javascript/clean-css/test/data/issue-232.css +17 -0
  78. data/lib/javascript/clean-css/test/data/issue-241-min.css +2 -0
  79. data/lib/javascript/clean-css/test/data/issue-241.css +2 -0
  80. data/lib/javascript/clean-css/test/data/issue-304-min.css +1 -0
  81. data/lib/javascript/clean-css/test/data/issue-304.css +4 -0
  82. data/lib/javascript/clean-css/test/data/issue-305-min.css +1 -0
  83. data/lib/javascript/clean-css/test/data/issue-305.css +3 -0
  84. data/lib/javascript/clean-css/test/data/issue-308-min.css +1 -0
  85. data/lib/javascript/clean-css/test/data/issue-308.css +5 -0
  86. data/lib/javascript/clean-css/test/data/issue-312-min.css +1 -0
  87. data/lib/javascript/clean-css/test/data/issue-312.css +7 -0
  88. data/lib/javascript/clean-css/test/data/issue-337-min.css +1 -0
  89. data/lib/javascript/clean-css/test/data/issue-337.css +4 -0
  90. data/lib/javascript/clean-css/test/data/line-breaks-in-attributes-min.css +2 -0
  91. data/lib/javascript/clean-css/test/data/line-breaks-in-attributes.css +8 -0
  92. data/lib/javascript/clean-css/test/data/partials-absolute/base.css +3 -0
  93. data/lib/javascript/clean-css/test/data/partials-absolute/base2.css +1 -0
  94. data/lib/javascript/clean-css/test/data/partials-absolute/extra/sub.css +3 -0
  95. data/lib/javascript/clean-css/test/data/partials-relative/base.css +3 -0
  96. data/lib/javascript/clean-css/test/data/partials-relative/extra/included.css +1 -0
  97. data/lib/javascript/clean-css/test/data/partials/comment.css +2 -0
  98. data/lib/javascript/clean-css/test/data/partials/extra/down.gif +0 -0
  99. data/lib/javascript/clean-css/test/data/partials/extra/four.css +3 -0
  100. data/lib/javascript/clean-css/test/data/partials/extra/three.css +1 -0
  101. data/lib/javascript/clean-css/test/data/partials/five.css +1 -0
  102. data/lib/javascript/clean-css/test/data/partials/four.css +1 -0
  103. data/lib/javascript/clean-css/test/data/partials/one.css +1 -0
  104. data/lib/javascript/clean-css/test/data/partials/three.css +1 -0
  105. data/lib/javascript/clean-css/test/data/partials/two.css +5 -0
  106. data/lib/javascript/clean-css/test/data/reset-min.css +12 -0
  107. data/lib/javascript/clean-css/test/data/reset.css +64 -0
  108. data/lib/javascript/clean-css/test/data/sample1-min.css +4 -0
  109. data/lib/javascript/clean-css/test/data/sample1.css +12 -0
  110. data/lib/javascript/clean-css/test/data/unsupported/selectors-ie7.css +20 -0
  111. data/lib/javascript/clean-css/test/data/unsupported/selectors-ie8.css +17 -0
  112. data/lib/javascript/clean-css/test/module-test.js +185 -0
  113. data/lib/javascript/clean-css/test/protocol-imports-test.js +409 -0
  114. data/lib/javascript/clean-css/test/text/splitter-test.js +20 -0
  115. data/lib/javascript/clean-css/test/unit-test.js +2071 -0
  116. data/lib/ruby-clean-css.rb +6 -0
  117. data/lib/ruby-clean-css/compressor.rb +142 -0
  118. data/lib/ruby-clean-css/exports.rb +258 -0
  119. data/lib/ruby-clean-css/railtie.rb +27 -0
  120. data/lib/ruby-clean-css/sprockets.rb +19 -0
  121. data/lib/ruby-clean-css/version.rb +5 -0
  122. data/ruby-clean-css.gemspec +30 -0
  123. data/test/test_compressor.rb +84 -0
  124. metadata +203 -0
@@ -0,0 +1,83 @@
1
+ var EscapeStore = require('./escape-store');
2
+ var QuoteScanner = require('./quote-scanner');
3
+
4
+ module.exports = function Comments(keepSpecialComments, keepBreaks, lineBreak) {
5
+ var comments = new EscapeStore('COMMENT');
6
+
7
+ return {
8
+ // Strip special comments (/*! ... */) by replacing them by a special marker
9
+ // for further restoring. Plain comments are removed. It's done by scanning data using
10
+ // String#indexOf scanning instead of regexps to speed up the process.
11
+ escape: function(data) {
12
+ var tempData = [];
13
+ var nextStart = 0;
14
+ var nextEnd = 0;
15
+ var cursor = 0;
16
+ var isQuotedAt = (function () {
17
+ var quoteMap = [];
18
+ new QuoteScanner(data).each(function (quotedString, _, startsAt) {
19
+ quoteMap.push([startsAt, startsAt + quotedString.length]);
20
+ });
21
+
22
+ return function (position) {
23
+ for (var i = 0, l = quoteMap.length; i < l; i++) {
24
+ if (quoteMap[i][0] < position && quoteMap[i][1] > position)
25
+ return true;
26
+ }
27
+
28
+ return false;
29
+ };
30
+ })();
31
+
32
+ for (; nextEnd < data.length;) {
33
+ nextStart = data.indexOf('/*', cursor);
34
+ if (nextStart == -1)
35
+ break;
36
+ if (isQuotedAt(nextStart)) {
37
+ tempData.push(data.substring(cursor, nextStart + 2));
38
+ cursor = nextStart + 2;
39
+ continue;
40
+ }
41
+
42
+ nextEnd = data.indexOf('*/', nextStart + 2);
43
+ if (nextEnd == -1)
44
+ break;
45
+
46
+ tempData.push(data.substring(cursor, nextStart));
47
+ if (data[nextStart + 2] == '!') {
48
+ // in case of special comments, replace them with a placeholder
49
+ var comment = data.substring(nextStart, nextEnd + 2);
50
+ var placeholder = comments.store(comment);
51
+ tempData.push(placeholder);
52
+ }
53
+ cursor = nextEnd + 2;
54
+ }
55
+
56
+ return tempData.length > 0 ?
57
+ tempData.join('') + data.substring(cursor, data.length) :
58
+ data;
59
+ },
60
+
61
+ restore: function(data) {
62
+ var restored = 0;
63
+ var breakSuffix = keepBreaks ? lineBreak : '';
64
+
65
+ return data.replace(new RegExp(comments.placeholderPattern + '(' + lineBreak + '| )?', 'g'), function(match, placeholder) {
66
+ restored++;
67
+
68
+ switch (keepSpecialComments) {
69
+ case '*':
70
+ return comments.restore(placeholder) + breakSuffix;
71
+ case 1:
72
+ case '1':
73
+ return restored == 1 ?
74
+ comments.restore(placeholder) + breakSuffix :
75
+ '';
76
+ case 0:
77
+ case '0':
78
+ return '';
79
+ }
80
+ });
81
+ }
82
+ };
83
+ };
@@ -0,0 +1,32 @@
1
+ module.exports = function EscapeStore(placeholderRoot) {
2
+ placeholderRoot = 'ESCAPED_' + placeholderRoot + '_CLEAN_CSS';
3
+
4
+ var placeholderToData = {};
5
+ var dataToPlaceholder = {};
6
+ var count = 0;
7
+ var nextPlaceholder = function() {
8
+ return '__' + placeholderRoot + (count++) + '__';
9
+ };
10
+ var pattern = '(__' + placeholderRoot + '\\d{1,}__)';
11
+
12
+ return {
13
+ placeholderPattern: pattern,
14
+
15
+ placeholderRegExp: new RegExp(pattern, 'g'),
16
+
17
+ store: function(data) {
18
+ var placeholder = dataToPlaceholder[data];
19
+ if (!placeholder) {
20
+ placeholder = nextPlaceholder();
21
+ placeholderToData[placeholder] = data;
22
+ dataToPlaceholder[data] = placeholder;
23
+ }
24
+
25
+ return placeholder;
26
+ },
27
+
28
+ restore: function(placeholder) {
29
+ return placeholderToData[placeholder];
30
+ }
31
+ };
32
+ };
@@ -0,0 +1,73 @@
1
+ var EscapeStore = require('./escape-store');
2
+
3
+ module.exports = function Expressions() {
4
+ var expressions = new EscapeStore('EXPRESSION');
5
+
6
+ var findEnd = function(data, start) {
7
+ var end = start + 'expression'.length;
8
+ var level = 0;
9
+ var quoted = false;
10
+
11
+ while (true) {
12
+ var next = data[end++];
13
+
14
+ if (quoted) {
15
+ quoted = next != '\'' && next != '"';
16
+ } else {
17
+ quoted = next == '\'' || next == '"';
18
+
19
+ if (next == '(')
20
+ level++;
21
+ if (next == ')')
22
+ level--;
23
+ if (next == '}' && level == 1) {
24
+ end--;
25
+ level--;
26
+ }
27
+ }
28
+
29
+ if (level === 0 && next == ')')
30
+ break;
31
+ if (!next) {
32
+ end = data.substring(0, end).lastIndexOf('}');
33
+ break;
34
+ }
35
+ }
36
+
37
+ return end;
38
+ };
39
+
40
+ return {
41
+ // Escapes expressions by replacing them by a special
42
+ // marker for further restoring. It's done via string scanning
43
+ // instead of regexps to speed up the process.
44
+ escape: function(data) {
45
+ var nextStart = 0;
46
+ var nextEnd = 0;
47
+ var cursor = 0;
48
+ var tempData = [];
49
+
50
+ for (; nextEnd < data.length;) {
51
+ nextStart = data.indexOf('expression(', nextEnd);
52
+ if (nextStart == -1)
53
+ break;
54
+
55
+ nextEnd = findEnd(data, nextStart);
56
+
57
+ var expression = data.substring(nextStart, nextEnd);
58
+ var placeholder = expressions.store(expression);
59
+ tempData.push(data.substring(cursor, nextStart));
60
+ tempData.push(placeholder);
61
+ cursor = nextEnd;
62
+ }
63
+
64
+ return tempData.length > 0 ?
65
+ tempData.join('') + data.substring(cursor, data.length) :
66
+ data;
67
+ },
68
+
69
+ restore: function(data) {
70
+ return data.replace(expressions.placeholderRegExp, expressions.restore);
71
+ }
72
+ };
73
+ };
@@ -0,0 +1,26 @@
1
+ (function() {
2
+ var EscapeStore = require('./escape-store');
3
+ var QuoteScanner = require('./quote-scanner');
4
+
5
+ var Free = function Free() {
6
+ this.matches = new EscapeStore('FREE_TEXT');
7
+ };
8
+
9
+ // Strip content tags by replacing them by the a special
10
+ // marker for further restoring. It's done via string scanning
11
+ // instead of regexps to speed up the process.
12
+ Free.prototype.escape = function(data) {
13
+ var self = this;
14
+
15
+ return new QuoteScanner(data).each(function(match, store) {
16
+ var placeholder = self.matches.store(match);
17
+ store.push(placeholder);
18
+ });
19
+ };
20
+
21
+ Free.prototype.restore = function(data) {
22
+ return data.replace(this.matches.placeholderRegExp, this.matches.restore);
23
+ };
24
+
25
+ module.exports = Free;
26
+ })();
@@ -0,0 +1,37 @@
1
+ (function() {
2
+ var QuoteScanner = require('./quote-scanner');
3
+ var PropertyScanner = require('../properties/scanner');
4
+
5
+ var NameQuotes = function NameQuotes() {};
6
+
7
+ var STRIPPABLE = /^['"][a-zA-Z][a-zA-Z\d\-_]+['"]$/;
8
+
9
+ var properties = [
10
+ 'animation',
11
+ '-moz-animation',
12
+ '-o-animation',
13
+ '-webkit-animation',
14
+ 'animation-name',
15
+ '-moz-animation-name',
16
+ '-o-animation-name',
17
+ '-webkit-animation-name',
18
+ 'font',
19
+ 'font-family'
20
+ ];
21
+
22
+ NameQuotes.prototype.process = function(data) {
23
+ var scanner = new PropertyScanner(data);
24
+
25
+ return new QuoteScanner(data).each(function(match, store, cursor) {
26
+ var lastProperty = scanner.nextAt(cursor);
27
+ if (properties.indexOf(lastProperty) > -1) {
28
+ if (STRIPPABLE.test(match))
29
+ match = match.substring(1, match.length - 1);
30
+ }
31
+
32
+ store.push(match);
33
+ });
34
+ };
35
+
36
+ module.exports = NameQuotes;
37
+ })();
@@ -0,0 +1,91 @@
1
+ (function() {
2
+ var QuoteScanner = function QuoteScanner(data) {
3
+ this.data = data;
4
+ };
5
+
6
+ var findQuoteEnd = function(data, matched, cursor, oldCursor) {
7
+ var commentStartMark = '/*';
8
+ var commentEndMark = '*/';
9
+ var escapeMark = '\\';
10
+ var blockEndMark = '}';
11
+ var dataPrefix = data.substring(oldCursor, cursor);
12
+ var commentEndedAt = dataPrefix.lastIndexOf(commentEndMark, cursor);
13
+ var commentStartedAt = dataPrefix.lastIndexOf(commentStartMark, cursor);
14
+ var commentStarted = false;
15
+
16
+ if (commentEndedAt >= cursor && commentStartedAt > -1)
17
+ commentStarted = true;
18
+ if (commentStartedAt < cursor && commentStartedAt > commentEndedAt)
19
+ commentStarted = true;
20
+
21
+ if (commentStarted) {
22
+ var commentEndsAt = data.indexOf(commentEndMark, cursor);
23
+ if (commentEndsAt > -1)
24
+ return commentEndsAt;
25
+
26
+ commentEndsAt = data.indexOf(blockEndMark, cursor);
27
+ return commentEndsAt > -1 ? commentEndsAt - 1 : data.length;
28
+ }
29
+
30
+ while (true) {
31
+ if (data[cursor] === undefined)
32
+ break;
33
+ if (data[cursor] == matched && data[cursor - 1] != escapeMark)
34
+ break;
35
+
36
+ cursor++;
37
+ }
38
+
39
+ return cursor;
40
+ };
41
+
42
+ QuoteScanner.prototype.each = function(callback) {
43
+ var data = this.data;
44
+ var tempData = [];
45
+ var nextStart = 0;
46
+ var nextEnd = 0;
47
+ var cursor = 0;
48
+ var matchedMark = null;
49
+ var singleMark = '\'';
50
+ var doubleMark = '"';
51
+ var dataLength = data.length;
52
+
53
+ for (; nextEnd < data.length;) {
54
+ var nextStartSingle = data.indexOf(singleMark, nextEnd + 1);
55
+ var nextStartDouble = data.indexOf(doubleMark, nextEnd + 1);
56
+
57
+ if (nextStartSingle == -1)
58
+ nextStartSingle = dataLength;
59
+ if (nextStartDouble == -1)
60
+ nextStartDouble = dataLength;
61
+
62
+ if (nextStartSingle < nextStartDouble) {
63
+ nextStart = nextStartSingle;
64
+ matchedMark = singleMark;
65
+ } else {
66
+ nextStart = nextStartDouble;
67
+ matchedMark = doubleMark;
68
+ }
69
+
70
+ if (nextStart == -1)
71
+ break;
72
+
73
+ nextEnd = findQuoteEnd(data, matchedMark, nextStart + 1, cursor);
74
+ if (nextEnd == -1)
75
+ break;
76
+
77
+ var text = data.substring(nextStart, nextEnd + 1);
78
+ tempData.push(data.substring(cursor, nextStart));
79
+ if (text.length > 0)
80
+ callback(text, tempData, nextStart);
81
+
82
+ cursor = nextEnd + 1;
83
+ }
84
+
85
+ return tempData.length > 0 ?
86
+ tempData.join('') + data.substring(cursor, data.length) :
87
+ data;
88
+ };
89
+
90
+ module.exports = QuoteScanner;
91
+ })();
@@ -0,0 +1,35 @@
1
+ var Splitter = function Splitter (separator) {
2
+ this.separator = separator;
3
+ };
4
+
5
+ Splitter.prototype.split = function (value) {
6
+ if (value.indexOf(this.separator) === -1)
7
+ return [value];
8
+
9
+ if (value.indexOf('(') === -1)
10
+ return value.split(this.separator);
11
+
12
+ var level = 0;
13
+ var cursor = 0;
14
+ var lastStart = 0;
15
+ var len = value.length;
16
+ var tokens = [];
17
+
18
+ while (cursor++ < len) {
19
+ if (value[cursor] == '(') {
20
+ level++;
21
+ } else if (value[cursor] == ')') {
22
+ level--;
23
+ } else if (value[cursor] == this.separator && level === 0) {
24
+ tokens.push(value.substring(lastStart, cursor));
25
+ lastStart = cursor + 1;
26
+ }
27
+ }
28
+
29
+ if (lastStart < cursor + 1)
30
+ tokens.push(value.substring(lastStart));
31
+
32
+ return tokens;
33
+ };
34
+
35
+ module.exports = Splitter;
@@ -0,0 +1,41 @@
1
+ var EscapeStore = require('./escape-store');
2
+
3
+ module.exports = function Urls() {
4
+ var urls = new EscapeStore('URL');
5
+
6
+ return {
7
+ // Strip urls by replacing them by a special
8
+ // marker for further restoring. It's done via string scanning
9
+ // instead of regexps to speed up the process.
10
+ escape: function(data) {
11
+ var nextStart = 0;
12
+ var nextEnd = 0;
13
+ var cursor = 0;
14
+ var tempData = [];
15
+
16
+ for (; nextEnd < data.length;) {
17
+ nextStart = data.indexOf('url(', nextEnd);
18
+ if (nextStart == -1)
19
+ break;
20
+
21
+ nextEnd = data.indexOf(')', nextStart);
22
+
23
+ var url = data.substring(nextStart, nextEnd + 1);
24
+ var placeholder = urls.store(url);
25
+ tempData.push(data.substring(cursor, nextStart));
26
+ tempData.push(placeholder);
27
+ cursor = nextEnd + 1;
28
+ }
29
+
30
+ return tempData.length > 0 ?
31
+ tempData.join('') + data.substring(cursor, data.length) :
32
+ data;
33
+ },
34
+
35
+ restore: function(data) {
36
+ return data.replace(urls.placeholderRegExp, function(placeholder) {
37
+ return urls.restore(placeholder).replace(/\s/g, '');
38
+ });
39
+ }
40
+ };
41
+ };
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "clean-css",
3
+ "version": "2.2.13",
4
+ "author": "Jakub Pawlowicz <jakub@goalsmashers.com> (http://twitter.com/GoalSmashers)",
5
+ "description": "A well-tested CSS minifier",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "css",
9
+ "minifier"
10
+ ],
11
+ "homepage": "https://github.com/GoalSmashers/clean-css",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/GoalSmashers/clean-css.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/GoalSmashers/clean-css/issues"
18
+ },
19
+ "bin": {
20
+ "cleancss": "./bin/cleancss"
21
+ },
22
+ "main": "index.js",
23
+ "files": [
24
+ "bin",
25
+ "lib",
26
+ "History.md",
27
+ "index.js",
28
+ "LICENSE"
29
+ ],
30
+ "scripts": {
31
+ "browserify": "browserify --standalone CleanCSS index.js | uglifyjs --compress --mangle -o cleancss-browser.js",
32
+ "bench": "node ./test/bench.js",
33
+ "check": "jshint ./bin/cleancss .",
34
+ "prepublish": "jshint .",
35
+ "test": "vows"
36
+ },
37
+ "dependencies": {
38
+ "commander": "2.3.x"
39
+ },
40
+ "devDependencies": {
41
+ "browserify": "5.x",
42
+ "jshint": "2.5.x",
43
+ "nock": "0.28.x",
44
+ "uglify-js": "2.4.x",
45
+ "vows": "0.7.x"
46
+ },
47
+ "engines": {
48
+ "node": ">=0.8.0"
49
+ }
50
+ }