1"use strict"; 2 3var to_ascii, to_base64; 4if (typeof Buffer == "undefined") { 5 to_ascii = atob; 6 to_base64 = btoa; 7} else if (typeof Buffer.alloc == "undefined") { 8 to_ascii = function(b64) { 9 return new Buffer(b64, "base64").toString(); 10 }; 11 to_base64 = function(str) { 12 return new Buffer(str).toString("base64"); 13 }; 14} else { 15 to_ascii = function(b64) { 16 return Buffer.from(b64, "base64").toString(); 17 }; 18 to_base64 = function(str) { 19 return Buffer.from(str).toString("base64"); 20 }; 21} 22 23function read_source_map(name, toplevel) { 24 var comments = toplevel.end.comments_after; 25 for (var i = comments.length; --i >= 0;) { 26 var comment = comments[i]; 27 if (comment.type != "comment1") break; 28 var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value); 29 if (!match) break; 30 if (match[1] == "sourceMappingURL") { 31 match = /^data:application\/json(;.*?)?;base64,([^,]+)$/.exec(match[2]); 32 if (!match) break; 33 return to_ascii(match[2]); 34 } 35 } 36 AST_Node.warn("inline source map not found: {name}", { 37 name: name, 38 }); 39} 40 41function parse_source_map(content) { 42 try { 43 return JSON.parse(content); 44 } catch (ex) { 45 throw new Error("invalid input source map: " + content); 46 } 47} 48 49function set_shorthand(name, options, keys) { 50 keys.forEach(function(key) { 51 if (options[key]) { 52 if (typeof options[key] != "object") options[key] = {}; 53 if (!(name in options[key])) options[key][name] = options[name]; 54 } 55 }); 56} 57 58function init_cache(cache) { 59 if (!cache) return; 60 if (!("props" in cache)) { 61 cache.props = new Dictionary(); 62 } else if (!(cache.props instanceof Dictionary)) { 63 cache.props = Dictionary.fromObject(cache.props); 64 } 65} 66 67function to_json(cache) { 68 return { 69 props: cache.props.toObject() 70 }; 71} 72 73function minify(files, options) { 74 try { 75 options = defaults(options, { 76 annotations: undefined, 77 compress: {}, 78 enclose: false, 79 expression: false, 80 ie: false, 81 ie8: false, 82 keep_fargs: false, 83 keep_fnames: false, 84 mangle: {}, 85 module: false, 86 nameCache: null, 87 output: {}, 88 parse: {}, 89 rename: undefined, 90 sourceMap: false, 91 timings: false, 92 toplevel: !!(options && options["module"]), 93 v8: false, 94 validate: false, 95 warnings: false, 96 webkit: false, 97 wrap: false, 98 }, true); 99 if (options.validate) AST_Node.enable_validation(); 100 var timings = options.timings && { start: Date.now() }; 101 if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]); 102 if (options.expression) set_shorthand("expression", options, [ "compress", "parse" ]); 103 if (options.ie8) options.ie = options.ie || options.ie8; 104 if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output", "rename" ]); 105 if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle", "rename" ]); 106 if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle", "rename" ]); 107 if (options.module) set_shorthand("module", options, [ "compress", "parse" ]); 108 if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle", "rename" ]); 109 if (options.v8) set_shorthand("v8", options, [ "mangle", "output", "rename" ]); 110 if (options.webkit) set_shorthand("webkit", options, [ "compress", "mangle", "output", "rename" ]); 111 var quoted_props; 112 if (options.mangle) { 113 options.mangle = defaults(options.mangle, { 114 cache: options.nameCache && (options.nameCache.vars || {}), 115 eval: false, 116 ie: false, 117 keep_fargs: false, 118 keep_fnames: false, 119 properties: false, 120 reserved: [], 121 toplevel: false, 122 v8: false, 123 webkit: false, 124 }, true); 125 if (options.mangle.properties) { 126 if (typeof options.mangle.properties != "object") { 127 options.mangle.properties = {}; 128 } 129 if (options.mangle.properties.keep_quoted) { 130 quoted_props = options.mangle.properties.reserved; 131 if (!Array.isArray(quoted_props)) quoted_props = []; 132 options.mangle.properties.reserved = quoted_props; 133 } 134 if (options.nameCache && !("cache" in options.mangle.properties)) { 135 options.mangle.properties.cache = options.nameCache.props || {}; 136 } 137 } 138 init_cache(options.mangle.cache); 139 init_cache(options.mangle.properties.cache); 140 } 141 if (options.rename === undefined) options.rename = options.compress && options.mangle; 142 if (options.sourceMap) { 143 options.sourceMap = defaults(options.sourceMap, { 144 content: null, 145 filename: null, 146 includeSources: false, 147 names: true, 148 root: null, 149 url: null, 150 }, true); 151 } 152 var warnings = []; 153 if (options.warnings) AST_Node.log_function(function(warning) { 154 warnings.push(warning); 155 }, options.warnings == "verbose"); 156 if (timings) timings.parse = Date.now(); 157 var toplevel; 158 options.parse = options.parse || {}; 159 if (files instanceof AST_Node) { 160 toplevel = files; 161 } else { 162 if (typeof files == "string") files = [ files ]; 163 options.parse.toplevel = null; 164 var source_map_content = options.sourceMap && options.sourceMap.content; 165 if (typeof source_map_content == "string" && source_map_content != "inline") { 166 source_map_content = parse_source_map(source_map_content); 167 } 168 if (source_map_content) options.sourceMap.orig = Object.create(null); 169 for (var name in files) if (HOP(files, name)) { 170 options.parse.filename = name; 171 options.parse.toplevel = toplevel = parse(files[name], options.parse); 172 if (source_map_content == "inline") { 173 var inlined_content = read_source_map(name, toplevel); 174 if (inlined_content) options.sourceMap.orig[name] = parse_source_map(inlined_content); 175 } else if (source_map_content) { 176 options.sourceMap.orig[name] = source_map_content; 177 } 178 } 179 } 180 if (options.parse.expression) toplevel = toplevel.wrap_expression(); 181 if (quoted_props) reserve_quoted_keys(toplevel, quoted_props); 182 [ "enclose", "wrap" ].forEach(function(action) { 183 var option = options[action]; 184 if (!option) return; 185 var orig = toplevel.print_to_string().slice(0, -1); 186 toplevel = toplevel[action](option); 187 files[toplevel.start.file] = toplevel.print_to_string().replace(orig, ""); 188 }); 189 if (options.validate) toplevel.validate_ast(); 190 if (timings) timings.rename = Date.now(); 191 if (options.rename) { 192 toplevel.figure_out_scope(options.rename); 193 toplevel.expand_names(options.rename); 194 } 195 if (timings) timings.compress = Date.now(); 196 if (options.compress) { 197 toplevel = new Compressor(options.compress).compress(toplevel); 198 if (options.validate) toplevel.validate_ast(); 199 } 200 if (timings) timings.scope = Date.now(); 201 if (options.mangle) toplevel.figure_out_scope(options.mangle); 202 if (timings) timings.mangle = Date.now(); 203 if (options.mangle) { 204 toplevel.compute_char_frequency(options.mangle); 205 toplevel.mangle_names(options.mangle); 206 } 207 if (timings) timings.properties = Date.now(); 208 if (quoted_props) reserve_quoted_keys(toplevel, quoted_props); 209 if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties); 210 if (options.parse.expression) toplevel = toplevel.unwrap_expression(); 211 if (timings) timings.output = Date.now(); 212 var result = {}; 213 var output = defaults(options.output, { 214 ast: false, 215 code: true, 216 }); 217 if (output.ast) result.ast = toplevel; 218 if (output.code) { 219 if (options.sourceMap) { 220 output.source_map = SourceMap(options.sourceMap); 221 if (options.sourceMap.includeSources) { 222 if (files instanceof AST_Toplevel) { 223 throw new Error("original source content unavailable"); 224 } else for (var name in files) if (HOP(files, name)) { 225 output.source_map.setSourceContent(name, files[name]); 226 } 227 } 228 } 229 delete output.ast; 230 delete output.code; 231 var stream = OutputStream(output); 232 toplevel.print(stream); 233 result.code = stream.get(); 234 if (options.sourceMap) { 235 result.map = output.source_map.toString(); 236 var url = options.sourceMap.url; 237 if (url) { 238 result.code = result.code.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, ""); 239 if (url == "inline") { 240 result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map); 241 } else { 242 result.code += "\n//# sourceMappingURL=" + url; 243 } 244 } 245 } 246 } 247 if (options.nameCache && options.mangle) { 248 if (options.mangle.cache) options.nameCache.vars = to_json(options.mangle.cache); 249 if (options.mangle.properties && options.mangle.properties.cache) { 250 options.nameCache.props = to_json(options.mangle.properties.cache); 251 } 252 } 253 if (timings) { 254 timings.end = Date.now(); 255 result.timings = { 256 parse: 1e-3 * (timings.rename - timings.parse), 257 rename: 1e-3 * (timings.compress - timings.rename), 258 compress: 1e-3 * (timings.scope - timings.compress), 259 scope: 1e-3 * (timings.mangle - timings.scope), 260 mangle: 1e-3 * (timings.properties - timings.mangle), 261 properties: 1e-3 * (timings.output - timings.properties), 262 output: 1e-3 * (timings.end - timings.output), 263 total: 1e-3 * (timings.end - timings.start) 264 }; 265 } 266 if (warnings.length) { 267 result.warnings = warnings; 268 } 269 return result; 270 } catch (ex) { 271 return { error: ex }; 272 } finally { 273 AST_Node.log_function(); 274 AST_Node.disable_validation(); 275 } 276} 277