diff --git a/resources/static/lib/jschannel.js b/resources/static/lib/jschannel.js
index ad70c3344f106368cf763af3b45f160008ee36ee..c2a5ee41093b37086c9742b8615ff3b8a5756d5c 100644
--- a/resources/static/lib/jschannel.js
+++ b/resources/static/lib/jschannel.js
@@ -1,4 +1,4 @@
-/**
+/*
  * js_channel is a very lightweight abstraction on top of
  * postMessage which defines message formats and semantics
  * to support interactions more rich than just message passing
diff --git a/scripts/compress-worker.js b/scripts/compress-worker.js
index a65b751fc86c677c2f83117100f014878a5d3228..277a3f7b410d71eaf886c23e0b9967c86d53bae3 100644
--- a/scripts/compress-worker.js
+++ b/scripts/compress-worker.js
@@ -29,15 +29,35 @@ function compressResource(staticPath, name, files, cb) {
     });
   }
 
+  function extract_copyright(code) {
+    var tok = jsp.tokenizer(code), toks, ret = "";
+    toks = tok().comments_before;
+
+    if (toks.length >= 1) {
+      var c = toks[0];
+      // copyrights that we'll include MUST be before code body and have
+      // the form: /** */
+      if (c.value.substr(0, 1) === '*' && c.type === 'comment2') {
+        ret += "/*" + c.value + "*/";
+      }
+    }
+
+    return ret;
+  };
+
   function compress() {
     try {
       var final_code;
       if (/\.js$/.test(name)) {
+        // extract copyright
+        var copyright = extract_copyright(orig_code) || "";
+        if (copyright.length) copyright += "\n\n";
+
         // compress javascript
         var ast = jsp.parse(orig_code); // parse code and get the initial AST
         ast = pro.ast_mangle(ast); // get a new AST with mangled names
         ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
-        final_code = pro.split_lines(pro.gen_code(ast), 32 * 1024); // compressed code here
+        final_code = copyright + pro.split_lines(pro.gen_code(ast), 32 * 1024); // compressed code here
       } else if (/\.css$/.test(name)) {
         // compress css
         var cach_code = cachify_embedded(orig_code);