<|start_filename|>polymer/app/scripts/page.js<|end_filename|>
'use strict';
document.addEventListener('WebComponentsReady', function() {
  window.addEventListener('resize', repositionFooter);
  repositionFooter();

  function repositionFooter() {
    var buffer = 10;
    var main = document.getElementsByTagName('main')[0];
    var footer = document.getElementsByTagName('footer-element')[0];
    var footerHeight = footer.clientHeight + buffer;
    main.style['margin-bottom'] = footerHeight + 'px';
  }
});


<|start_filename|>jquery-spaghetti/app/uploader.js<|end_filename|>
/*global _:true */
$(function() {
  var encryptedFile /* object */;
  var passphrase = window.secureShared.generatePassphrase();
  $("#password").val(passphrase);
  var cryptoWorker;

  // bindings
  $('#fileupload').change(encryptFile);
  $('#submit').click(uploadFile);

  function encryptFile(){

    // Clear any errors
    $(".itemStatus").add(".attachedFileInfo").html("");
    $(".uploadLoader").hide();
    $("#downloaded-content").hide();
    $(".fileInfo").hide();
    $("#link").hide();

    // Remove hash from URL bar to avoid confusion.
    window.location.hash = "";

    // Check file
    var file = this.files[0]; // browser 'File' object
    if(!file) return window.alert("Please attach a file to share first.");
    if(file.size > window.secureShared.fileSizeLimit) return window.alert("File is too big. Please choose a file under 10MB.");
    file.name = file.name + "?" + (Math.random() * 1000); // browser cache buster

    // Change page styles to indicate encryption is in #uploadProgress
    window.isEncrypting = true;
    $(".uploadLoader").show();
    $(".attachedFileInfo").html("File attached: " + file.name + ". <br>Size: " + window.secureShared.fileSize(file.size));
    $(".itemStatus").html("Encrypting: 0% complete");
    $("#submit").removeClass('btn-primary').addClass('btn-inverse loading').attr('disabled', 'disabled');
    $("#uploadProgress").toggle();

    // Create worker
    if(cryptoWorker) cryptoWorker.terminate();
    var workers = window.secureShared.spawnWorkers(window.secureShared.workerCount), i;
    for(i = 0; i < workers.length; i++){
      workers[i].addEventListener('message', onWorkerMessage, false);
      // Log errors
      workers[i].onError = onWorkerError;
    }

    // Slice file into chunks
    var slices = sliceFile(file);

    // Encrypt slices (post to workers)
    for(i = 0; i < slices.length; i++){
      var msg = {slice: slices[i], encrypt: true, passphrase: passphrase, index: i};
      if(i === 0) msg.fileName = file.name; // don't send filename past the first slice
      workers[i % workers.length].postMessage(msg);
    }

    encryptedFile = {
      fileData : [],
      fileName : '',
      contentType: file.type,
      chunkDelimiter: window.secureShared.chunkDelimiter
    };
    // Listen to encryption events
    var finished = 0;
    var total = 0;
    var time = new Date();

    function onWorkerError(e){
      console.error(e.data);
    }
    function onWorkerMessage(e){
      // received a slice.
      if(_.isString(e.data)){
        // message
        return console.log(e.data);
      }
      // console.log(e.data.fileData.length);

      onSlice(e);
      total += e.data.fileData.length;
      finished++;

      // If finished
      // This seems brittle, if the last chunk finishes before another does, the upload will be considered
      // finished & the workers terminated.
      // FIXME: Check `total` === file.size
      if(finished === slices.length){
        onEncryptFinished();
      }
    }

    function onSlice(e){
      encryptedFile.fileData[e.data.index] = e.data.fileData;
      if(e.data.fileName) encryptedFile.fileName = e.data.fileName;
      $("#uploadProgress").attr({value: finished, max: slices.length + 1});
      $(".itemStatus").html("Encrypting: " + ((finished / (slices.length + 1))* 100).toFixed(0) + "% complete.");
    }

    function onEncryptFinished(){
      // console.log("File Size: " + file.size);
      // console.log("Total: " + total);
      // console.log("Time elapsed: " + (new Date() - time));

      // Terminate workers
      for(var i = 0; i < workers.length; i++){
        workers[i].terminate();
      }
      window.isEncrypting = false;
      $(".uploadLoader").hide();
      $(".itemStatus").html("Encryption complete. Click \"Get Secure Link\" to upload.");
      $("#submit").addClass('btn-primary').removeClass('btn-inverse loading').removeAttr('disabled');
      $("#uploadProgress").toggle();
    }
  }


  // Upload file to server, triggered by user click.
  function uploadFile() {
    if(!encryptedFile) return window.alert("Please attach a file to share.");
    if(!encryptedFile.fileData.length || window.isEncrypting) return window.alert("Still encrypting! Please wait...");

    $("#uploadProgress").toggle();

    // Get form params
    var formParams = $("form").serializeArray();
    var params = encryptedFile;
    formParams.forEach(function(param) {
      params[param.name] = param.value;
    });
    delete params.password; // IMPORTANT: don't send password to server!

    // Set #uploadProgress bar to zero
    $('#uploadProgress').attr({value: 0, total: 1});

    // Show 'preparing upload' text
    $(".itemStatus").html("Preparing Upload...");

    $(".uploadLoader").show();
    $.ajax({
      url: '/putfile',
      //server script to process data
      type: 'POST',
      xhr: function() { // custom xhr
        var myXhr = $.ajaxSettings.xhr();
        if(myXhr.upload) { // check if upload property exists
          myXhr.upload.addEventListener('progress', progressHandler, false); // for handling the progress of the upload
        }
        return myXhr;
      },
      contentType: 'text/plain',
      //Ajax events
      //beforeSend: beforeSendHandler,
      success: successHandler,
      error: errorHandler,
      // Form data
      headers: {
        'X-File-Expiration-Days' : params.days,
        'X-File-Max-Views': params.views,
        'X-File-Content-Type': params.contentType,
        'X-File-Name': params.fileName
      },
      data: params.fileData.join(window.secureShared.chunkDelimiter),
      processData: false,
      cache: false
    });

    function beforeSendHandler(xhr) {
      // TODO: Show 'uploading' text
    }

    function successHandler(response) {
      displayURL(response.url, passphrase);
      $(".uploadLoader").hide();
      $(".itemStatus").html("");
    }

    function errorHandler() {
      $(".itemStatus").html("<i>Error</i>");
      $(".uploadLoader").hide();
    }

    function progressHandler(e) {
      if(e.lengthComputable) {
        $('#uploadProgress').attr({
          value: e.loaded,
          max: e.total
        });
      }
      if(e.loaded != e.total){
        $(".itemStatus").html("Uploading: " + ((e.loaded / e.total) * 100).toFixed(0) + "% complete.");
      } else {
        $(".itemStatus").html("Upload complete. Generating URL...");
      }
    }
  }

  // Display uploaded file URL on screen.
  function displayURL(url, passphrase) {
    var fileURL = window.location.protocol + "//" + window.location.host + '?#u=' + url + '&p=' + passphrase;
    var fileURLNoPass = window.location.protocol + "//" + window.location.host + '?#u=' + url;
    var link = "Your file can be reached at:<br> <textarea rows=\"2\" readonly>" + fileURL + "</textarea><br><br>" +
               "The above link is enough for a user to access the file. If you have sent the password separately, " +
               "use this URL instead:<br><textarea rows=\"2\" readonly>" + fileURLNoPass + "</textarea><br><br>" +
               "Your file's password:<br> <input value=\"" + passphrase + "\"/>";
    $("#link").html(link).fadeIn();
    $("#warnings").show();
  }

  // Regen hashes if the user changes the encryption key
  var onPasswordKeyUp = _.debounce(function(){$("#fileupload").trigger('change');}, 250);
  $('#password').bind('input', function() {
    // Ensure the slider is actually open
    if ($("#advance-toggle").find("i").hasClass("glyphicon-chevron-down")) {
      onPasswordKeyUp();
      passphrase = $(this).val(); // change encrypted file's passphrase
    }
  });

  // Slice a file into chunks for fast encryption & upload.
  function sliceFile(file){
    file.slice = file.mozSlice || file.webkitSlice || file.slice; // compatibility
    var pos = 0;
    var slices = [];
    while(pos < file.size){
      slices.push(file.slice(pos, pos += window.secureShared.chunkSize));
    }
    return slices;
  }
});


