<commit_before>/**
 * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

define(['require', 'lodash', 'jquery', 'log', 'backbone', 'file_browser', 'bootstrap','ace/ace'],
    function (require, _, $, log, Backbone, FileBrowser,ace) {
        var SaveToFileDialog = Backbone.View.extend(
            /** @lends SaveToFileDialog.prototype */
            {
                /**
                 * @augments Backbone.View
                 * @constructs
                 * @class SaveToFileDialog
                 * @param {Object} config configuration options for the SaveToFileDialog
                 */
                initialize: function (options) {
                    this.app = options;
                    this.dialog_container = $(_.get(options.config.dialog, 'container'));
                    this.notification_container = _.get(options.config.tab_controller.tabs.tab.das_editor.notifications,
                        'container');
                },

                show: function(){
                    var self = this;
                    this._fileSaveModal.modal('show').on('shown.bs.modal', function(){
                        self.trigger('loaded');
                    });
                    this._fileSaveModal.on('hidden.bs.modal', function(){
                        self.trigger('unloaded');
                    })
                },

                setSelectedFile: function(path, fileName){
                    this._fileBrowser.select(path);
                    if(!_.isNil(this._configNameInput)){
                        this._configNameInput.val(fileName);
                    }
                },
                render: function (tabInstance) {
                    var self = this;
                    var fileBrowser;
                    var app = this.app;
                    var notification_container = this.notification_container;
                    var workspaceServiceURL = app.config.services.workspace.endpoint;
                    var activeTab;
                    if(tabInstance !== undefined) {
                        activeTab = tabInstance;
                    } else {
                        activeTab = app.tabController.activeTab;
                    }

                    var siddhiFileEditor= activeTab.getSiddhiFileEditor();
                    var content = siddhiFileEditor.getContent();
                    var plan_regex = /@[Aa][Pp][Pp]:[Nn][Aa][Mm][Ee]\(['|"](.*?)['|"]\)/g;
                    var providedAppContent = plan_regex.exec(content);
                    var providedFileName = "";

                    if (providedAppContent && providedAppContent[1]) {
                        providedFileName = providedAppContent[1].replace(/ /g, "_");
                    }
                    providedFileName = providedFileName.replace("\"","");

                    if(!_.isNil(this._fileSaveModal)){
                        this._fileSaveModal.remove();
                    }

                    var fileSave = $(
                        "
" +
                        "
" +
                        "
" +
                        "
" +
                        "<button type='button' class='close' data-dismiss='modal' aria-label='Close'>" +
                        "×" +
                        "</button>" +
                        "
Save To Workspace
" +
                        "
"+
                        "
" +
                        "
" +
                        "
" +
                        "<form class='form-horizontal' onsubmit='return false'>" +
                        "
" +
                        "File Name :" +
                        "
" +
                        "<input class='file-dialog-form-control' id='configName' name='siddhiAppName' placeholder='"+ providedFileName +"'>" +
                        "
" +
                        "
" +
                        "
" +
                        "
" +
                        "<button id='saveButton' type='button' class='btn btn-primary'>save" +
                        "</button>" +
                        "
" +
                        "<button type='cancelButton' class='btn btn-default' data-dismiss='modal'>cancel</button>" +
                        "
" +
                        "</form>" +
                        "
" +
                        "Error! Something went wrong." +
                        "
" +
                        "
" +
                        "
" +
                        "
" +
                        "
" +
                        "
"
                    );

                    var successNotification = $(
                        "
"+
                        ""+
                        "Configuration saved successfully !"+
                        ""+
                        "
");

                    function getErrorNotification(detailedErrorMsg) {
                        var errorMsg = "Error while saving configuration";
                        if (!_.isEmpty(detailedErrorMsg)){
                            errorMsg += (" : " + detailedErrorMsg);
                        }
                        return $(
                            "
" +
                            "" +
                            errorMsg +
                            "" +
                            "
");
                    }

                    var saveConfigModal = fileSave.filter("#saveConfigModal");
                    var saveWizardError = fileSave.find("#saveWizardError");
                    var location = fileSave.find("input").filter("#location");
                    var configName = fileSave.find("input").filter("#configName");
                    this._configNameInput = configName;

                    //Gets the selected location from tree and sets the value as location
                    this.listenTo(fileBrowser, 'selected', function (selectedLocation) {
                        if(selectedLocation){
                            location.val(selectedLocation);
                        }
                    });

                    fileSave.find("button").filter("#saveButton").click(function() {
                        var _location = location.val();
                        var _configName = configName.val();
                        var replaceContent = false;

                        if (_.isEmpty(_configName)) {
                            _configName = providedFileName;
                        }else{
                            _configName = _configName.trim();
                        }

                        if(!_configName.endsWith(".siddhi")){
                            _configName = _configName + ".siddhi";
                        }

                        if(_configName != providedFileName){
                            replaceContent = true;
                        }

                        var callback = function(isSaved) {
                            self.trigger('save-completed', isSaved);
                            if (isSaved) {
                                saveConfigModal.modal('hide');
                            }
                        };

                        var existsResponse = existFileInPath({configName: _configName});

                        if(existsResponse.error == undefined){
                            if(existsResponse.exists) {
                                // File with this name already exists. Need confirmation from user to replace
                                var replaceConfirmCb = function(confirmed) {
                                    if(confirmed) {
                                        saveConfiguration({location: _location, configName: _configName,
                                                replaceContent: replaceContent, oldAppName: providedFileName},
                                            callback, tabInstance);
                                    } else {
                                        callback(false);
                                    }
                                };

                                var options = {
                                    path: existsResponse.file,
                                    handleConfirm: replaceConfirmCb
                                };

                                self.app.commandManager.dispatch('open-replace-file-confirm-dialog', options);
                            } else {
                                saveConfiguration({location: _location, configName: _configName, replaceContent:
                                    replaceContent, oldAppName: providedFileName}, callback, tabInstance);
                            }
                        }else {
                            saveWizardError.text("Error in reading the file location "+_location);
                            saveWizardError.show();
                        }

                    });

                    $(this.dialog_container).append(fileSave);
                    saveWizardError.hide();
                    this._fileSaveModal = fileSave;

                    function alertSuccess(){
                        $(notification_container).append(successNotification);
                        successNotification.fadeTo(2000, 200).slideUp(1000, function(){
                            successNotification.slideUp(1000);
                        });
                    }

                    function alertError(errorMessage) {
                        var errorNotification = getErrorNotification(errorMessage);
                        $(notification_container).append(errorNotification);
                        errorNotification.fadeTo(2000, 200).slideUp(1000, function () {
                            errorNotification.slideUp(1000);
                        });
                    }

                    function isJsonString(str) {
                        try {
                            JSON.parse(str);
                        } catch (e) {
                            return false;
                        }
                        return true;
                    }

                    function existFileInPath(options){
                        var client = self.app.workspaceManager.getServiceClient();
                        var data = {};
                        var workspaceServiceURL = app.config.services.workspace.endpoint;
                        var saveServiceURL = workspaceServiceURL + "/exists/workspace";
                        var payload = "configName=" + self.app.utils.base64EncodeUnicode(options.configName);

                        $.ajax({
                            type: "POST",
                            contentType: "text/plain; charset=utf-8",
                            url: saveServiceURL,
                            data: payload,
                            async: false,
                            success: function (response) {
                                data = response;
                            },
                            error: function(xhr, textStatus, errorThrown){
                                data = client.getErrorFromResponse(xhr, textStatus, errorThrown);
                                log.error(data.message);
                            }
                        });
                        return data;
                    }

                    function saveConfiguration(options, callback, tabInstance) {
                        var workspaceServiceURL = app.config.services.workspace.endpoint;
                        var saveServiceURL = workspaceServiceURL + "/write";
                        var activeTab;
                        if(tabInstance !== undefined) {
                            activeTab = tabInstance;
                        } else {
                            activeTab = app.tabController.activeTab;
                        }
                        var siddhiFileEditor= activeTab.getSiddhiFileEditor();
                        var config = siddhiFileEditor.getContent();
                        var regexToExtractAppNameAnnotation = /@[Aa][Pp][Pp]:[Nn][Aa][Mm][Ee]\(['|"]/g;
                        var appNameAnnotation = regexToExtractAppNameAnnotation.exec(config)[0];
                        var unicodeOfLastCharacter =
                            appNameAnnotation.charCodeAt(appNameAnnotation.length-1);
                        var wrappingCodeTobeUsed = "";
                        if(unicodeOfLastCharacter == 39){
                            wrappingCodeTobeUsed = "\'";
                        }else if(unicodeOfLastCharacter == 34){
                            wrappingCodeTobeUsed = "\"";
                        }

                        var appNameToAdd = appNameAnnotation + options.configName.substring
                        (0, options.configName.lastIndexOf(".siddhi")) + wrappingCodeTobeUsed + ")";
                        var appNameToRemove = appNameAnnotation + options.oldAppName + wrappingCodeTobeUsed + ")";
                        if(options.replaceContent){
                            config = config.replace(appNameToRemove,'');
                            config = appNameToAdd + config;
                        }

                        var payload = "configName=" + self.app.utils.base64EncodeUnicode(options.configName) +
                            "&config=" + self.app.utils.base64EncodeUnicode(config);

                        $.ajax({
                            url: saveServiceURL,
                            type: "POST",
                            data: payload,
                            contentType: "text/plain; charset=utf-8",
                            async: false,
                            success: function (data, textStatus, xhr) {
                                if (xhr.status == 200) {
                                    activeTab.setTitle(options.configName);
                                    activeTab.getFile()
                                        .setPath(options.location)
                                        .setName(options.configName)
                                        .setContent(config)
                                        .setPersisted(true)
                                        .setLastPersisted(_.now())
                                        .setDirty(false)
                                        .save();
                                    app.commandManager.dispatch("open-folder", data.path);
                                    if(!app.workspaceExplorer.isActive()){
                                        app.commandManager.dispatch("toggle-file-explorer");
                                    }
                                    //app.breadcrumbController.setPath(options.location, options.configName);
                                    saveConfigModal.modal('hide');
                                    app.workspaceManager.updateMenuItems();
                                    var trimmedSiddhiAppName = options.configName;
                                    if (checkEndsWithSiddhi(trimmedSiddhiAppName)) {
                                        trimmedSiddhiAppName = trimmedSiddhiAppName.slice(0, -7);
                                    }
                                    app.commandManager.dispatch('remove-unwanted-streams-single-simulation',
                                        trimmedSiddhiAppName);
                                    log.debug('file saved successfully');
                                    siddhiFileEditor.setContent(config);
                                    callback(true);
                                } else {
                                    saveWizardError.text(data.Error);
                                    saveWizardError.show();
                                    callback(false);
                                }
                            },
                            error: function(res, errorCode, error){
                                var msg = _.isString(error) ? error : res.statusText;
                                if(isJsonString(res.responseText)){
                                    var resObj = JSON.parse(res.responseText);
                                    if(_.has(resObj, 'Error')){
                                        msg = _.get(resObj, 'Error');
                                    }
                                }
                                saveWizardError.text(msg);
                                saveWizardError.show();
                                callback(false);
                            }
                        });
                    }

                    function checkEndsWithSiddhi(string) {
                        return string.endsWith(".siddhi");
                    }
                }
            });

        return SaveToFileDialog;
    });
<commit_msg>Fix - style for save to workspace dialog box<commit_after>/**
 * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

define(['require', 'lodash', 'jquery', 'log', 'backbone', 'file_browser', 'bootstrap','ace/ace'],
    function (require, _, $, log, Backbone, FileBrowser,ace) {
        var SaveToFileDialog = Backbone.View.extend(
            /** @lends SaveToFileDialog.prototype */
            {
                /**
                 * @augments Backbone.View
                 * @constructs
                 * @class SaveToFileDialog
                 * @param {Object} config configuration options for the SaveToFileDialog
                 */
                initialize: function (options) {
                    this.app = options;
                    this.dialog_container = $(_.get(options.config.dialog, 'container'));
                    this.notification_container = _.get(options.config.tab_controller.tabs.tab.das_editor.notifications,
                        'container');
                },

                show: function(){
                    var self = this;
                    this._fileSaveModal.modal('show').on('shown.bs.modal', function(){
                        self.trigger('loaded');
                    });
                    this._fileSaveModal.on('hidden.bs.modal', function(){
                        self.trigger('unloaded');
                    })
                },

                setSelectedFile: function(path, fileName){
                    this._fileBrowser.select(path);
                    if(!_.isNil(this._configNameInput)){
                        this._configNameInput.val(fileName);
                    }
                },
                render: function (tabInstance) {
                    var self = this;
                    var fileBrowser;
                    var app = this.app;
                    var notification_container = this.notification_container;
                    var workspaceServiceURL = app.config.services.workspace.endpoint;
                    var activeTab;
                    if(tabInstance !== undefined) {
                        activeTab = tabInstance;
                    } else {
                        activeTab = app.tabController.activeTab;
                    }

                    var siddhiFileEditor= activeTab.getSiddhiFileEditor();
                    var content = siddhiFileEditor.getContent();
                    var plan_regex = /@[Aa][Pp][Pp]:[Nn][Aa][Mm][Ee]\(['|"](.*?)['|"]\)/g;
                    var providedAppContent = plan_regex.exec(content);
                    var providedFileName = "";

                    if (providedAppContent && providedAppContent[1]) {
                        providedFileName = providedAppContent[1].replace(/ /g, "_");
                    }
                    providedFileName = providedFileName.replace("\"","");

                    if(!_.isNil(this._fileSaveModal)){
                        this._fileSaveModal.remove();
                    }

                    var fileSave = $(
                        "
" +
                        "
" +
                        "
" +
                        "
" +
                        "<button type='button' class='close' data-dismiss='modal' aria-label='Close'>" +
                        "" +
                        "</button>" +
                        "
Save To Workspace
" +
                        "
"+
                        "
" +
                        "
" +
                        "
" +
                        "<form class='form-horizontal' onsubmit='return false'>" +
                        "
" +
                        "File Name :" +
                        "
" +
                        "<input class='file-dialog-form-control' id='configName' name='siddhiAppName' placeholder='"+ providedFileName +"'>" +
                        "
" +
                        "
" +
                        "
" +
                        "
" +
                        "<button id='saveButton' type='button' class='btn btn-primary'>save" +
                        "</button>" +
                        "
" +
                        "<button type='cancelButton' class='btn btn-default' data-dismiss='modal'>cancel</button>" +
                        "
" +
                        "</form>" +
                        "
" +
                        "Error! Something went wrong." +
                        "
" +
                        "
" +
                        "
" +
                        "
" +
                        "
" +
                        "
"
                    );

                    var successNotification = $(
                        "
"+
                        ""+
                        "Configuration saved successfully !"+
                        ""+
                        "
");

                    function getErrorNotification(detailedErrorMsg) {
                        var errorMsg = "Error while saving configuration";
                        if (!_.isEmpty(detailedErrorMsg)){
                            errorMsg += (" : " + detailedErrorMsg);
                        }
                        return $(
                            "
" +
                            "" +
                            errorMsg +
                            "" +
                            "
");
                    }

                    var saveConfigModal = fileSave.filter("#saveConfigModal");
                    var saveWizardError = fileSave.find("#saveWizardError");
                    var location = fileSave.find("input").filter("#location");
                    var configName = fileSave.find("input").filter("#configName");
                    this._configNameInput = configName;

                    //Gets the selected location from tree and sets the value as location
                    this.listenTo(fileBrowser, 'selected', function (selectedLocation) {
                        if(selectedLocation){
                            location.val(selectedLocation);
                        }
                    });

                    fileSave.find("button").filter("#saveButton").click(function() {
                        var _location = location.val();
                        var _configName = configName.val();
                        var replaceContent = false;

                        if (_.isEmpty(_configName)) {
                            _configName = providedFileName;
                        }else{
                            _configName = _configName.trim();
                        }

                        if(!_configName.endsWith(".siddhi")){
                            _configName = _configName + ".siddhi";
                        }

                        if(_configName != providedFileName){
                            replaceContent = true;
                        }

                        var callback = function(isSaved) {
                            self.trigger('save-completed', isSaved);
                            if (isSaved) {
                                saveConfigModal.modal('hide');
                            }
                        };

                        var existsResponse = existFileInPath({configName: _configName});

                        if(existsResponse.error == undefined){
                            if(existsResponse.exists) {
                                // File with this name already exists. Need confirmation from user to replace
                                var replaceConfirmCb = function(confirmed) {
                                    if(confirmed) {
                                        saveConfiguration({location: _location, configName: _configName,
                                                replaceContent: replaceContent, oldAppName: providedFileName},
                                            callback, tabInstance);
                                    } else {
                                        callback(false);
                                    }
                                };

                                var options = {
                                    path: existsResponse.file,
                                    handleConfirm: replaceConfirmCb
                                };

                                self.app.commandManager.dispatch('open-replace-file-confirm-dialog', options);
                            } else {
                                saveConfiguration({location: _location, configName: _configName, replaceContent:
                                    replaceContent, oldAppName: providedFileName}, callback, tabInstance);
                            }
                        }else {
                            saveWizardError.text("Error in reading the file location "+_location);
                            saveWizardError.show();
                        }

                    });

                    $(this.dialog_container).append(fileSave);
                    saveWizardError.hide();
                    this._fileSaveModal = fileSave;

                    function alertSuccess(){
                        $(notification_container).append(successNotification);
                        successNotification.fadeTo(2000, 200).slideUp(1000, function(){
                            successNotification.slideUp(1000);
                        });
                    }

                    function alertError(errorMessage) {
                        var errorNotification = getErrorNotification(errorMessage);
                        $(notification_container).append(errorNotification);
                        errorNotification.fadeTo(2000, 200).slideUp(1000, function () {
                            errorNotification.slideUp(1000);
                        });
                    }

                    function isJsonString(str) {
                        try {
                            JSON.parse(str);
                        } catch (e) {
                            return false;
                        }
                        return true;
                    }

                    function existFileInPath(options){
                        var client = self.app.workspaceManager.getServiceClient();
                        var data = {};
                        var workspaceServiceURL = app.config.services.workspace.endpoint;
                        var saveServiceURL = workspaceServiceURL + "/exists/workspace";
                        var payload = "configName=" + self.app.utils.base64EncodeUnicode(options.configName);

                        $.ajax({
                            type: "POST",
                            contentType: "text/plain; charset=utf-8",
                            url: saveServiceURL,
                            data: payload,
                            async: false,
                            success: function (response) {
                                data = response;
                            },
                            error: function(xhr, textStatus, errorThrown){
                                data = client.getErrorFromResponse(xhr, textStatus, errorThrown);
                                log.error(data.message);
                            }
                        });
                        return data;
                    }

                    function saveConfiguration(options, callback, tabInstance) {
                        var workspaceServiceURL = app.config.services.workspace.endpoint;
                        var saveServiceURL = workspaceServiceURL + "/write";
                        var activeTab;
                        if(tabInstance !== undefined) {
                            activeTab = tabInstance;
                        } else {
                            activeTab = app.tabController.activeTab;
                        }
                        var siddhiFileEditor= activeTab.getSiddhiFileEditor();
                        var config = siddhiFileEditor.getContent();
                        var regexToExtractAppNameAnnotation = /@[Aa][Pp][Pp]:[Nn][Aa][Mm][Ee]\(['|"]/g;
                        var appNameAnnotation = regexToExtractAppNameAnnotation.exec(config)[0];
                        var unicodeOfLastCharacter =
                            appNameAnnotation.charCodeAt(appNameAnnotation.length-1);
                        var wrappingCodeTobeUsed = "";
                        if(unicodeOfLastCharacter == 39){
                            wrappingCodeTobeUsed = "\'";
                        }else if(unicodeOfLastCharacter == 34){
                            wrappingCodeTobeUsed = "\"";
                        }

                        var appNameToAdd = appNameAnnotation + options.configName.substring
                        (0, options.configName.lastIndexOf(".siddhi")) + wrappingCodeTobeUsed + ")";
                        var appNameToRemove = appNameAnnotation + options.oldAppName + wrappingCodeTobeUsed + ")";
                        if(options.replaceContent){
                            config = config.replace(appNameToRemove,'');
                            config = appNameToAdd + config;
                        }

                        var payload = "configName=" + self.app.utils.base64EncodeUnicode(options.configName) +
                            "&config=" + self.app.utils.base64EncodeUnicode(config);

                        $.ajax({
                            url: saveServiceURL,
                            type: "POST",
                            data: payload,
                            contentType: "text/plain; charset=utf-8",
                            async: false,
                            success: function (data, textStatus, xhr) {
                                if (xhr.status == 200) {
                                    activeTab.setTitle(options.configName);
                                    activeTab.getFile()
                                        .setPath(options.location)
                                        .setName(options.configName)
                                        .setContent(config)
                                        .setPersisted(true)
                                        .setLastPersisted(_.now())
                                        .setDirty(false)
                                        .save();
                                    app.commandManager.dispatch("open-folder", data.path);
                                    if(!app.workspaceExplorer.isActive()){
                                        app.commandManager.dispatch("toggle-file-explorer");
                                    }
                                    //app.breadcrumbController.setPath(options.location, options.configName);
                                    saveConfigModal.modal('hide');
                                    app.workspaceManager.updateMenuItems();
                                    var trimmedSiddhiAppName = options.configName;
                                    if (checkEndsWithSiddhi(trimmedSiddhiAppName)) {
                                        trimmedSiddhiAppName = trimmedSiddhiAppName.slice(0, -7);
                                    }
                                    app.commandManager.dispatch('remove-unwanted-streams-single-simulation',
                                        trimmedSiddhiAppName);
                                    log.debug('file saved successfully');
                                    siddhiFileEditor.setContent(config);
                                    callback(true);
                                } else {
                                    saveWizardError.text(data.Error);
                                    saveWizardError.show();
                                    callback(false);
                                }
                            },
                            error: function(res, errorCode, error){
                                var msg = _.isString(error) ? error : res.statusText;
                                if(isJsonString(res.responseText)){
                                    var resObj = JSON.parse(res.responseText);
                                    if(_.has(resObj, 'Error')){
                                        msg = _.get(resObj, 'Error');
                                    }
                                }
                                saveWizardError.text(msg);
                                saveWizardError.show();
                                callback(false);
                            }
                        });
                    }

                    function checkEndsWithSiddhi(string) {
                        return string.endsWith(".siddhi");
                    }
                }
            });

        return SaveToFileDialog;
    });
<|endoftext|>


<commit_before>/*
 * Foundation Responsive Library
 * http://foundation.zurb.com
 * Copyright 2013, ZURB
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
*/

/*jslint unparam: true, browser: true, indent: 2 */

// Accommodate running jQuery or Zepto in noConflict() mode by
// using an anonymous function to redefine the $ shorthand name.
// See http://docs.jquery.com/Using_jQuery_with_Other_Libraries
// and http://zeptojs.com/
var libFuncName = null;

if (typeof jQuery === "undefined" &&
    typeof Zepto === "undefined" &&
    typeof $ === "function") {
  libFuncName = $;
} else if (typeof jQuery === "function") {
  libFuncName = jQuery;
} else if (typeof Zepto === "function") {
  libFuncName = Zepto;
} else {
  throw new TypeError();
}

(function ($, window, document, undefined) {
  'use strict';

  // add dusty browser stuff
  if (!Array.prototype.filter) {
    Array.prototype.filter = function(fun /*, thisp */) {
      "use strict";

      if (this == null) {
        throw new TypeError();
      }

      var t = Object(this),
          len = t.length >>> 0;
      if (typeof fun != "function") {
          return;
      }

      var res = [],
          thisp = arguments[1];
      for (var i = 0; i < len; i++) {
        if (i in t) {
          var val = t[i]; // in case fun mutates this
          if (fun && fun.call(thisp, val, i, t)) {
            res.push(val);
          }
        }
      }

      return res;
    }
  }

  if (!Function.prototype.bind) {
    Function.prototype.bind = function (oThis) {
      if (typeof this !== "function") {
        // closest thing possible to the ECMAScript 5 internal IsCallable function
        throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
      }

      var aArgs = Array.prototype.slice.call(arguments, 1),
          fToBind = this,
          fNOP = function () {},
          fBound = function () {
            return fToBind.apply(this instanceof fNOP && oThis
               ? this
               : oThis,
             aArgs.concat(Array.prototype.slice.call(arguments)));
          };

      fNOP.prototype = this.prototype;
      fBound.prototype = new fNOP();

      return fBound;
    };
  }

  if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
      "use strict";
      if (this == null) {
        throw new TypeError();
      }
      var t = Object(this);
      var len = t.length >>> 0;
      if (len === 0) {
        return -1;
      }
      var n = 0;
      if (arguments.length > 1) {
        n = Number(arguments[1]);
        if (n != n) { // shortcut for verifying if it's NaN
          n = 0;
        } else if (n != 0 && n != Infinity && n != -Infinity) {
          n = (n > 0 || -1) * Math.floor(Math.abs(n));
        }
      }
      if (n >= len) {
          return -1;
      }
      var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
      for (; k < len; k++) {
        if (k in t && t[k] === searchElement) {
          return k;
        }
      }
      return -1;
    }
  }

  // fake stop() for zepto.
  $.fn.stop = $.fn.stop || function() {
    return this;
  };

  window.Foundation = {
    name : 'Foundation',

    version : '4.1.5',

    cache : {},

    init : function (scope, libraries, method, options, response, /* internal */ nc) {
      var library_arr,
          args = [scope, method, options, response],
          responses = [],
          nc = nc || false;

      // disable library error catching,
      // used for development only
      if (nc) this.nc = nc;

      // check RTL
      this.rtl = /rtl/i.test($('html').attr('dir'));

      // set foundation global scope
      this.scope = scope || this.scope;

      if (libraries && typeof libraries === 'string') {
        if (/off/i.test(libraries)) return this.off();

        library_arr = libraries.split(' ');

        if (library_arr.length > 0) {
          for (var i = library_arr.length - 1; i >= 0; i--) {
            responses.push(this.init_lib(library_arr[i], args));
          }
        }
      } else {
        for (var lib in this.libs) {
          responses.push(this.init_lib(lib, args));
        }
      }

      // if first argument is callback, add to args
      if (typeof libraries === 'function') {
        args.unshift(libraries);
      }

      return this.response_obj(responses, args);
    },

    response_obj : function (response_arr, args) {
      for (var i = 0, len = args.length; i < len; i++) {
        if (typeof args[i] === 'function') {
          return args[i]({
            errors: response_arr.filter(function (s) {
              if (typeof s === 'string') return s;
            })
          });
        }
      }

      return response_arr;
    },

    init_lib : function (lib, args) {
      return this.trap(function () {
        if (this.libs.hasOwnProperty(lib)) {
          this.patch(this.libs[lib]);
          return this.libs[lib].init.apply(this.libs[lib], args);
        }
        else {
          return function () {};
        }
      }.bind(this), lib);
    },

    trap : function (fun, lib) {
      if (!this.nc) {
        try {
          return fun();
        } catch (e) {
          return this.error({name: lib, message: 'could not be initialized', more: e.name + ' ' + e.message});
        }
      }

      return fun();
    },

    patch : function (lib) {
      this.fix_outer(lib);
      lib.scope = this.scope;
      lib.rtl = this.rtl;
    },

    inherit : function (scope, methods) {
      var methods_arr = methods.split(' ');

      for (var i = methods_arr.length - 1; i >= 0; i--) {
        if (this.lib_methods.hasOwnProperty(methods_arr[i])) {
          this.libs[scope.name][methods_arr[i]] = this.lib_methods[methods_arr[i]];
        }
      }
    },

    random_str : function (length) {
      var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');

      if (!length) {
          length = Math.floor(Math.random() * chars.length);
      }

      var str = '';
      for (var i = 0; i < length; i++) {
          str += chars[Math.floor(Math.random() * chars.length)];
      }
      return str;
    },

    libs : {},

    // methods that can be inherited in libraries
    lib_methods : {
      set_data : function (node, data) {
        // this.name references the name of the library calling this method
        var id = [this.name,+new Date(),Foundation.random_str(5)].join('-');

        Foundation.cache[id] = data;
        node.attr('data-' + this.name + '-id', id);
        return data;
      },

      get_data : function (node) {
        return Foundation.cache[node.attr('data-' + this.name + '-id')];
      },

      remove_data : function (node) {
        if (node) {
          delete Foundation.cache[node.attr('data-' + this.name + '-id')];
          node.attr('data-' + this.name + '-id', '');
        } else {
          $('[data-' + this.name + '-id]').each(function () {
            delete Foundation.cache[$(this).attr('data-' + this.name + '-id')];
            $(this).attr('data-' + this.name + '-id', '');
          });
        }
      },

      throttle : function(fun, delay) {
        var timer = null;
        return function () {
          var context = this, args = arguments;
          clearTimeout(timer);
          timer = setTimeout(function () {
            fun.apply(context, args);
          }, delay);
        };
      },

      // parses data-options attribute on nodes and turns
      // them into an object
      data_options : function (el) {
        var opts = {}, ii, p,
            opts_arr = (el.attr('data-options') || ':').split(';'),
            opts_len = opts_arr.length;

        function isNumber (o) {
          return ! isNaN (o-0) && o !== null && o !== "" && o !== false && o !== true;
        }

        function trim(str) {
          if (typeof str === 'string') return $.trim(str);
          return str;
        }

        // parse options
        for (ii = opts_len - 1; ii >= 0; ii--) {
          p = opts_arr[ii].split(':');

          if (/true/i.test(p[1])) p[1] = true;
          if (/false/i.test(p[1])) p[1] = false;
          if (isNumber(p[1])) p[1] = parseInt(p[1], 10);

          if (p.length === 2 && p[0].length > 0) {
            opts[trim(p[0])] = trim(p[1]);
          }
        }

        return opts;
      },

      delay : function (fun, delay) {
        return setTimeout(fun, delay);
      },

      // animated scrolling
      scrollTo : function (el, to, duration) {
        if (duration < 0) return;
        var difference = to - $(window).scrollTop();
        var perTick = difference / duration * 10;

        this.scrollToTimerCache = setTimeout(function() {
          if (!isNaN(parseInt(perTick, 10))) {
            window.scrollTo(0, $(window).scrollTop() + perTick);
            this.scrollTo(el, to, duration - 10);
          }
        }.bind(this), 10);
      },

      // not supported in core Zepto
      scrollLeft : function (el) {
        if (!el.length) return;
        return ('scrollLeft' in el[0]) ? el[0].scrollLeft : el[0].pageXOffset;
      },

      // test for empty object or array
      empty : function (obj) {
        if (obj.length && obj.length > 0)    return false;
        if (obj.length && obj.length === 0)  return true;

        for (var key in obj) {
          if (hasOwnProperty.call(obj, key))    return false;
        }

        return true;
      }
    },

    fix_outer : function (lib) {
      lib.outerHeight = function (el, bool) {
        if (typeof Zepto === 'function') {
          return el.height();
        }

        if (typeof bool !== 'undefined') {
          return el.outerHeight(bool);
        }

        return el.outerHeight();
      };

      lib.outerWidth = function (el) {
        if (typeof Zepto === 'function') {
          return el.width();
        }

        if (typeof bool !== 'undefined') {
          return el.outerWidth(bool);
        }

        return el.outerWidth();
      };
    },

    error : function (error) {
      return error.name + ' ' + error.message + '; ' + error.more;
    },

    // remove all foundation events.
    off: function () {
      $(this.scope).off('.fndtn');
      $(window).off('.fndtn');
      return true;
    },

    zj : function () {
      try {
        return Zepto;
      } catch (e) {
        return jQuery;
      }
    }()
  };

  $.fn.foundation = function () {
    var args = Array.prototype.slice.call(arguments, 0);

    return this.each(function () {
      Foundation.init.apply(Foundation, [this].concat(args));
      return this;
    });
  };

}(libFuncName, this, this.document));
<commit_msg>Better method to test for Zepto<commit_after>/*
 * Foundation Responsive Library
 * http://foundation.zurb.com
 * Copyright 2013, ZURB
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
*/

/*jslint unparam: true, browser: true, indent: 2 */

// Accommodate running jQuery or Zepto in noConflict() mode by
// using an anonymous function to redefine the $ shorthand name.
// See http://docs.jquery.com/Using_jQuery_with_Other_Libraries
// and http://zeptojs.com/
var libFuncName = null;

if (typeof jQuery === "undefined" &&
    typeof Zepto === "undefined" &&
    typeof $ === "function") {
  libFuncName = $;
} else if (typeof jQuery === "function") {
  libFuncName = jQuery;
} else if (typeof Zepto === "function") {
  libFuncName = Zepto;
} else {
  throw new TypeError();
}

(function ($, window, document, undefined) {
  'use strict';

  // add dusty browser stuff
  if (!Array.prototype.filter) {
    Array.prototype.filter = function(fun /*, thisp */) {
      "use strict";

      if (this == null) {
        throw new TypeError();
      }

      var t = Object(this),
          len = t.length >>> 0;
      if (typeof fun != "function") {
          return;
      }

      var res = [],
          thisp = arguments[1];
      for (var i = 0; i < len; i++) {
        if (i in t) {
          var val = t[i]; // in case fun mutates this
          if (fun && fun.call(thisp, val, i, t)) {
            res.push(val);
          }
        }
      }

      return res;
    }
  }

  if (!Function.prototype.bind) {
    Function.prototype.bind = function (oThis) {
      if (typeof this !== "function") {
        // closest thing possible to the ECMAScript 5 internal IsCallable function
        throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
      }

      var aArgs = Array.prototype.slice.call(arguments, 1),
          fToBind = this,
          fNOP = function () {},
          fBound = function () {
            return fToBind.apply(this instanceof fNOP && oThis
               ? this
               : oThis,
             aArgs.concat(Array.prototype.slice.call(arguments)));
          };

      fNOP.prototype = this.prototype;
      fBound.prototype = new fNOP();

      return fBound;
    };
  }

  if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
      "use strict";
      if (this == null) {
        throw new TypeError();
      }
      var t = Object(this);
      var len = t.length >>> 0;
      if (len === 0) {
        return -1;
      }
      var n = 0;
      if (arguments.length > 1) {
        n = Number(arguments[1]);
        if (n != n) { // shortcut for verifying if it's NaN
          n = 0;
        } else if (n != 0 && n != Infinity && n != -Infinity) {
          n = (n > 0 || -1) * Math.floor(Math.abs(n));
        }
      }
      if (n >= len) {
          return -1;
      }
      var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
      for (; k < len; k++) {
        if (k in t && t[k] === searchElement) {
          return k;
        }
      }
      return -1;
    }
  }

  // fake stop() for zepto.
  $.fn.stop = $.fn.stop || function() {
    return this;
  };

  window.Foundation = {
    name : 'Foundation',

    version : '4.1.5',

    cache : {},

    init : function (scope, libraries, method, options, response, /* internal */ nc) {
      var library_arr,
          args = [scope, method, options, response],
          responses = [],
          nc = nc || false;

      // disable library error catching,
      // used for development only
      if (nc) this.nc = nc;

      // check RTL
      this.rtl = /rtl/i.test($('html').attr('dir'));

      // set foundation global scope
      this.scope = scope || this.scope;

      if (libraries && typeof libraries === 'string') {
        if (/off/i.test(libraries)) return this.off();

        library_arr = libraries.split(' ');

        if (library_arr.length > 0) {
          for (var i = library_arr.length - 1; i >= 0; i--) {
            responses.push(this.init_lib(library_arr[i], args));
          }
        }
      } else {
        for (var lib in this.libs) {
          responses.push(this.init_lib(lib, args));
        }
      }

      // if first argument is callback, add to args
      if (typeof libraries === 'function') {
        args.unshift(libraries);
      }

      return this.response_obj(responses, args);
    },

    response_obj : function (response_arr, args) {
      for (var i = 0, len = args.length; i < len; i++) {
        if (typeof args[i] === 'function') {
          return args[i]({
            errors: response_arr.filter(function (s) {
              if (typeof s === 'string') return s;
            })
          });
        }
      }

      return response_arr;
    },

    init_lib : function (lib, args) {
      return this.trap(function () {
        if (this.libs.hasOwnProperty(lib)) {
          this.patch(this.libs[lib]);
          return this.libs[lib].init.apply(this.libs[lib], args);
        }
        else {
          return function () {};
        }
      }.bind(this), lib);
    },

    trap : function (fun, lib) {
      if (!this.nc) {
        try {
          return fun();
        } catch (e) {
          return this.error({name: lib, message: 'could not be initialized', more: e.name + ' ' + e.message});
        }
      }

      return fun();
    },

    patch : function (lib) {
      this.fix_outer(lib);
      lib.scope = this.scope;
      lib.rtl = this.rtl;
    },

    inherit : function (scope, methods) {
      var methods_arr = methods.split(' ');

      for (var i = methods_arr.length - 1; i >= 0; i--) {
        if (this.lib_methods.hasOwnProperty(methods_arr[i])) {
          this.libs[scope.name][methods_arr[i]] = this.lib_methods[methods_arr[i]];
        }
      }
    },

    random_str : function (length) {
      var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');

      if (!length) {
          length = Math.floor(Math.random() * chars.length);
      }

      var str = '';
      for (var i = 0; i < length; i++) {
          str += chars[Math.floor(Math.random() * chars.length)];
      }
      return str;
    },

    libs : {},

    // methods that can be inherited in libraries
    lib_methods : {
      set_data : function (node, data) {
        // this.name references the name of the library calling this method
        var id = [this.name,+new Date(),Foundation.random_str(5)].join('-');

        Foundation.cache[id] = data;
        node.attr('data-' + this.name + '-id', id);
        return data;
      },

      get_data : function (node) {
        return Foundation.cache[node.attr('data-' + this.name + '-id')];
      },

      remove_data : function (node) {
        if (node) {
          delete Foundation.cache[node.attr('data-' + this.name + '-id')];
          node.attr('data-' + this.name + '-id', '');
        } else {
          $('[data-' + this.name + '-id]').each(function () {
            delete Foundation.cache[$(this).attr('data-' + this.name + '-id')];
            $(this).attr('data-' + this.name + '-id', '');
          });
        }
      },

      throttle : function(fun, delay) {
        var timer = null;
        return function () {
          var context = this, args = arguments;
          clearTimeout(timer);
          timer = setTimeout(function () {
            fun.apply(context, args);
          }, delay);
        };
      },

      // parses data-options attribute on nodes and turns
      // them into an object
      data_options : function (el) {
        var opts = {}, ii, p,
            opts_arr = (el.attr('data-options') || ':').split(';'),
            opts_len = opts_arr.length;

        function isNumber (o) {
          return ! isNaN (o-0) && o !== null && o !== "" && o !== false && o !== true;
        }

        function trim(str) {
          if (typeof str === 'string') return $.trim(str);
          return str;
        }

        // parse options
        for (ii = opts_len - 1; ii >= 0; ii--) {
          p = opts_arr[ii].split(':');

          if (/true/i.test(p[1])) p[1] = true;
          if (/false/i.test(p[1])) p[1] = false;
          if (isNumber(p[1])) p[1] = parseInt(p[1], 10);

          if (p.length === 2 && p[0].length > 0) {
            opts[trim(p[0])] = trim(p[1]);
          }
        }

        return opts;
      },

      delay : function (fun, delay) {
        return setTimeout(fun, delay);
      },

      // animated scrolling
      scrollTo : function (el, to, duration) {
        if (duration < 0) return;
        var difference = to - $(window).scrollTop();
        var perTick = difference / duration * 10;

        this.scrollToTimerCache = setTimeout(function() {
          if (!isNaN(parseInt(perTick, 10))) {
            window.scrollTo(0, $(window).scrollTop() + perTick);
            this.scrollTo(el, to, duration - 10);
          }
        }.bind(this), 10);
      },

      // not supported in core Zepto
      scrollLeft : function (el) {
        if (!el.length) return;
        return ('scrollLeft' in el[0]) ? el[0].scrollLeft : el[0].pageXOffset;
      },

      // test for empty object or array
      empty : function (obj) {
        if (obj.length && obj.length > 0)    return false;
        if (obj.length && obj.length === 0)  return true;

        for (var key in obj) {
          if (hasOwnProperty.call(obj, key))    return false;
        }

        return true;
      }
    },

    fix_outer : function (lib) {
      lib.outerHeight = function (el, bool) {
        if (typeof Zepto === 'function') {
          return el.height();
        }

        if (typeof bool !== 'undefined') {
          return el.outerHeight(bool);
        }

        return el.outerHeight();
      };

      lib.outerWidth = function (el) {
        if (typeof Zepto === 'function') {
          return el.width();
        }

        if (typeof bool !== 'undefined') {
          return el.outerWidth(bool);
        }

        return el.outerWidth();
      };
    },

    error : function (error) {
      return error.name + ' ' + error.message + '; ' + error.more;
    },

    // remove all foundation events.
    off: function () {
      $(this.scope).off('.fndtn');
      $(window).off('.fndtn');
      return true;
    },

    zj : function () {
      if (typeof Zepto !== 'undefined') {
        return Zepto;
      } else {
        return jQuery;
      }
    }()
  };

  $.fn.foundation = function () {
    var args = Array.prototype.slice.call(arguments, 0);

    return this.each(function () {
      Foundation.init.apply(Foundation, [this].concat(args));
      return this;
    });
  };

}(libFuncName, this, this.document));
<|endoftext|>


<commit_before>function Dataset(nparray) {
    if (nparray instanceof NParray) {
        this.init(nparray);
    }
}
Dataset.fromJSON = function(json) {
    var ds;
    if (json.data instanceof NParray) {
        ds = new Dataset(json.data);
    } else if (typeof(json.data) == "string") {
        ds = new Dataset(null);
        NParray.fromURL(json.data, function(array) {
            ds.init(array);
        });
    }
    if (json.stim !== undefined)
        ds.addStim(json.stim, json.delay);
    ds.min = json.min;
    ds.max = json.max;
    ds.cmap = json.cmap;
    ds.rate = json.rate === undefined ? 1 : json.rate;
    return ds;
}
Dataset.maketex = function(array, shape, raw, slice) {
    //Creates paired textures on top of each other
    var tex, data, form;
    var arr = slice === undefined ? array : array.view(slice);
    var size = array.shape[array.shape.length-1];
    var len = shape[0] * shape[1] * (raw ? size : 1);

    data = new array.data.constructor(len*2);
    data.subarray(0, len).set(arr.data);
    if (slice+1 < array.shape[0]) {
        arr = array.view(slice+1);
        data.subarray(len).set(arr.data);
    }

    if (raw) {
        form = size == 4 ? THREE.RGBAFormat : THREE.RGBFormat;
        tex = new THREE.DataTexture(data, shape[0], shape[1]*2, form, THREE.UnsignedByteType);
    } else {
        tex = new THREE.DataTexture(data, shape[0], shape[1]*2, THREE.LuminanceFormat, THREE.FloatType);
    }
    tex.needsUpdate = true;
    tex.flipY = false;
    tex.minFilter = THREE.NearestFilter;
    tex.magFilter = THREE.NearestFilter;
    return tex;
}
Dataset.prototype = {
    init: function(nparray) {
        this.array = nparray;
        this.raw = nparray.data instanceof Uint8Array && nparray.shape.length > 1;
        this.textures = [];

        if ((this.raw && nparray.shape.length > 2) || (!this.raw && nparray.shape.length > 1)) {
            //Movie
            this.datasize = new THREE.Vector2(256, Math.ceil(nparray.shape[1] / 256));
            for (var i = 0; i < nparray.shape[0]; i++) {
                this.textures.push(Dataset.maketex(nparray, [this.datasize.x, this.datasize.y], this.raw, i));
            }
        } else {
            //Single frame
            this.datasize = new THREE.Vector2(256, Math.ceil(nparray.shape[0] / 256));
            this.textures.push(Dataset.maketex(nparray, [this.datasize.x, this.datasize.y], this.raw));
        }
        var minmax = nparray.minmax();
        this.lmin = minmax[0];
        this.lmax = minmax[1];
        if (this.min === undefined)
            this.min = this.lmin;
        if (this.max === undefined)
            this.max = this.lmax;

        if (this._func !== undefined) {
            this._func();
            delete this._func;
        }
    },
    addStim: function(url, delay) {
        this.delay = delay;
        this.stim = document.createElement("video");
        this.stim.id = "stim_movie";
        this.stim.setAttribute("preload", "");
        this.stim.setAttribute("loop", "loop");
        var src = document.createElement("source");
        var ext = url.match(/^(.*)\.(\w{3,4})$/);
        if (ext.length == 3) {
            if (ext[2] == 'ogv') {
                src.setAttribute('type', 'video/ogg; codecs="theora, vorbis"');
            } else if (ext[2] == 'webm') {
                src.setAttribute('type', 'video/webm; codecs="vp8, vorbis"');
            } else if (ext[2] == 'mp4') {
                src.setAttribute('type', 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
            }
        }
        src.setAttribute("src", url);
        this.stim.appendChild(src);

        allStims.push(this.stim);

        this.stim.seekTo = function(time) {
            if (this.seekable.length > 0 &&
                this.seekable.end(0) >= time) {
                this.currentTime = time;
                $("#pluginload").hide()
                if (typeof(this.callback) == "function")
                    this.callback();
            } else {
                this.seekTarget = time;
                $("#pluginload").show()
            }
        }
        $(this.stim).bind("progress", function() {
            if (this.seekTarget != null &&
                this.seekable.length > 0 &&
                this.seekable.end(0) >= this.seekTarget &&
                this.parentNode != null) {
                var func = function() {
                    try {
                        this.currentTime = this.seekTarget;
                        this.seekTarget = null;
                        $("#pluginload").hide()
                        if (typeof(this.callback) == "function")
                            this.callback();
                    } catch (e) {
                        console.log(e);
                        setTimeout(func, 5);
                    }
                }.bind(this);
                func();
            }
        });
        this.stim.seekTo(delay);
    },
    set: function(viewer, dim) {
        if (dim === undefined)
            dim = 0;
        var func = function() {
            viewer._setShader(this.raw, this.datasize);
            if (this.textures.length > 1) {
                viewer.setFrame(0);
                $("#moviecontrols").show();
                $("#bottombar").addClass("bbar_controls");
                $("#movieprogress div").slider("option", {min:0, max:this.textures.length});
            } else {
                viewer.shader.uniforms['ds_' + (dim ? 'y':'x')].texture = this.textures[0];
                $("#moviecontrols").hide();
                $("#bottombar").removeClass("bbar_controls");
            }

            if (this.cmap !== undefined) {
                viewer.setColormap(this.cmap);
            }

            $(dim == 0 ? "#vrange" : "#vrange2").slider("option", {min: this.lmin, max:this.lmax});
            viewer.setVminmax(this.min, this.max, dim);

            if (dim > 0)
                return;

            if (this.stim === undefined) {
                viewer.rmPlugin();
            } else {
                for (var i = 0; i < allStims.length; i++)
                    $(allStims[i]).unbind("timeupdate");

                var delay = this.delay;
                viewer.addPlugin(this.stim);
                //this.stim.seekTo(viewer.frame + delay);
                $(this.stim).bind("timeupdate", function() {
                    var now = new Date().getTime() / 1000;
                    var sec = now - viewer._startplay / 1000;
                    console.log("Time diff: "+(this.currentTime - delay - sec));
                    viewer._startplay = (now - this.currentTime + delay)*1000;
                })
            }
        }.bind(this);
        if (this.array !== undefined)
            func();
        else
            this._func = func;
    },
}<commit_msg>Limit the movie to the maximum length<commit_after>function Dataset(nparray) {
    if (nparray instanceof NParray) {
        this.init(nparray);
    }
}
Dataset.fromJSON = function(json) {
    var ds;
    if (json.data instanceof NParray) {
        ds = new Dataset(json.data);
    } else if (typeof(json.data) == "string") {
        ds = new Dataset(null);
        NParray.fromURL(json.data, function(array) {
            ds.init(array);
        });
    }
    if (json.stim !== undefined)
        ds.addStim(json.stim, json.delay);
    ds.min = json.min;
    ds.max = json.max;
    ds.cmap = json.cmap;
    ds.rate = json.rate === undefined ? 1 : json.rate;
    return ds;
}
Dataset.maketex = function(array, shape, raw, slice) {
    //Creates paired textures on top of each other
    var tex, data, form;
    var arr = slice === undefined ? array : array.view(slice);
    var size = array.shape[array.shape.length-1];
    var len = shape[0] * shape[1] * (raw ? size : 1);

    data = new array.data.constructor(len*2);
    data.subarray(0, len).set(arr.data);
    if (slice+1 < array.shape[0]) {
        arr = array.view(slice+1);
        data.subarray(len).set(arr.data);
    }

    if (raw) {
        form = size == 4 ? THREE.RGBAFormat : THREE.RGBFormat;
        tex = new THREE.DataTexture(data, shape[0], shape[1]*2, form, THREE.UnsignedByteType);
    } else {
        tex = new THREE.DataTexture(data, shape[0], shape[1]*2, THREE.LuminanceFormat, THREE.FloatType);
    }
    tex.needsUpdate = true;
    tex.flipY = false;
    tex.minFilter = THREE.NearestFilter;
    tex.magFilter = THREE.NearestFilter;
    return tex;
}
Dataset.prototype = {
    init: function(nparray) {
        this.array = nparray;
        this.raw = nparray.data instanceof Uint8Array && nparray.shape.length > 1;
        this.textures = [];

        if ((this.raw && nparray.shape.length > 2) || (!this.raw && nparray.shape.length > 1)) {
            //Movie
            this.datasize = new THREE.Vector2(256, Math.ceil(nparray.shape[1] / 256));
            for (var i = 0; i < nparray.shape[0]; i++) {
                this.textures.push(Dataset.maketex(nparray, [this.datasize.x, this.datasize.y], this.raw, i));
            }
        } else {
            //Single frame
            this.datasize = new THREE.Vector2(256, Math.ceil(nparray.shape[0] / 256));
            this.textures.push(Dataset.maketex(nparray, [this.datasize.x, this.datasize.y], this.raw));
        }
        var minmax = nparray.minmax();
        this.lmin = minmax[0];
        this.lmax = minmax[1];
        if (this.min === undefined)
            this.min = this.lmin;
        if (this.max === undefined)
            this.max = this.lmax;

        if (this._func !== undefined) {
            this._func();
            delete this._func;
        }
    },
    addStim: function(url, delay) {
        this.delay = delay;
        this.stim = document.createElement("video");
        this.stim.id = "stim_movie";
        this.stim.setAttribute("preload", "");
        this.stim.setAttribute("loop", "loop");
        var src = document.createElement("source");
        var ext = url.match(/^(.*)\.(\w{3,4})$/);
        if (ext.length == 3) {
            if (ext[2] == 'ogv') {
                src.setAttribute('type', 'video/ogg; codecs="theora, vorbis"');
            } else if (ext[2] == 'webm') {
                src.setAttribute('type', 'video/webm; codecs="vp8, vorbis"');
            } else if (ext[2] == 'mp4') {
                src.setAttribute('type', 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
            }
        }
        src.setAttribute("src", url);
        this.stim.appendChild(src);

        allStims.push(this.stim);

        this.stim.seekTo = function(time) {
            if (this.seekable.length > 0 &&
                this.seekable.end(0) >= time) {
                this.currentTime = time;
                $("#pluginload").hide()
                if (typeof(this.callback) == "function")
                    this.callback();
            } else {
                this.seekTarget = time;
                $("#pluginload").show()
            }
        }
        $(this.stim).bind("progress", function() {
            if (this.seekTarget != null &&
                this.seekable.length > 0 &&
                this.seekable.end(0) >= this.seekTarget &&
                this.parentNode != null) {
                var func = function() {
                    try {
                        this.currentTime = this.seekTarget;
                        this.seekTarget = null;
                        $("#pluginload").hide()
                        if (typeof(this.callback) == "function")
                            this.callback();
                    } catch (e) {
                        console.log(e);
                        setTimeout(func, 5);
                    }
                }.bind(this);
                func();
            }
        });
        this.stim.seekTo(delay);
    },
    set: function(viewer, dim) {
        if (dim === undefined)
            dim = 0;
        var func = function() {
            viewer._setShader(this.raw, this.datasize);
            if (this.textures.length > 1) {
                viewer.setFrame(0);
                $("#moviecontrols").show();
                $("#bottombar").addClass("bbar_controls");
                $("#movieprogress div").slider("option", {min:0, max:this.textures.length-1});
            } else {
                viewer.shader.uniforms['ds_' + (dim ? 'y':'x')].texture = this.textures[0];
                $("#moviecontrols").hide();
                $("#bottombar").removeClass("bbar_controls");
            }

            if (this.cmap !== undefined) {
                viewer.setColormap(this.cmap);
            }

            $(dim == 0 ? "#vrange" : "#vrange2").slider("option", {min: this.lmin, max:this.lmax});
            viewer.setVminmax(this.min, this.max, dim);

            if (dim > 0)
                return;

            if (this.stim === undefined) {
                viewer.rmPlugin();
            } else {
                for (var i = 0; i < allStims.length; i++)
                    $(allStims[i]).unbind("timeupdate");

                var delay = this.delay;
                viewer.addPlugin(this.stim);
                //this.stim.seekTo(viewer.frame + delay);
                $(this.stim).bind("timeupdate", function() {
                    var now = new Date().getTime() / 1000;
                    var sec = now - viewer._startplay / 1000;
                    console.log("Time diff: "+(this.currentTime - delay - sec));
                    viewer._startplay = (now - this.currentTime + delay)*1000;
                })
            }
        }.bind(this);
        if (this.array !== undefined)
            func();
        else
            this._func = func;
    },
}<|endoftext|>


<commit_before>// Copyright 2017-2022, University of Colorado Boulder

/**
 * Builds standalone JS deliverables (e.g. dot/kite/scenery)
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

// modules
const assert = require( 'assert' );
const fs = require( 'fs' );
const grunt = require( 'grunt' );
const minify = require( './minify' );
const webpackBuild = require( './webpackBuild' );
const _ = require( 'lodash' ); // eslint-disable-line require-statement-match
const getStringMap = require( './getStringMap' );
const ChipperConstants = require( '../common/ChipperConstants' );
const getLocalesFromRepository = require( './getLocalesFromRepository' );
const getPhetLibs = require( './getPhetLibs' );

/**
 * Builds standalone JS deliverables (e.g. dot/kite/scenery)
 * @public
 *
 * @param {string} repo
 * @param {Object} providedOptions - Passed directly to minify()
 * @returns {Promise}
 */
module.exports = async function( repo, providedOptions ) {
  assert( typeof repo === 'string' );
  assert( typeof providedOptions === 'object' );

  const options = _.merge( {
    isDebug: false,

    // {null|string[]} - if provided, exclude these preloads from the built standalone
    omitPreloads: null
  }, providedOptions );

  const packageObject = grunt.file.readJSON( `../${repo}/package.json` );
  assert( packageObject.phet, '`phet` object expected in package.json' );

  const webpackResult = ( await webpackBuild( repo, 'phet' ) );

  const webpackJS = webpackResult.js;

  let includedSources = [
    '../assert/js/assert.js',
    '../tandem/js/PhetioIDUtils.js'
  ];

  // add repo-specific preloads from package.json
  if ( packageObject.phet.preload ) {
    assert( Array.isArray( packageObject.phet.preload ), 'preload should be an array' );
    includedSources = includedSources.concat( packageObject.phet.preload );

    // NOTE: Should find a better way of handling putting these first
    includedSources.forEach( ( source, index ) => {
      if ( source.includes( 'sherpa/lib/lodash-' ) ) {
        includedSources.splice( index, 1 );
        includedSources.unshift( source );
      }
    } );
    includedSources.forEach( ( source, index ) => {
      if ( source.includes( 'sherpa/lib/jquery-' ) ) {
        includedSources.splice( index, 1 );
        includedSources.unshift( source );
      }
    } );
  }
  if ( options.omitPreloads ) {
    includedSources = includedSources.filter( source => !options.omitPreloads.includes( source ) );
  }

  let includedJS = includedSources.map( file => fs.readFileSync( file, 'utf8' ) ).join( '\n' );

  // Checks if lodash exists
  const testLodash = '  if ( !window.hasOwnProperty( \'_\' ) ) {\n' +
                     '    throw new Error( \'Underscore/Lodash not found: _\' );\n' +
                     '  }\n';
  // Checks if jQuery exists
  const testJQuery = '  if ( !window.hasOwnProperty( \'$\' ) ) {\n' +
                     '    throw new Error( \'jQuery not found: $\' );\n' +
                     '  }\n';

  const debugJS = '\nwindow.assertions.enableAssert();\n';
  if ( options.isDebug ) {
    includedJS += debugJS;
  }

  let fullSource = `${includedJS}\n${webpackJS}`;
  if ( packageObject.phet.requiresJQuery ) {
    fullSource = testJQuery + fullSource;
  }
  if ( packageObject.phet.requiresLodash ) {
    fullSource = testLodash + fullSource;
  }

  // include globals assignment
  if ( packageObject.phet.assignGlobals ) {
    let globals = `window.phet=window.phet||{}\n;phet.chipper=phet.chipper||{};\nphet.chipper.packageObject=${JSON.stringify( packageObject )};\n`;
    if ( packageObject.name === 'phet-lib' ) {

      const subRepos = [ 'scenery', 'sun', 'scenery-phet', 'twixt', 'mobius' ];

      const phetLibs = _.uniq( _.flatten( subRepos.map( subRepo => {
        return getPhetLibs( subRepo );
      } ) ).sort() );
      const locales = [
        ChipperConstants.FALLBACK_LOCALE,
        ..._.flatten( subRepos.map( subRepo => getLocalesFromRepository( subRepo ) ) )
      ];
      const { stringMap, stringMetadata } = getStringMap( repo, locales, phetLibs, webpackResult.usedModules );

      globals += `phet.chipper.stringPath = '../';\n`; // eslint-disable-line quotes
      globals += `phet.chipper.locale = 'en';\n`; // eslint-disable-line quotes
      globals += `phet.chipper.loadModules = () => {};\n`; // eslint-disable-line quotes
      globals += `phet.chipper.strings = ${JSON.stringify( stringMap, null, options.isDebug ? 2 : '' )};\n`;
      globals += `phet.chipper.stringMetadata = ${JSON.stringify( stringMetadata, null, options.isDebug ? 2 : '' )};\n`;
    }
    fullSource = `\n${globals}\n${fullSource}`;
  }

  // Wrap with an IIFE
  fullSource = `(function() {\n${fullSource}\n}());`;

  fullSource = minify( fullSource, options );

  return fullSource;
};
<commit_msg>minor doc, https://github.com/phetsims/studio/issues/281<commit_after>// Copyright 2017-2022, University of Colorado Boulder

/**
 * Builds standalone JS deliverables (e.g. dot/kite/scenery)
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

// modules
const assert = require( 'assert' );
const fs = require( 'fs' );
const grunt = require( 'grunt' );
const minify = require( './minify' );
const webpackBuild = require( './webpackBuild' );
const _ = require( 'lodash' ); // eslint-disable-line require-statement-match
const getStringMap = require( './getStringMap' );
const ChipperConstants = require( '../common/ChipperConstants' );
const getLocalesFromRepository = require( './getLocalesFromRepository' );
const getPhetLibs = require( './getPhetLibs' );

/**
 * Builds standalone JS deliverables (e.g. dot/kite/scenery)
 * @public
 *
 * @param {string} repo
 * @param {Object} providedOptions - Passed directly to minify()
 * @returns {Promise<string>}
 */
module.exports = async function( repo, providedOptions ) {
  assert( typeof repo === 'string' );
  assert( typeof providedOptions === 'object' );

  const options = _.merge( {
    isDebug: false,

    // {null|string[]} - if provided, exclude these preloads from the built standalone
    omitPreloads: null
  }, providedOptions );

  const packageObject = grunt.file.readJSON( `../${repo}/package.json` );
  assert( packageObject.phet, '`phet` object expected in package.json' );

  const webpackResult = ( await webpackBuild( repo, 'phet' ) );

  const webpackJS = webpackResult.js;

  let includedSources = [
    '../assert/js/assert.js',
    '../tandem/js/PhetioIDUtils.js'
  ];

  // add repo-specific preloads from package.json
  if ( packageObject.phet.preload ) {
    assert( Array.isArray( packageObject.phet.preload ), 'preload should be an array' );
    includedSources = includedSources.concat( packageObject.phet.preload );

    // NOTE: Should find a better way of handling putting these first
    includedSources.forEach( ( source, index ) => {
      if ( source.includes( 'sherpa/lib/lodash-' ) ) {
        includedSources.splice( index, 1 );
        includedSources.unshift( source );
      }
    } );
    includedSources.forEach( ( source, index ) => {
      if ( source.includes( 'sherpa/lib/jquery-' ) ) {
        includedSources.splice( index, 1 );
        includedSources.unshift( source );
      }
    } );
  }
  if ( options.omitPreloads ) {
    includedSources = includedSources.filter( source => !options.omitPreloads.includes( source ) );
  }

  let includedJS = includedSources.map( file => fs.readFileSync( file, 'utf8' ) ).join( '\n' );

  // Checks if lodash exists
  const testLodash = '  if ( !window.hasOwnProperty( \'_\' ) ) {\n' +
                     '    throw new Error( \'Underscore/Lodash not found: _\' );\n' +
                     '  }\n';
  // Checks if jQuery exists
  const testJQuery = '  if ( !window.hasOwnProperty( \'$\' ) ) {\n' +
                     '    throw new Error( \'jQuery not found: $\' );\n' +
                     '  }\n';

  const debugJS = '\nwindow.assertions.enableAssert();\n';
  if ( options.isDebug ) {
    includedJS += debugJS;
  }

  let fullSource = `${includedJS}\n${webpackJS}`;
  if ( packageObject.phet.requiresJQuery ) {
    fullSource = testJQuery + fullSource;
  }
  if ( packageObject.phet.requiresLodash ) {
    fullSource = testLodash + fullSource;
  }

  // include globals assignment
  if ( packageObject.phet.assignGlobals ) {
    let globals = `window.phet=window.phet||{}\n;phet.chipper=phet.chipper||{};\nphet.chipper.packageObject=${JSON.stringify( packageObject )};\n`;
    if ( packageObject.name === 'phet-lib' ) {

      const subRepos = [ 'scenery', 'sun', 'scenery-phet', 'twixt', 'mobius' ];

      const phetLibs = _.uniq( _.flatten( subRepos.map( subRepo => {
        return getPhetLibs( subRepo );
      } ) ).sort() );
      const locales = [
        ChipperConstants.FALLBACK_LOCALE,
        ..._.flatten( subRepos.map( subRepo => getLocalesFromRepository( subRepo ) ) )
      ];
      const { stringMap, stringMetadata } = getStringMap( repo, locales, phetLibs, webpackResult.usedModules );

      globals += `phet.chipper.stringPath = '../';\n`; // eslint-disable-line quotes
      globals += `phet.chipper.locale = 'en';\n`; // eslint-disable-line quotes
      globals += `phet.chipper.loadModules = () => {};\n`; // eslint-disable-line quotes
      globals += `phet.chipper.strings = ${JSON.stringify( stringMap, null, options.isDebug ? 2 : '' )};\n`;
      globals += `phet.chipper.stringMetadata = ${JSON.stringify( stringMetadata, null, options.isDebug ? 2 : '' )};\n`;
    }
    fullSource = `\n${globals}\n${fullSource}`;
  }

  // Wrap with an IIFE
  fullSource = `(function() {\n${fullSource}\n}());`;

  fullSource = minify( fullSource, options );

  return fullSource;
};
<|endoftext|>