| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 01:02:02 +08:00
										 |  |  | const Template = require("../Template"); | 
					
						
							|  |  |  | const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Get all wasm modules
 | 
					
						
							|  |  |  | function getAllWasmModules(chunk) { | 
					
						
							|  |  |  | 	const wasmModules = chunk.getAllAsyncChunks(); | 
					
						
							|  |  |  | 	const array = []; | 
					
						
							|  |  |  | 	for (const chunk of wasmModules) { | 
					
						
							|  |  |  | 		for (const m of chunk.modulesIterable) { | 
					
						
							|  |  |  | 			if (m.type.startsWith("webassembly")) { | 
					
						
							|  |  |  | 				array.push(m); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return array; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function generateImportObject(module) { | 
					
						
							|  |  |  | 	const depsByRequest = new Map(); | 
					
						
							|  |  |  | 	for (const dep of module.dependencies) { | 
					
						
							|  |  |  | 		if (dep instanceof WebAssemblyImportDependency) { | 
					
						
							|  |  |  | 			// Ignore global they will be handled later
 | 
					
						
							|  |  |  | 			if (dep.description.type === "GlobalType") { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const request = dep.request; | 
					
						
							|  |  |  | 			let array = depsByRequest.get(request); | 
					
						
							|  |  |  | 			if (!array) { | 
					
						
							|  |  |  | 				depsByRequest.set(request, (array = [])); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			const exportName = dep.name; | 
					
						
							|  |  |  | 			const usedName = dep.module && dep.module.isUsed(exportName); | 
					
						
							| 
									
										
										
										
											2018-03-29 19:52:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-05 00:52:07 +08:00
										 |  |  | 			if (dep.module === null) { | 
					
						
							|  |  |  | 				// Dependency was not found, an error will be thrown later
 | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-29 19:52:26 +08:00
										 |  |  | 			if (usedName !== false) { | 
					
						
							|  |  |  | 				array.push({ | 
					
						
							|  |  |  | 					exportName, | 
					
						
							|  |  |  | 					usedName, | 
					
						
							|  |  |  | 					module: dep.module, | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 					description: dep.description, | 
					
						
							|  |  |  | 					direct: dep.onlyDirectImport | 
					
						
							| 
									
										
										
										
											2018-03-29 19:52:26 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	const importsCode = []; | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 	const waitForPromises = new Map(); | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 	for (const pair of depsByRequest) { | 
					
						
							|  |  |  | 		const properties = []; | 
					
						
							|  |  |  | 		for (const data of pair[1]) { | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 			if (data.direct) { | 
					
						
							|  |  |  | 				const instanceVar = `m${waitForPromises.size}`; | 
					
						
							|  |  |  | 				waitForPromises.set( | 
					
						
							|  |  |  | 					instanceVar, | 
					
						
							|  |  |  | 					`installedWasmModules[${JSON.stringify(data.module.id)}]` | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				properties.push( | 
					
						
							|  |  |  | 					`${JSON.stringify(data.exportName)}: ${instanceVar}.exports` + | 
					
						
							|  |  |  | 						`[${JSON.stringify(data.exportName)}]` | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2018-04-28 17:38:34 +08:00
										 |  |  | 				const params = data.description.signature.params.map( | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 					(param, k) => "p" + k + param.valtype | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 				const result = `__webpack_require__(${JSON.stringify( | 
					
						
							|  |  |  | 					data.module.id | 
					
						
							|  |  |  | 				)})[${JSON.stringify(data.usedName)}](${params})`;
 | 
					
						
							| 
									
										
										
										
											2018-03-28 20:58:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 				properties.push( | 
					
						
							|  |  |  | 					Template.asString([ | 
					
						
							|  |  |  | 						`${JSON.stringify(data.exportName)}: function(${params}) {`, | 
					
						
							|  |  |  | 						Template.indent([`return ${result};`]), | 
					
						
							|  |  |  | 						"}" | 
					
						
							|  |  |  | 					]) | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-03-28 20:58:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 		importsCode.push( | 
					
						
							| 
									
										
										
										
											2018-04-28 15:57:21 +08:00
										 |  |  | 			Template.asString([ | 
					
						
							|  |  |  | 				`${JSON.stringify(pair[0])}: {`, | 
					
						
							|  |  |  | 				Template.indent([properties.join(",")]), | 
					
						
							|  |  |  | 				"}" | 
					
						
							|  |  |  | 			]) | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 	if (waitForPromises.size > 0) { | 
					
						
							|  |  |  | 		const promises = Array.from(waitForPromises.values()).join(", "); | 
					
						
							|  |  |  | 		const variables = Array.from( | 
					
						
							|  |  |  | 			waitForPromises.keys(), | 
					
						
							|  |  |  | 			(name, i) => `var ${name} = array[${i}];` | 
					
						
							|  |  |  | 		).join("\n"); | 
					
						
							|  |  |  | 		return Template.asString([ | 
					
						
							|  |  |  | 			`${JSON.stringify(module.id)}: function() {`, | 
					
						
							|  |  |  | 			Template.indent([ | 
					
						
							| 
									
										
										
										
											2018-04-28 17:29:46 +08:00
										 |  |  | 				`return Promise.resolve().then(function() { return Promise.all([${promises}]); }).then(function(array) {`, | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 				Template.indent([ | 
					
						
							|  |  |  | 					variables, | 
					
						
							|  |  |  | 					"return {", | 
					
						
							|  |  |  | 					Template.indent([importsCode.join(",")]), | 
					
						
							|  |  |  | 					"};" | 
					
						
							|  |  |  | 				]), | 
					
						
							|  |  |  | 				"});" | 
					
						
							|  |  |  | 			]), | 
					
						
							|  |  |  | 			"}," | 
					
						
							|  |  |  | 		]); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return Template.asString([ | 
					
						
							|  |  |  | 			`${JSON.stringify(module.id)}: function() {`, | 
					
						
							|  |  |  | 			Template.indent([ | 
					
						
							|  |  |  | 				"return {", | 
					
						
							|  |  |  | 				Template.indent([importsCode.join(",")]), | 
					
						
							|  |  |  | 				"};" | 
					
						
							|  |  |  | 			]), | 
					
						
							|  |  |  | 			"}," | 
					
						
							|  |  |  | 		]); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 01:02:02 +08:00
										 |  |  | class WasmMainTemplatePlugin { | 
					
						
							| 
									
										
										
										
											2018-04-30 14:35:06 +08:00
										 |  |  | 	constructor(generateLoadBinaryCode, supportsStreaming) { | 
					
						
							| 
									
										
										
										
											2018-04-28 01:02:02 +08:00
										 |  |  | 		this.generateLoadBinaryCode = generateLoadBinaryCode; | 
					
						
							| 
									
										
										
										
											2018-04-30 14:35:06 +08:00
										 |  |  | 		this.supportsStreaming = supportsStreaming; | 
					
						
							| 
									
										
										
										
											2018-04-28 01:02:02 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	apply(mainTemplate) { | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 		mainTemplate.hooks.localVars.tap( | 
					
						
							| 
									
										
										
										
											2018-04-28 01:02:02 +08:00
										 |  |  | 			"WasmMainTemplatePlugin", | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 			(source, chunk) => { | 
					
						
							| 
									
										
										
										
											2018-04-28 15:57:21 +08:00
										 |  |  | 				const wasmModules = getAllWasmModules(chunk); | 
					
						
							|  |  |  | 				if (wasmModules.length === 0) return source; | 
					
						
							|  |  |  | 				const importObjects = wasmModules.map(generateImportObject); | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 				return Template.asString([ | 
					
						
							|  |  |  | 					source, | 
					
						
							|  |  |  | 					"", | 
					
						
							|  |  |  | 					"// object to store loaded and loading wasm modules", | 
					
						
							| 
									
										
										
										
											2018-04-28 15:57:21 +08:00
										 |  |  | 					"var installedWasmModules = {};", | 
					
						
							|  |  |  | 					"", | 
					
						
							|  |  |  | 					"var wasmImportObjects = {", | 
					
						
							|  |  |  | 					Template.indent([importObjects]), | 
					
						
							|  |  |  | 					"};" | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 				]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		mainTemplate.hooks.requireEnsure.tap( | 
					
						
							| 
									
										
										
										
											2018-04-28 01:02:02 +08:00
										 |  |  | 			"WasmMainTemplatePlugin", | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 			(source, chunk, hash) => { | 
					
						
							|  |  |  | 				const webassemblyModuleFilename = | 
					
						
							|  |  |  | 					mainTemplate.outputOptions.webassemblyModuleFilename; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				const chunkModuleMaps = chunk.getChunkModuleMaps(m => | 
					
						
							|  |  |  | 					m.type.startsWith("webassembly") | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				if (Object.keys(chunkModuleMaps.id).length === 0) return source; | 
					
						
							|  |  |  | 				const wasmModuleSrcPath = mainTemplate.getAssetPath( | 
					
						
							|  |  |  | 					JSON.stringify(webassemblyModuleFilename), | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`, | 
					
						
							|  |  |  | 						hashWithLength: length => | 
					
						
							|  |  |  | 							`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`, | 
					
						
							|  |  |  | 						module: { | 
					
						
							|  |  |  | 							id: '" + wasmModuleId + "', | 
					
						
							|  |  |  | 							hash: `" + ${JSON.stringify( | 
					
						
							|  |  |  | 								chunkModuleMaps.hash | 
					
						
							|  |  |  | 							)}[wasmModuleId] + "`,
 | 
					
						
							|  |  |  | 							hashWithLength(length) { | 
					
						
							|  |  |  | 								const shortChunkHashMap = Object.create(null); | 
					
						
							|  |  |  | 								for (const wasmModuleId of Object.keys(chunkModuleMaps.hash)) { | 
					
						
							|  |  |  | 									if (typeof chunkModuleMaps.hash[wasmModuleId] === "string") | 
					
						
							|  |  |  | 										shortChunkHashMap[wasmModuleId] = chunkModuleMaps.hash[ | 
					
						
							|  |  |  | 											wasmModuleId | 
					
						
							|  |  |  | 										].substr(0, length); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								return `" + ${JSON.stringify( | 
					
						
							|  |  |  | 									shortChunkHashMap | 
					
						
							|  |  |  | 								)}[wasmModuleId] + "`;
 | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				return Template.asString([ | 
					
						
							|  |  |  | 					source, | 
					
						
							|  |  |  | 					"", | 
					
						
							|  |  |  | 					"// Fetch + compile chunk loading for webassembly", | 
					
						
							|  |  |  | 					"", | 
					
						
							|  |  |  | 					`var wasmModules = ${JSON.stringify( | 
					
						
							|  |  |  | 						chunkModuleMaps.id | 
					
						
							|  |  |  | 					)}[chunkId] || [];`,
 | 
					
						
							|  |  |  | 					"", | 
					
						
							|  |  |  | 					"wasmModules.forEach(function(wasmModuleId) {", | 
					
						
							|  |  |  | 					Template.indent([ | 
					
						
							|  |  |  | 						"var installedWasmModuleData = installedWasmModules[wasmModuleId];", | 
					
						
							|  |  |  | 						"", | 
					
						
							|  |  |  | 						'// a Promise means "currently loading" or "already loaded".', | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 						"if(installedWasmModuleData)", | 
					
						
							|  |  |  | 						Template.indent(["promises.push(installedWasmModuleData);"]), | 
					
						
							|  |  |  | 						"else {", | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 						Template.indent([ | 
					
						
							| 
									
										
										
										
											2018-04-30 14:35:06 +08:00
										 |  |  | 							`var importObject = wasmImportObjects[wasmModuleId]();`, | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 							`var req = ${this.generateLoadBinaryCode(wasmModuleSrcPath)};`, | 
					
						
							| 
									
										
										
										
											2018-04-30 14:35:06 +08:00
										 |  |  | 							"var promise;", | 
					
						
							|  |  |  | 							this.supportsStreaming | 
					
						
							|  |  |  | 								? Template.asString([ | 
					
						
							|  |  |  | 										"if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {", | 
					
						
							|  |  |  | 										Template.indent([ | 
					
						
							|  |  |  | 											"promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {", | 
					
						
							|  |  |  | 											Template.indent([ | 
					
						
							|  |  |  | 												"return WebAssembly.instantiate(items[0], items[1]);" | 
					
						
							|  |  |  | 											]), | 
					
						
							|  |  |  | 											"});" | 
					
						
							|  |  |  | 										]), | 
					
						
							|  |  |  | 										"} else if(typeof WebAssembly.instantiateStreaming === 'function') {", | 
					
						
							|  |  |  | 										Template.indent([ | 
					
						
							|  |  |  | 											"promise = WebAssembly.instantiateStreaming(req, importObject);" | 
					
						
							|  |  |  | 										]) | 
					
						
							|  |  |  | 								  ]) | 
					
						
							|  |  |  | 								: Template.asString([ | 
					
						
							|  |  |  | 										"if(importObject instanceof Promise) {", | 
					
						
							|  |  |  | 										Template.indent([ | 
					
						
							|  |  |  | 											"var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });", | 
					
						
							|  |  |  | 											"promise = Promise.all([", | 
					
						
							|  |  |  | 											Template.indent([ | 
					
						
							|  |  |  | 												"bytesPromise.then(function(bytes) { return WebAssembly.compile(bytes); }),", | 
					
						
							|  |  |  | 												"importObject" | 
					
						
							|  |  |  | 											]), | 
					
						
							|  |  |  | 											"]).then(function(items) {", | 
					
						
							|  |  |  | 											Template.indent([ | 
					
						
							|  |  |  | 												"return WebAssembly.instantiate(items[0], items[1]);" | 
					
						
							|  |  |  | 											]), | 
					
						
							|  |  |  | 											"});" | 
					
						
							|  |  |  | 										]) | 
					
						
							|  |  |  | 								  ]), | 
					
						
							|  |  |  | 							"} else {", | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 							Template.indent([ | 
					
						
							| 
									
										
										
										
											2018-04-30 14:35:06 +08:00
										 |  |  | 								"var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });", | 
					
						
							|  |  |  | 								"promise = bytesPromise.then(function(bytes) {", | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 								Template.indent([ | 
					
						
							| 
									
										
										
										
											2018-04-30 14:35:06 +08:00
										 |  |  | 									"return WebAssembly.instantiate(bytes, importObject);" | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 								]), | 
					
						
							| 
									
										
										
										
											2018-04-30 14:35:06 +08:00
										 |  |  | 								"});" | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 							]), | 
					
						
							| 
									
										
										
										
											2018-04-30 14:35:06 +08:00
										 |  |  | 							"}", | 
					
						
							|  |  |  | 							"promises.push(installedWasmModules[wasmModuleId] = promise.then(function(res) {", | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 							Template.indent([ | 
					
						
							|  |  |  | 								`return ${ | 
					
						
							|  |  |  | 									mainTemplate.requireFn | 
					
						
							| 
									
										
										
										
											2018-04-30 14:35:06 +08:00
										 |  |  | 								}.w[wasmModuleId] = res.instance || res;`
 | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 							]), | 
					
						
							| 
									
										
										
										
											2018-04-28 17:09:13 +08:00
										 |  |  | 							"}));" | 
					
						
							|  |  |  | 						]), | 
					
						
							|  |  |  | 						"}" | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 					]), | 
					
						
							|  |  |  | 					"});" | 
					
						
							|  |  |  | 				]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		mainTemplate.hooks.requireExtensions.tap( | 
					
						
							| 
									
										
										
										
											2018-04-28 01:02:02 +08:00
										 |  |  | 			"WasmMainTemplatePlugin", | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 			(source, chunk) => { | 
					
						
							|  |  |  | 				if (!chunk.hasModuleInGraph(m => m.type.startsWith("webassembly"))) | 
					
						
							|  |  |  | 					return source; | 
					
						
							|  |  |  | 				return Template.asString([ | 
					
						
							|  |  |  | 					source, | 
					
						
							|  |  |  | 					"", | 
					
						
							|  |  |  | 					"// object with all WebAssembly.instance", | 
					
						
							|  |  |  | 					`${mainTemplate.requireFn}.w = {};` | 
					
						
							|  |  |  | 				]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-04-28 01:02:02 +08:00
										 |  |  | 		mainTemplate.hooks.hash.tap("WasmMainTemplatePlugin", hash => { | 
					
						
							|  |  |  | 			hash.update("WasmMainTemplatePlugin"); | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 			hash.update("1"); | 
					
						
							|  |  |  | 			hash.update(`${mainTemplate.outputOptions.webassemblyModuleFilename}`); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2018-04-28 16:02:12 +08:00
										 |  |  | 		mainTemplate.hooks.hashForChunk.tap( | 
					
						
							|  |  |  | 			"WasmMainTemplatePlugin", | 
					
						
							|  |  |  | 			(hash, chunk) => { | 
					
						
							|  |  |  | 				const chunkModuleMaps = chunk.getChunkModuleMaps(m => | 
					
						
							|  |  |  | 					m.type.startsWith("webassembly") | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				hash.update(JSON.stringify(chunkModuleMaps.id)); | 
					
						
							|  |  |  | 				const wasmModules = getAllWasmModules(chunk); | 
					
						
							|  |  |  | 				for (const module of wasmModules) { | 
					
						
							|  |  |  | 					hash.update(module.hash); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-03-14 23:13:03 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 01:02:02 +08:00
										 |  |  | module.exports = WasmMainTemplatePlugin; |