<|start_filename|>jquery-spaghetti/css/style.css<|end_filename|>
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\000036}}
* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000310}}
.input-prepend input, .input-prepend .add-on, .input-append input, .input-append .add-on {
  -webkit-box-sizing: content-box;
  -moz-box-sizing: content-box;
  box-sizing: content-box;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000313}}
h1, h2, h3, h4, h5, p, a, span, div, article, body {
  color: white;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000316}}
html {
  color: white;
  position: relative;
  min-height: 100%;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000321}}
body {
  background-color: #3366cc;
  background-image: url("/img/bg-texture.png");
  background-repeat: repeat;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000326}}
#wrapper {
  height: 100%;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000329}}
#main {
  width: 600px;
  margin: 0 auto;
  min-height: 500px;
  text-align: center;
  position: relative;
  margin-bottom: 260px;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000336}}
#main .bg {
  background: black 0 0 repeat fixed;
  margin: 0 auto;
  padding: 0;
  position: absolute;
  width: 100%;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000343}}
#main .title {
  width: 100%;
  text-align: center;
  padding-top: 70px;
  margin-left: -50px;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000349}}
#main .title .intro-line {
  position: relative;
  border-top: 1px solid #ededed;
  width: 700px;
  margin: 0 auto 25px auto;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000355}}
