28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/packr/shrinker.rb', line 28
def shrink(script, protected_names = [])
script = encode_data(script)
protected_names ||= []
protected_names = protected_names.map { |s| s.to_s }
__block = /((catch|do|if|while|with|function)\b[^~{};]*(\(\s*[^{};]*\s*\))\s*)?(\{[^{}]*\})/
__brackets = /\{[^{}]*\}|\[[^\[\]]*\]|\([^\(\)]*\)|~[^~]+~/
__encoded_block = /~#?(\d+)~/
__identifier = /[a-zA-Z_$][\w\$]*/
__scoped = /~#(\d+)~/
__var = /\bvar\b/
__vars = /\bvar\s+[\w$]+[^;#]*|\bfunction\s+[\w$]+/
__var_tidy = /\b(var|function)\b|\sin\s+[^;]+/
__var_equal = /\s*=[^,;]*/
blocks = [] total = 0
decode_blocks = lambda do |script, encoded|
script = script.gsub(encoded) { |match| blocks[$1.to_i] } while script =~ encoded
script
end
encode_blocks = lambda do |match|
prefix, block_type, args, block = $1 || "", $2, $3, $4
if block_type == 'function'
block = args + decode_blocks.call(block, __scoped)
prefix = prefix.gsub(__brackets, "")
args = args[1...-1]
if args != '_no_shrink_'
vars = block.scan(__vars).join(";").gsub(__var, ";var")
vars = vars.gsub(__brackets, "") while vars =~ __brackets
vars = vars.gsub(__var_tidy, "").gsub(__var_equal, "")
end
block = decode_blocks.call(block, __encoded_block)
if args != '_no_shrink_'
count, short_id = 0, nil
ids = [args, vars].join(",").scan(__identifier)
processed = {}
ids.each do |id|
if !processed['#' + id] and !protected_names.include?(id)
processed['#' + id] = true
id = id.gsub(/([\/()\[\]{}|*+-.,^$?\\])/) { |m| "\\#{$1}" }
count += 1 while block =~ Regexp.new("#{PREFIX}#{count}\\b")
reg = Regexp.new("([^\\w$.])#{id}([^\\w$:])")
block = block.gsub(reg, "\\1#{PREFIX}#{count}\\2") while block =~ reg
reg = Regexp.new("([^{,\\w$.])#{id}:")
block = block.gsub(reg, "\\1#{PREFIX}#{count}:")
count += 1
end
end
total = [total, count].max
end
replacement = "#{prefix}~#{blocks.length}~"
blocks << block
else
replacement = "~##{blocks.length}~"
blocks << (prefix + block)
end
replacement
end
script = script.gsub(__block, &encode_blocks) while script =~ __block
script = decode_blocks.call(script, __encoded_block)
short_id, count = nil, 0
shrunk = Encoder.new(SHRUNK, lambda { |object|
begin
short_id = Packr.encode52(count)
count += 1
end while script =~ Regexp.new("[^\\w$.]#{short_id}[^\\w$:]")
short_id
})
script = shrunk.encode(script)
decode_data(script)
end
|