grimen-packr 3.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +20 -0
- data/README.rdoc +108 -0
- data/bin/packr +97 -0
- data/lib/packr.rb +55 -0
- data/lib/packr/base62.rb +150 -0
- data/lib/packr/collection.rb +147 -0
- data/lib/packr/encoder.rb +35 -0
- data/lib/packr/engine.rb +20 -0
- data/lib/packr/map.rb +66 -0
- data/lib/packr/minifier.rb +80 -0
- data/lib/packr/parser.rb +21 -0
- data/lib/packr/privates.rb +19 -0
- data/lib/packr/regexp_group.rb +122 -0
- data/lib/packr/shrinker.rb +123 -0
- data/lib/packr/words.rb +39 -0
- data/test/assets/packed/controls.js +1 -0
- data/test/assets/packed/domready.js +1 -0
- data/test/assets/packed/dragdrop.js +1 -0
- data/test/assets/packed/effects.js +1 -0
- data/test/assets/packed/prototype.js +1 -0
- data/test/assets/packed/prototype_shrunk.js +1 -0
- data/test/assets/packed/selector.js +1 -0
- data/test/assets/src/controls.js +833 -0
- data/test/assets/src/domready.js +36 -0
- data/test/assets/src/dragdrop.js +942 -0
- data/test/assets/src/effects.js +1088 -0
- data/test/assets/src/prototype.js +2515 -0
- data/test/assets/src/selector.js +666 -0
- data/test/assets/test/controls.js +1 -0
- data/test/assets/test/domready.js +1 -0
- data/test/assets/test/dragdrop.js +1 -0
- data/test/assets/test/effects.js +1 -0
- data/test/assets/test/prototype.js +1 -0
- data/test/assets/test/prototype_shrunk.js +1 -0
- data/test/assets/test/selector.js +1 -0
- data/test/test_packr.rb +156 -0
- metadata +139 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
module Packr
|
2
|
+
class Encoder
|
3
|
+
|
4
|
+
def initialize(pattern = nil, encoder = nil, ignore = nil)
|
5
|
+
@parser = Parser.new(ignore)
|
6
|
+
@parser.put(pattern, "") if pattern
|
7
|
+
@encoder = encoder
|
8
|
+
end
|
9
|
+
|
10
|
+
def search(script)
|
11
|
+
words = Words.new
|
12
|
+
@parser.put_at(-1, lambda { |word, *args|
|
13
|
+
words.add(word)
|
14
|
+
})
|
15
|
+
@parser.exec(script)
|
16
|
+
words
|
17
|
+
end
|
18
|
+
|
19
|
+
def encode(script)
|
20
|
+
words = search(script)
|
21
|
+
words.sort!
|
22
|
+
index = 0
|
23
|
+
words.each do |word, key|
|
24
|
+
word.encoded = @encoder.call(index)
|
25
|
+
index += 1
|
26
|
+
end
|
27
|
+
@parser.put_at(-1, lambda { |word, *args|
|
28
|
+
words.get(word).encoded
|
29
|
+
})
|
30
|
+
@parser.exec(script)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
data/lib/packr/engine.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Packr
|
2
|
+
class Engine
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@minifier = Minifier.new
|
6
|
+
@shrinker = Shrinker.new
|
7
|
+
@privates = Privates.new
|
8
|
+
@base62 = Base62.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def pack(script, options = {})
|
12
|
+
script = @minifier.minify(script)
|
13
|
+
script = @shrinker.shrink(script, options[:protect]) if options[:shrink_vars]
|
14
|
+
script = @privates.encode(script) if options[:private]
|
15
|
+
script = @base62.encode(script) if options[:base62]
|
16
|
+
script
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
data/lib/packr/map.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module Packr
|
2
|
+
# This is effectively a wrapper for Hash instances - we're including it
|
3
|
+
# to maintain similarity with the JavaScript version for easier maintainance.
|
4
|
+
class Map
|
5
|
+
|
6
|
+
def initialize(values = nil)
|
7
|
+
@values = {}
|
8
|
+
merge(values) unless values.nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
def clear
|
12
|
+
@values.clear
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy
|
16
|
+
self.class.new(@values)
|
17
|
+
end
|
18
|
+
|
19
|
+
def each
|
20
|
+
@values.each { |key, value| yield(value, key) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(key)
|
24
|
+
@values[key.to_s]
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_keys
|
28
|
+
@values.keys
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_values
|
32
|
+
@values.values
|
33
|
+
end
|
34
|
+
|
35
|
+
def has?(key)
|
36
|
+
@values.has_key?(key.to_s)
|
37
|
+
end
|
38
|
+
|
39
|
+
def merge(*args)
|
40
|
+
args.each do |values|
|
41
|
+
values = values.get_values if values.is_a?(Map)
|
42
|
+
values.each { |key, value| put(key, value) }
|
43
|
+
end
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove(key)
|
48
|
+
@values.delete(key.to_s)
|
49
|
+
end
|
50
|
+
|
51
|
+
def put(key, value = nil)
|
52
|
+
value ||= key
|
53
|
+
# Create the new entry (or overwrite the old entry).
|
54
|
+
@values[key.to_s] = value
|
55
|
+
end
|
56
|
+
|
57
|
+
def size
|
58
|
+
@values.length
|
59
|
+
end
|
60
|
+
|
61
|
+
def union(*values)
|
62
|
+
copy.merge(*values)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Packr
|
2
|
+
class Minifier
|
3
|
+
|
4
|
+
def self.conditional_comments
|
5
|
+
@@conditional_comments
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@concat = Packr::CONCAT.union(DATA)
|
10
|
+
|
11
|
+
def @concat.exec(script)
|
12
|
+
parsed = super(script)
|
13
|
+
while parsed != script
|
14
|
+
script = parsed
|
15
|
+
parsed = super(script)
|
16
|
+
end
|
17
|
+
parsed
|
18
|
+
end
|
19
|
+
|
20
|
+
@comments = DATA.union(COMMENTS)
|
21
|
+
@clean = DATA.union(CLEAN)
|
22
|
+
@whitespace = DATA.union(WHITESPACE)
|
23
|
+
|
24
|
+
@@conditional_comments = @comments.copy
|
25
|
+
@@conditional_comments.put_at(-1, " \\3")
|
26
|
+
@whitespace.remove_at(2) # conditional comments
|
27
|
+
@comments.remove_at(2)
|
28
|
+
end
|
29
|
+
|
30
|
+
def minify(script)
|
31
|
+
# packing with no additional options
|
32
|
+
script += "\n"
|
33
|
+
script = script.gsub(CONTINUE, "")
|
34
|
+
script = @comments.exec(script)
|
35
|
+
script = @clean.exec(script)
|
36
|
+
script = @whitespace.exec(script)
|
37
|
+
script = @concat.exec(script)
|
38
|
+
script
|
39
|
+
end
|
40
|
+
|
41
|
+
CONTINUE = /\\\r?\n/
|
42
|
+
|
43
|
+
CLEAN = Parser.new.
|
44
|
+
put("\\(\\s*([^;)]*)\\s*;\\s*([^;)]*)\\s*;\\s*([^;)]*)\\)", "(\\1;\\2;\\3)"). # for (;;) loops
|
45
|
+
put("throw[^};]+[};]", IGNORE). # a safari 1.3 bug
|
46
|
+
put(";+\\s*([};])", "\\1")
|
47
|
+
|
48
|
+
COMMENTS = Parser.new.
|
49
|
+
put(";;;[^\\n]*\\n", REMOVE).
|
50
|
+
put("(COMMENT1)\\n\\s*(REGEXP)?", "\n\\3").
|
51
|
+
put("(COMMENT2)\\s*(REGEXP)?", lambda do |*args|
|
52
|
+
match, comment, b, regexp = args[0..3]
|
53
|
+
if comment =~ /^\/\*@/ and comment =~ /@\*\/$/
|
54
|
+
# comments = Minifier.conditional_comments.exec(comment)
|
55
|
+
else
|
56
|
+
comment = ""
|
57
|
+
end
|
58
|
+
comment + " " + (regexp || "")
|
59
|
+
end)
|
60
|
+
|
61
|
+
Packr::CONCAT = Parser.new.
|
62
|
+
put("(STRING1)\\+(STRING1)", lambda { |*args| args[1][0...-1] + args[3][1..-1] }).
|
63
|
+
put("(STRING2)\\+(STRING2)", lambda { |*args| args[1][0...-1] + args[3][1..-1] })
|
64
|
+
|
65
|
+
WHITESPACE = Parser.new.
|
66
|
+
put("/\\/\\/@[^\\n]*\\n", IGNORE).
|
67
|
+
put("@\\s+\\b", "@ "). # protect conditional comments
|
68
|
+
put("\\b\\s+@", " @").
|
69
|
+
put("(\\d)\\s+(\\.\\s*[a-z\\$_\\[(])", "\\1 \\2"). # http://dean.edwards.name/weblog/2007/04/packer3/#comment84066
|
70
|
+
put("([+-])\\s+([+-])", "\\1 \\2"). # c = a++ +b;
|
71
|
+
put("\\b\\s+\\$\\s+\\b", " $ "). # var $ in
|
72
|
+
put("\\$\\s+\\b", "$ "). # object$ in
|
73
|
+
put("\\b\\s+\\$", " $"). # return $object
|
74
|
+
# put("\\b\\s+#", " #"). # CSS
|
75
|
+
put("\\b\\s+\\b", SPACE).
|
76
|
+
put("\\s+", REMOVE)
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
data/lib/packr/parser.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Packr
|
2
|
+
class Parser < RegexpGroup
|
3
|
+
|
4
|
+
def put(expression, replacement)
|
5
|
+
expression = DICTIONARY.exec(expression) if expression.is_a?(String)
|
6
|
+
super(expression, replacement)
|
7
|
+
end
|
8
|
+
|
9
|
+
# STRING1 requires backslashes to fix concat bug
|
10
|
+
DICTIONARY = RegexpGroup.new.
|
11
|
+
put(:OPERATOR, /return|typeof|[\[(\^=,{}:;&|!*?]/.source).
|
12
|
+
put(:CONDITIONAL, /\/\*@\w*|\w*@\*\/|\/\/@\w*|@\w+/.source).
|
13
|
+
put(:COMMENT1, /\/\/[^\n]*/.source).
|
14
|
+
put(:COMMENT2, /\/\*[^*]*\*+([^\/][^*]*\*+)*\//.source).
|
15
|
+
put(:REGEXP, /\/(\\[\/\\]|[^*\/])(\\.|[^\/\n\\])*\/[gim]*/.source).
|
16
|
+
put(:STRING1, /\'(\\.|[^\'\\])*\'/.source).
|
17
|
+
put(:STRING2, /"(\\.|[^"\\])*"/.source)
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Packr
|
2
|
+
class Privates < Encoder
|
3
|
+
|
4
|
+
IGNORE = {
|
5
|
+
:CONDITIONAL => Packr::IGNORE,
|
6
|
+
"(OPERATOR)(REGXEP)" => Packr::IGNORE
|
7
|
+
}
|
8
|
+
|
9
|
+
PATTERN = /\b_[\da-zA-Z$][\w$]*\b/
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super(PATTERN, lambda { |index|
|
13
|
+
"_" + Packr.encode62(index)
|
14
|
+
}, IGNORE)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Packr
|
2
|
+
class RegexpGroup < Collection
|
3
|
+
|
4
|
+
IGNORE = "\\0"
|
5
|
+
BACK_REF = /\\(\d+)/
|
6
|
+
ESCAPE_CHARS = /\\./
|
7
|
+
ESCAPE_BRACKETS = /\(\?[:=!]|\[[^\]]+\]/
|
8
|
+
BRACKETS = /\(/
|
9
|
+
LOOKUP = /\\(\d+)/
|
10
|
+
LOOKUP_SIMPLE = /^\\\d+$/
|
11
|
+
|
12
|
+
def initialize(values = nil, ignore_case = false)
|
13
|
+
super(values)
|
14
|
+
@ignore_case = !!ignore_case
|
15
|
+
end
|
16
|
+
|
17
|
+
def exec(string, override = nil)
|
18
|
+
string = string.to_s # type-safe
|
19
|
+
return string if @keys.empty?
|
20
|
+
override = 0 if override == IGNORE
|
21
|
+
string.gsub(Regexp.new(self.to_s, @ignore_case && Regexp::IGNORECASE)) do |match|
|
22
|
+
offset, i, result = 1, 0, match
|
23
|
+
arguments = [match] + $~.captures + [$~.begin(0), string]
|
24
|
+
# Loop through the items.
|
25
|
+
each do |item, key|
|
26
|
+
nxt = offset + item.length + 1
|
27
|
+
if arguments[offset] # do we have a result?
|
28
|
+
replacement = override.nil? ? item.replacement : override
|
29
|
+
case replacement
|
30
|
+
when Proc
|
31
|
+
result = replacement.call(*arguments[offset...nxt])
|
32
|
+
when Numeric
|
33
|
+
result = arguments[offset + replacement]
|
34
|
+
else
|
35
|
+
result = replacement
|
36
|
+
end
|
37
|
+
end
|
38
|
+
offset = nxt
|
39
|
+
end
|
40
|
+
result
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def insert_at(index, expression, replacement)
|
45
|
+
expression = expression.is_a?(Regexp) ? expression.source : expression.to_s
|
46
|
+
super(index, expression, replacement)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test(string)
|
50
|
+
exec(string) != string
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
offset = 1
|
55
|
+
"(" + map { |item, key|
|
56
|
+
# Fix back references.
|
57
|
+
expression = item.to_s.gsub(BACK_REF) { |m| "\\" + (offset + $1.to_i) }
|
58
|
+
offset += item.length + 1
|
59
|
+
expression
|
60
|
+
}.join(")|(") + ")"
|
61
|
+
end
|
62
|
+
|
63
|
+
class Item
|
64
|
+
attr_accessor :expression, :length, :replacement
|
65
|
+
|
66
|
+
def initialize(expression, replacement = nil)
|
67
|
+
@expression = expression
|
68
|
+
|
69
|
+
if replacement.nil?
|
70
|
+
replacement = IGNORE
|
71
|
+
elsif replacement.respond_to?(:replacement)
|
72
|
+
replacement = replacement.replacement
|
73
|
+
elsif !replacement.is_a?(Proc)
|
74
|
+
replacement = replacement.to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
# does the pattern use sub-expressions?
|
78
|
+
if replacement.is_a?(String) and replacement =~ LOOKUP
|
79
|
+
# a simple lookup? (e.g. "\2")
|
80
|
+
if replacement.gsub(/\n/, " ") =~ LOOKUP_SIMPLE
|
81
|
+
# store the index (used for fast retrieval of matched strings)
|
82
|
+
replacement = replacement[1..-1].to_i
|
83
|
+
else # a complicated lookup (e.g. "Hello \2 \1")
|
84
|
+
# build a function to do the lookup
|
85
|
+
# Improved version by Alexei Gorkov:
|
86
|
+
q = '"'
|
87
|
+
replacement_string = replacement.
|
88
|
+
gsub(/\\/, "\\\\").
|
89
|
+
gsub(/"/, "\\x22").
|
90
|
+
gsub(/\n/, "\\n").
|
91
|
+
gsub(/\r/, "\\r").
|
92
|
+
gsub(/\\(\d+)/, q + "+(args[\\1]||" + q+q + ")+" + q).
|
93
|
+
gsub(/(['"])\1\+(.*)\+\1\1$/, '\1')
|
94
|
+
replacement = lambda { |*args| eval(q + replacement_string + q) }
|
95
|
+
|
96
|
+
# My old crappy version:
|
97
|
+
# q = (replacement.gsub(/\\./, "") =~ /'/) ? '"' : "'"
|
98
|
+
# replacement = replacement.gsub(/\r/, "\\r").gsub(/\\(\d+)/,
|
99
|
+
# q + "+(args[\\1]||" + q+q + ")+" + q)
|
100
|
+
# replacement_string = q + replacement.gsub(/(['"])\1\+(.*)\+\1\1$/, '\1') + q
|
101
|
+
# replacement = lambda { |*args| eval(replacement_string) }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
@length = RegexpGroup.count(@expression)
|
106
|
+
@replacement = replacement
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_s
|
110
|
+
@expression.respond_to?(:source) ? @expression.source : @expression.to_s
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.count(expression)
|
115
|
+
# Count the number of sub-expressions in a Regexp/RegexpGroup::Item.
|
116
|
+
expression = expression.to_s.gsub(ESCAPE_CHARS, "").gsub(ESCAPE_BRACKETS, "")
|
117
|
+
expression.scan(BRACKETS).length
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Packr
|
2
|
+
class Shrinker
|
3
|
+
|
4
|
+
ENCODED_DATA = /~\^(\d+)\^~/
|
5
|
+
PREFIX = '@'
|
6
|
+
SHRUNK = /\@\d+\b/
|
7
|
+
|
8
|
+
def decode_data(script)
|
9
|
+
# put strings and regular expressions back
|
10
|
+
script.gsub(ENCODED_DATA) { |match| @strings[$1.to_i] }
|
11
|
+
end
|
12
|
+
|
13
|
+
def encode_data(script)
|
14
|
+
# encode strings and regular expressions
|
15
|
+
@strings = [] # encoded strings and regular expressions
|
16
|
+
DATA.exec(script, lambda { |match, *args|
|
17
|
+
operator, regexp = args[0].to_s, args[1].to_s
|
18
|
+
replacement = "~^#{@strings.length}^~"
|
19
|
+
unless regexp.empty?
|
20
|
+
replacement = operator + replacement
|
21
|
+
match = regexp
|
22
|
+
end
|
23
|
+
@strings << match
|
24
|
+
replacement
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
def shrink(script, protected_names = [])
|
29
|
+
script = encode_data(script)
|
30
|
+
protected_names ||= []
|
31
|
+
protected_names = protected_names.map { |s| s.to_s }
|
32
|
+
|
33
|
+
# identify blocks, particularly identify function blocks (which define scope)
|
34
|
+
__block = /((catch|do|if|while|with|function)\b[^~{};]*(\(\s*[^{};]*\s*\))\s*)?(\{[^{}]*\})/
|
35
|
+
__brackets = /\{[^{}]*\}|\[[^\[\]]*\]|\([^\(\)]*\)|~[^~]+~/
|
36
|
+
__encoded_block = /~#?(\d+)~/
|
37
|
+
__identifier = /[a-zA-Z_$][\w\$]*/
|
38
|
+
__scoped = /~#(\d+)~/
|
39
|
+
__var = /\bvar\b/
|
40
|
+
__vars = /\bvar\s+[\w$]+[^;#]*|\bfunction\s+[\w$]+/
|
41
|
+
__var_tidy = /\b(var|function)\b|\sin\s+[^;]+/
|
42
|
+
__var_equal = /\s*=[^,;]*/
|
43
|
+
|
44
|
+
blocks = [] # store program blocks (anything between braces {})
|
45
|
+
total = 0
|
46
|
+
# decoder for program blocks
|
47
|
+
decode_blocks = lambda do |script, encoded|
|
48
|
+
script = script.gsub(encoded) { |match| blocks[$1.to_i] } while script =~ encoded
|
49
|
+
script
|
50
|
+
end
|
51
|
+
|
52
|
+
# encoder for program blocks
|
53
|
+
encode_blocks = lambda do |match|
|
54
|
+
prefix, block_type, args, block = $1 || "", $2, $3, $4
|
55
|
+
if block_type == 'function'
|
56
|
+
# decode the function block (THIS IS THE IMPORTANT BIT)
|
57
|
+
# We are retrieving all sub-blocks and will re-parse them in light
|
58
|
+
# of newly shrunk variables
|
59
|
+
block = args + decode_blocks.call(block, __scoped)
|
60
|
+
prefix = prefix.gsub(__brackets, "")
|
61
|
+
|
62
|
+
# create the list of variable and argument names
|
63
|
+
args = args[1...-1]
|
64
|
+
|
65
|
+
if args != '_no_shrink_'
|
66
|
+
vars = block.scan(__vars).join(";").gsub(__var, ";var")
|
67
|
+
vars = vars.gsub(__brackets, "") while vars =~ __brackets
|
68
|
+
vars = vars.gsub(__var_tidy, "").gsub(__var_equal, "")
|
69
|
+
end
|
70
|
+
block = decode_blocks.call(block, __encoded_block)
|
71
|
+
|
72
|
+
# process each identifier
|
73
|
+
if args != '_no_shrink_'
|
74
|
+
count, short_id = 0, nil
|
75
|
+
ids = [args, vars].join(",").scan(__identifier)
|
76
|
+
processed = {}
|
77
|
+
ids.each do |id|
|
78
|
+
if !processed['#' + id] and !protected_names.include?(id)
|
79
|
+
processed['#' + id] = true
|
80
|
+
id = Packr.rescape(id)
|
81
|
+
# encode variable names
|
82
|
+
count += 1 while block =~ Regexp.new("#{PREFIX}#{count}\\b")
|
83
|
+
reg = Regexp.new("([^\\w$.])#{id}([^\\w$:])")
|
84
|
+
block = block.gsub(reg, "\\1#{PREFIX}#{count}\\2") while block =~ reg
|
85
|
+
reg = Regexp.new("([^{,\\w$.])#{id}:")
|
86
|
+
block = block.gsub(reg, "\\1#{PREFIX}#{count}:")
|
87
|
+
count += 1
|
88
|
+
end
|
89
|
+
end
|
90
|
+
total = [total, count].max
|
91
|
+
end
|
92
|
+
replacement = "#{prefix}~#{blocks.length}~"
|
93
|
+
blocks << block
|
94
|
+
else
|
95
|
+
replacement = "~##{blocks.length}~"
|
96
|
+
blocks << (prefix + block)
|
97
|
+
end
|
98
|
+
replacement
|
99
|
+
end
|
100
|
+
|
101
|
+
# encode blocks, as we encode we replace variable and argument names
|
102
|
+
script = script.gsub(__block, &encode_blocks) while script =~ __block
|
103
|
+
|
104
|
+
# put the blocks back
|
105
|
+
script = decode_blocks.call(script, __encoded_block)
|
106
|
+
|
107
|
+
short_id, count = nil, 0
|
108
|
+
shrunk = Encoder.new(SHRUNK, lambda { |object|
|
109
|
+
# find the next free short name
|
110
|
+
begin
|
111
|
+
short_id = Packr.encode52(count)
|
112
|
+
count += 1
|
113
|
+
end while script =~ Regexp.new("[^\\w$.]#{short_id}[^\\w$:]")
|
114
|
+
short_id
|
115
|
+
})
|
116
|
+
script = shrunk.encode(script)
|
117
|
+
|
118
|
+
decode_data(script)
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|