#main .title h1 {
  color: white;
  font-size: 56px;
  font-weight: 700;
  position: relative;
  margin-bottom: 15px;
  width: 700px;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000362}}
#main .title h1.small {
  font-size: 17px;
  margin-bottom: 20px;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000366}}
#main .title h1 a {
  text-decoration: none;
  color: white;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000369}}
#main .title h1 a:hover {
  text-decoration: none;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000372}}
#main .file-uploader {
  width: 100%;
  margin-bottom: 270px;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000377}}
#main .file-uploader #upload-form {
  margin: 0 auto;
  text-align: left;
  width: 100%;
  background: rgba(255, 255, 255, 0.15);
  -webkit-box-shadow: 1px 3px 5px 1px rgba(255, 255, 255, 0.3), 1px 3px 3px 1px rgba(255, 255, 255, 0.1) inset;
  -moz-box-shadow: 1px 3px 5px 1px rgba(255, 255, 255, 0.3), 1px 3px 3px 1px rgba(255, 255, 255, 0.1) inset;
  box-shadow: 1px 3px 5px 1px rgba(255, 255, 255, 0.3), 1px 3px 3px 1px rgba(255, 255, 255, 0.1) inset;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  padding: 20px;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000386}}
#main .file-uploader #password-field, #main .file-uploader #expiration-field {
  margin: 0 auto;
  width: 95%;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000389}}
#main .file-uploader #password-field > p, #main .file-uploader #expiration-field > p {
  text-align: center;
  font-weight: bold;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000393}}
#main .file-uploader #inner-advanced {
  padding: 25px 10px;
  background: rgba(255, 255, 255, 0.2);
  width: 100%;
  border-radius: 10px;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\0000399}}
#main .file-uploader #password {
  width: 100%;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003102}}
#main .file-uploader .help-block {
  color: white;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003107}}
#footer-content {
  background: black;
  width: 100%;
  margin: 0;
  position: absolute;
  text-align: center;
  bottom: 0;
  left: 0;
  right: 0;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003117}}
#footer-content article {
  text-align: left;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003121}}
#main-content h2 {
  font-size: 2.5em;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003124}}
#outer-advanced {
  margin-top: 10px;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003127}}
#link, #downloaded-content, #inner-advanced {
  display: none;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003130}}
.loadingText {
  float: left;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003133}}
#downloaded-content {
  margin-bottom: 20px;
  margin-top: 20px;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003137}}
#link {
  margin: 20px auto;
  width: 100%;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003140}}
#link textarea {
  width: 100%;
  height: 60px;
  word-break: break-all;
  cursor: text !important;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003145}}
#link input {
  width: 100%;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003147}}
#link textarea, #link input {
  margin-top: 10px;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003151}}
#downloaded-content button {
  display: none;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003153}}
#downloaded-content .loading {
  margin-bottom: 5px;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003158}}
input#fileupload {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  opacity: 0;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003165}}
.passwordNotes, .explain {
  font-size: 0.85em;
  margin: 5px 0 5px 5px;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003169}}
span.input-group-addon {
  color: white;
  text-shadow: none !important;
  background-color: #5bb75b;
  background: linear-gradient(to bottom, #62c462, #51a351);
  background-repeat: repeat-x;
  border-color: #51a351 #51a351 #387038;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003180}}
.delete {
  margin: 10px 0 0 0;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003183}}
.help {
  margin-left: 4px;
  border: 1px black solid;
  height: 15px;
  width: 15px;
  border-radius: 15px;
  background-color: black;
  color: white;
  text-align: center;
  display: inline-block;
  font-weight: bolder;
  text-decoration: none;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003196}}
#advance-toggle {
  text-decoration: none;
  color: white;
  margin: 0 0 5px 0;
  display: block;
  font-weight: bolder;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003203}}
#advanced-toggle:hover {
  color: #c8c8c8;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003206}}
.status {
  margin: 20px 0 0 0;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003209}}
#submit {
  float: left;
  margin-right: 3px;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003212}}
#submit.loading {
  opacity: 0.5;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003215}}
progress {
  display: none;
  float: left;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003220}}
#passwordModal h3, #passwordModal h4 {
  color: black;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003222}}
#passwordModal input {
  width: 200px;
}
@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003224}}
#passwordModal .modal-header {
  background: whitesmoke;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003227}}
.clear {
  float: none;
  clear: both;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003231}}
#downloadProgress {
  margin: 5px 5px 0;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003234}}
#uploadProgress {
  margin: 9px 5px 0;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003237}}
.itemStatus {
  margin-top: 10px;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003240}}
.ajaxLoader {
  display: none;
  float: left;
  width: 24px;
  height: 24px;
  background: url("/img/ajax-loader-pacman.gif") no-repeat;
  margin: 3px 0px;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003248}}
.downloadLoader {
  margin: 0 3px;
}

@media -sass-debug-info{filename{font-family:file\:\/\/\/Users\/samuelreed\/git\/securesha\.re\/public\/css\/style\.sass}line{font-family:\00003251}}
.downloadStatusText {
  float: left;
}

@media(max-width: 700px) {
  #main {
    width: 400px;
  }
  #main .title {
    margin-left: -10px;
  }
  #main .title h1 {
    width: 420px;
    font-size: 35px;
  }
  #main .title h1.small {
    font-size: 16px;
    line-height: 25px;
  }
  #main .title .intro-line {
    width: 420px;
  }
  #main .file-uploader {
    margin-bottom: 470px;
  }
}


<|start_filename|>ember/app/scripts/views/bound_text_field_view.js<|end_filename|>
SecureShare.BoundTextFieldView = Ember.TextField.extend({
  valueBinding: 'content.value',
  contentChanged: function() {
    this.get('controller').get('model').set(
      this.get('content').key,
      this.get('content').value
    ); // ugly, but gets the job done
  }.observes('content.value')
});


<|start_filename|>ember/app/scripts/controllers/file_edit_controller.js<|end_filename|>
SecureShare.FileEditController = Ember.ObjectController.extend({
  save: function(){
    // we're cheating here that there's no commit()
    // but the UI element is already bound to the model
    this.transitionToRoute('user',this.get('model'));
  }
});



<|start_filename|>jquery-spaghetti/app/dom.js<|end_filename|>
$(function() {
  // Basic page JS

  // advanced toggle
  $("#advance-toggle").click(function(){
    $("#inner-advanced").slideToggle();
    $(this).find("i").toggleClass("glyphicon-chevron-down");
    explainAdvanced();
  });

  $("#days").change(explainAdvanced);
  $("#views").change(explainAdvanced);

  // Change explanation text
  function explainAdvanced(){
    var $explain = $("#upload-form .explain");
    var days = $("#days").val();
    var views = $("#views").val();
    adjustLabelText(days, views);
    var expirationDate = new Date(new Date().getTime() + (86400000 * days));
    $explain.text("Your file will expire at " + expirationDate.toString() + " or after " + views + " view" +
      (views > 1 ? 's' : '') + ", " + "whichever comes first.");
  }

  function adjustLabelText(days, views) {
    $("#days").siblings('.add-on').text(days == 1 ? 'Day' : 'Days');
    $("#views").siblings('.add-on').text(views == 1 ? 'View' : 'Views');
  }

  // map fileupload
  $(".fileUpload").click(function(){
    $("#fileupload").click(function(e){
      e.stopImmediatePropagation();
    });
    $("#fileupload").click();
  });
});

<|start_filename|>ember/app/scripts/views/file_view.js<|end_filename|>
SecureShare.FileView = Ember.View.extend({
    templateName: 'file'
});


<|start_filename|>ember/app/scripts/routes/files_route.js<|end_filename|>
SecureShare.FilesRoute = Ember.Route.extend({
  model: function() {
    return SecureShare.File.find();
  }
});



<|start_filename|>ember/app/scripts/models/file_model.js<|end_filename|>
SecureShare.File = DS.Model.extend({
    name: DS.attr('string'),

    contents: DS.attr('ArrayBuffer')
});

// probably should be mixed-in...
SecureShare.File.reopen({
  // certainly I'm duplicating something that exists elsewhere...
  attributes: function(){
    var attrs = [];
    var model = this;
    $.each(Em.A(Ember.keys(this.get('data.attributes'))), function(idx, key){
      var pair = { key: key, value: model.get(key) };
      attrs.push(pair);
    });
    return attrs;
  }.property()
});

// delete below here if you do not want fixtures
SecureShare.File.FIXTURES = [
  
  {
    id: 0,
    
    name: 'foo',
    
    contents: 'foo'
    
  },
  
  {
    id: 1,
    
    name: 'foo',
    
    contents: 'foo'
    
  }
  
];


<|start_filename|>jquery-spaghetti/Gruntfile.js<|end_filename|>
'use strict';

var _ = require('lodash');
var matchdep = require('matchdep');

module.exports = function(grunt) {

  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    // The clean task ensures all files are removed from the dist/ directory so
    // that no files linger from previous builds.
    clean: {
      build: ['dist/*']
    },

    // The lint task will run the build configuration and the application
    // JavaScript through JSHint and report any errors.  You can change the
    // options for this task, by reading this:
    // https://github.com/cowboy/grunt/blob/master/docs/task_lint.md
    jshint: {
      validate: {
        src: ['app/**/*.js']
      },
      options: grunt.file.readJSON('.jshintrc')
    },

    compass: {
      secureshare: {
        options: {
          // config: "../config.rb",
          // basePath: "../",
          force: false // not necessary unless config_prod changes
        }
      }
    },


    // The jst task compiles all application templates into JavaScript
    // functions with the underscore.js template function from 1.2.4.  You can
    // change the namespace and the template options, by reading this:
    // https://github.com/gruntjs/grunt-contrib/blob/master/docs/jst.md
    //
    // The concat task depends on this file to exist, so if you decide to
    // remove this, ensure concat is updated accordingly.
    jst: {
      'dist/templates.js': [
        'app/templates/**/*.tpl'
      ],
      options: {
        processName: function(fileName) {
          return '/' + fileName; // add leading slash to fileName so layoutmanager sees it
        }
      }

    },

    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
                '<%= grunt.template.today("yyyy-mm-dd") %> */',
        sourceMap: function(dest){
          return dest + ".map";
        },
      },
      secureshare: {
        files: { // 'dest' : ['src']
          'dist/build.js' : [
            'dist/templates.js',
            'app/**/*.js'
          ]
        },
      },
    },

    md5: {
      compile: {
        files: [
          {src: 'dist/build.js', dest: 'dist/'},
          {src: 'css/style.css', dest: 'dist/'}
        ],
        //overide the paths in the index.html with the new md5 name
        options: {
          after: function(fileChanges, options) {
            var fs = require('fs');
            var files = {
              'index.html': fs.readFileSync('index.html', 'utf8')
            };
            // Iterate through files & replace contents based on md5
            Object.keys(files).forEach(function(fileName) {
              var file = files[fileName];
              fileChanges.forEach(function(fileChange) {
                // Remove webroot
                fileChange.newPath = fileChange.newPath.replace('webroot/', '');
                file = file.replace(fileChange.oldPath, fileChange.newPath);
              });
              fs.writeFileSync(fileName, file);
            });
          },
          keepExtension: true,
          keepBasename: true,
          encoding: 'utf8'
        }
      }
    },

    /**
     * Dev tasks
     */

    // Live reloading
    watch: {
      options: {
        //nospawn: true // This is faster but can cause problems over time
      },
      // This will simply refresh on a script change, nothing more. Not always the right answer.
      // Would love chrome debugger code hot swapping.
      scripts: {
        files: ['app/**/*.js'],
        tasks: [],
        options: {
          livereload: false
        },
      },
      templates: {
        files: ['app/**/*.tpl'],
        tasks: ['jst'],
        options: {
          livereload: false
        }
      },
      sass: {
        files: ['css/*.sass'],
        tasks: ['compass:dev'],
        options: {
          livereload: false // this will refresh the browser if true
        }
      },
      css: {
        files: ['css/**/*'],
        options: {
          livereload: true
        }
      },
    }

  });

  /**
   * Main tasks
   */

  _.each(matchdep.filterAll('grunt-*'), function(pkgName){
    grunt.loadNpmTasks(pkgName);
  });


  // The debug task will remove all contents inside the dist/ folder, lint
  // all your code, precompile all the underscore templates into
  // dist/debug/templates.js, compile all the application code into
  // dist/debug/require.js, and then concatenate the require/define shim
  // almond.js and dist/debug/templates.js into the require.js file.
  grunt.registerTask('debug', ['clean:build', 'jshint', 'jst', 'compass'/*, "jsdoc"*/]);

  // The release task will run the debug tasks and then minify the
  // dist/debug/require.js file and CSS files.
  grunt.registerTask('release', ['debug', 'uglify', 'md5']);

  grunt.registerTask('default', ['release']);
};


<|start_filename|>jquery-spaghetti/app/shared.js<|end_filename|>
/*global _:true, escape: true, CryptoJS: true */
window.secureShared = {
  chunkSize : 64 * 1024, // 64kb chunks
  chunkDelimiter : "/--delimiter--/",
  fileSizeLimit: 20 * 1024 * 1024,
  workerCount : 4,
  spawnWorkers : function(workerCount){
    var workers = [];
    for(var i = 0; i < workerCount; i++){
      workers.push(new Worker("app/crypto.js"));
    }
    return workers;
  },

  convertLatin1ToUtf8 : function(str){
    return decodeURIComponent(escape(str));
  },

  // Generate a 256-bit key. 
  generatePassphrase: function() {
    // If window.crypto is available, use it.
    var passphrase;
    if(window.crypto && typeof window.crypto.getRandomValues === "function"){
      var array = new Uint8Array(32);
      window.crypto.getRandomValues(array);
      passphrase = window.secureShared.ab2str(array.buffer);
    }
    // Otherwise, use CryptoJS internals.
    else {
      passphrase = CryptoJS.enc.Base64.stringify(CryptoJS.lib.WordArray.random(32));
    }
    return window.secureShared.urlSafeBase64encode(passphrase);
  },

  // Create url-safe base64 string from array buffer.
  ab2str: function(buf) {
    return window.btoa(String.fromCharCode.apply(null, new Uint8Array(buf)));
  },

  // Create an array buffer from a string.
  str2ab : function(str) {
    var buf = new ArrayBuffer(str.length); // 2 bytes for each char
    var bufView = new Uint8Array(buf);
    for (var i=0, strLen=str.length; i<strLen; i++) {
      bufView[i] = str.charCodeAt(i);
    }
    return buf;
  },

  // Convert a base64 string into something url-safe.
  urlSafeBase64encode: function(input) {
    return input.replace(/\+/g, '-').replace(/\//, '_').replace(/\=/g, ''); // '=' is padding char and can be removed
  },

  // Reverse the above process.
  urlSafeBase64decode: function(input) {
    return input.replace(/-/g, '+').replace(/_/, '/');
  },

  showStatusMessage: function(message){
  },

  fileSize: function(fileSizeInBytes) {
    var i = -1;
    var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
    do {
      fileSizeInBytes = fileSizeInBytes / 1024;
      i++;
    } while (fileSizeInBytes > 1024);

    return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
  }
};


<|start_filename|>ember/app/scripts/routes/file_edit_route.js<|end_filename|>
SecureShare.FileEditRoute = Ember.Route.extend({
  model: function(model) {
    return SecureShare.File.find(model.file_id);
  }
});



<|start_filename|>polymer/app/scripts/workers/vendor/formatters.js<|end_filename|>
/*jshint worker:true*/
/*global CryptoJS:true */
'use strict';

// Must be included after cryptoJS

var Latin1Formatter = {
  /**
   * Converts a cipher params object to an OpenSSL-style string using Latin1
   *
   * @param {CipherParams} cipherParams The cipher params object.
   *
   * @return {string} The OpenSSL-style string.
   *
   */
  stringify: function (cipherParams, opts) {
    // Shortcuts
    var ciphertext = cipherParams.ciphertext;
    var salt = cipherParams.salt;
    var wordArray;

    // Format
    if (salt) {
      wordArray = CryptoJS.lib.WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
    } else {
      wordArray = ciphertext;
    }
    var output = wordArray.toString(CryptoJS.enc.Latin1);

    return output;
  },

  /**
   * Converts an OpenSSL-style string using Latin1 to a cipher params object.
   *
   * @param {string} openSSLStr The OpenSSL-style string.
   *
   * @return {CipherParams} The cipher params object.
   *
   */
  parse: function (str) {
    // Parse base64
    var ciphertext = CryptoJS.enc.Latin1.parse(str), salt;

    // Test for salt
    if (ciphertext.words[0] === 0x53616c74 && ciphertext.words[1] === 0x65645f5f) {
      // Extract salt
      salt = CryptoJS.lib.WordArray.create(ciphertext.words.slice(2, 4));

      // Remove salt from ciphertext
      ciphertext.words.splice(0, 4);
      ciphertext.sigBytes -= 16;
    }

    return CryptoJS.lib.CipherParams.create({ ciphertext: ciphertext, salt: salt });
  }
};

<|start_filename|>ember/app/scripts/store.js<|end_filename|>
SecureShare.Store = DS.Store.extend({
    adapter: DS.FixtureAdapter.create()
});


<|start_filename|>polymer/app/scripts/shared.js<|end_filename|>
'use strict';
window.secureShared = {
  chunkSize : 512 * 1024, // 512kb chunks
  fileSizeLimit: 20 * 1024 * 1024, // 20MB
  workerCount : 1,

  getHash: function() {
    // parse hash
    var hash = (function(a) {
      if (a === '') return {};
      var b = {};
      for (var i = 0; i < a.length; ++i)
      {
        var p=a[i].split('=');
        if (p.length !== 2) continue;
        b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, ' '));
      }
      return b;
    })(window.location.hash.substr(1).split('&'));
    return hash;
  }

};

<|start_filename|>ember/app/scripts/views/file_edit_view.js<|end_filename|>
SecureShare.FileEditView = Ember.View.extend({
    templateName: 'file_edit'
});


<|start_filename|>polymer/app/scripts/workers/vendor/lib-typedarrays.js<|end_filename|>
/*
CryptoJS v3.x
code.google.com/p/crypto-js
(c) 2009-2013 by <NAME>. All rights reserved.
code.google.com/p/crypto-js/wiki/License
r667
*/
(function (ArrayBuffer, Uint8Array, Uint8ClampedArray) {
    // Ensure typed arrays are supported before proceeding
    if (!ArrayBuffer) {
        return;
    }

    // Shortcuts
    var C = CryptoJS;
    var C_lib = C.lib;
    var WordArray = C_lib.WordArray;

    /**
     * Initializes a newly created word array.
     *
     * @param {ArrayBuffer|ArrayBufferView} typedArray A typed array buffer or view
     */
    var superInit = WordArray.init;
    var subInit   = WordArray.init = function (typedArray) {
        // Convert ArrayBuffer to Uint8Array
        if (typedArray instanceof ArrayBuffer) {
            typedArray = new Uint8Array(typedArray);
        }

        // Convert other ArrayBufferViews to Uint8Array
        if (
            typedArray instanceof Int8Array ||
            (
                // Safari doesn't seem to support Uint8ClampedArray
                Uint8ClampedArray && typedArray instanceof Uint8ClampedArray
            ) ||
            typedArray instanceof Int16Array ||
            typedArray instanceof Uint16Array ||
            typedArray instanceof Int32Array ||
            typedArray instanceof Uint32Array ||
            typedArray instanceof Float32Array ||
            typedArray instanceof Float64Array ||
            typedArray instanceof DataView
        ) {
            typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength);
        }

        // Handle Uint8Array
        if (typedArray instanceof Uint8Array) {
            // Shortcut
            var typedArrayByteLength = typedArray.byteLength;

            // Extract bytes
            var words = [];
            for (var i = 0; i < typedArrayByteLength; i++) {
                words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8);
            }

            // Initialize this word array
            superInit.call(this, words, typedArrayByteLength);
        } else {
            // Else call normal init
            superInit.apply(this, arguments);
        }
    };
    subInit.prototype = WordArray;

    /**
     * Converts this word array to an array buffer.
     *
     * @returns {ArrayBuffer} The array buffer.
     */
    WordArray.toArrayBuffer = function () {
        // Shortcuts
        var words = this.words;
        var sigBytes = this.sigBytes;

        // Create buffer
        var arrayBuffer = new ArrayBuffer(sigBytes);
        var uint8View = new Uint8Array(arrayBuffer);

        // Copy data into buffer
        for (var i = 0; i < sigBytes; i++) {
            uint8View[i] = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
        }

        return arrayBuffer;
    };
}(ArrayBuffer, Uint8Array, Uint8ClampedArray));


<|start_filename|>polymer/app/scripts/workers/xhrWorker.js<|end_filename|>
/*jshint worker:true*/
'use strict';

// This simple worker joins the fileData together and encodes the part.
// With large files, this gets really slow, so I put it here instead.
self.onmessage = function (oEvent) {
  encodeFileData(oEvent);
};

function encodeFileData(oEvent){
  var r20 = /%20/g;
  // Join chunks on chunk delimiter
  var fileData = oEvent.data.fileData;
  for(var i = 0; i < fileData.length; i++) {
    fileData[i] = encodeURIComponent(fileData[i]).replace(r20, '+');
  }
  // Join file chunks by the delimiter. This is intentional - the chunks need to be decrypted
  // the same way they were encrypted, so this delimiter allows us to split the chunks again
  // when they come back down.
  oEvent.data.fileData = new Blob([fileData.join(oEvent.data.chunkDelimiter)]);

  postMessage(oEvent.data);
}

<|start_filename|>polymer/app/scripts/workers/crypto.js<|end_filename|>
/*jshint worker:true*/
/*global CryptoJS:true, FileReaderSync:true, Latin1Formatter:true */
'use strict';
importScripts('/bower_components/crypto-js/rollups/aes.js');
importScripts('vendor/lib-typedarrays.js');
importScripts('vendor/formatters.js'); // returns Latin1Formatter

// shortcut
var WordArray = CryptoJS.lib.WordArray;

self.onmessage = function (oEvent) {
  var data = oEvent.data;
  if (data instanceof Object && data.encrypt) {
    encrypt(data);
  } else if (data instanceof Object && data.decrypt) {
    decrypt(data);
  }
};

// Encrypt a file. `data.slice` is always a Blob object.
// If the browser supports XHR2 (it pretty much has to, to get to this point anyway),
// we output a typed array instead of a string.
function encrypt(data){
  var encrypted = {index: data.index}; // keep index for eventual rebuilding
  var cipherParams;

  // Encrypt filename
  if (data.fileName) {
    encrypted.fileName = CryptoJS.AES.encrypt(data.fileName, data.passphrase).toString();
  }

  if (data.slice) {
    cipherParams = CryptoJS.AES.encrypt(_getWordArrayFromSlice(data.slice, data.useTypedArrays), data.passphrase);
    if (data.useTypedArrays) {
      encrypted.fileData = _createArrayBufferFromCipherParams(cipherParams);
    } else {
      encrypted.fileData = cipherParams.toString(Latin1Formatter);
    }
  }

  postMessage(encrypted);
}

// Decrypt a file. It can come in as a string (old browsers) or as a 
// Blob or ArrayBuffer in newer browsers.
function decrypt(data){
  var decrypted = {index: data.index};
  var fileData, cipherParams;

  // Wrap the decryption in a try/catch. If the password is wrong or the data garbled, it will throw.
  try{
    // Decrypt fileName if present
    if(data.fileName){
      decrypted.fileName = CryptoJS.AES.decrypt(data.fileName, data.passphrase).toString(CryptoJS.enc.Latin1);
    }

    // Decrypt fileData
    if (data.useTypedArrays) {
      fileData = _getWordArrayFromSlice(data.slice, data.useTypedArrays);
      cipherParams = _createCipherParamsFromWordArray(fileData);
      decrypted.fileData = CryptoJS.AES.decrypt(cipherParams, data.passphrase).toArrayBuffer();
    } else {
      fileData = Latin1Formatter.parse(data.slice); // create wordArray from encrypted Latin1
      decrypted.fileData = CryptoJS.AES.decrypt(fileData, data.passphrase).toString(CryptoJS.enc.Utf8);
    }

    postMessage(decrypted);
  } catch (e){
    postMessage('Error: ' + e); // usually bad password
  }
}

// Given a slice (which is likely a blob), turn it into a wordarray.
// If we support typed arrays use those instead of strings, they're faster.
// If `slice` is already a typed array it will be passed directly into the
// WordArray constructor.
// 3.1.2 of CryptoJS lets us pass a typed array directly into an encrypt/decrypt function,
// but r667 (newer) deletes that functionality. This works in both.
function _getWordArrayFromSlice(slice, useTypedArrays) {
  var data = slice;
  if (Object.prototype.toString.call(slice) === '[object Blob]'){
    var fileReader = new FileReaderSync();
    if (useTypedArrays) {
      data = fileReader.readAsArrayBuffer(slice);
    } else {
      data = fileReader.readAsBinaryString(slice);
    }
  }
  return WordArray.create(data);
}

// These parsing functions are similar to the Latin1Formatter.
// Append magical salt value to outgoing ArrayBuffer.
function _createArrayBufferFromCipherParams(cipherParams) {
  var wordArray = WordArray.create([0x53616c74, 0x65645f5f])
    .concat(cipherParams.salt).concat(cipherParams.ciphertext);
  return wordArray.toArrayBuffer();
}

// Pretty much copy/paste from Latin1Formatter
function _createCipherParamsFromWordArray(wordArray) {
  var salt;

  // Test for salt
  if (wordArray.words[0] === 0x53616c74 && wordArray.words[1] === 0x65645f5f) {
    // Extract salt
    salt = CryptoJS.lib.WordArray.create(wordArray.words.slice(2, 4));

    // Remove salt from ciphertext
    wordArray.words.splice(0, 4);
    wordArray.sigBytes -= 16;
  }

  return CryptoJS.lib.CipherParams.create({ ciphertext: wordArray, salt: salt });
}

<|start_filename|>ember/app/scripts/router.js<|end_filename|>
SecureShare.Router.map(function () {
  
  this.resource('file_edit');
  this.resource('file_edit', { path: '/file_edit/:file_edit_id' });
  this.resource('file_edit.edit', { path: '/file_edit/:file_edit_id/edit' });
  
  this.resource('files');
  this.resource('file', { path: '/file/:file_id' });
  this.resource('file.edit', { path: '/file/:file_id/edit' });
  
});


<|start_filename|>ember/app/scripts/views/files_view.js<|end_filename|>
SecureShare.FilesView = Ember.View.extend({
    templateName: 'files'
});
