<commit_before>/**
 * @file Postinstall-script for npm-package-manager
 * @copyright 2013 Berne University of Applied Sciences (BUAS) -- {@link http://bfh.ch}
 * @author Pascal Mainini <pascal.mainini@bfh.ch>
 * @version 0.1.1
 *
 * ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING !
 *
 * THIS FILE HAS NO DEFINITIVE LICENSING INFORMATION.
 * LICENSE IS SUBJECT OF CHANGE ANYTIME SOON - DO NOT DISTRIBUTE!
 *
 * ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING !
 *
 * This script is run by npm after the installation. It is responsible for downloading
 * additional dependencies which are not (or not in a form needed) available as npm-packages.
 */

/*jshint node:true, bitwise:true, curly:true, immed:true, indent:2, latedef:true, newcap:true, noarg: true, noempty:true, nonew:true, quotmark:single, undef:true, unused: true, trailing:true, white:false */
/*global EXTERNAL_FILES:true */

/***********************************************************
 * Initialisation
 **********************************************************/

'use strict';

var request = require('request'),
  fs = require('fs');

var EXTERNAL_FILES = [
  ['lib/jquery.js','http://code.jquery.com/jquery-1.9.1.min.js'],
  ['lib/jquery.rest.js','http://raw.github.com/lyconic/jquery.rest/master/jquery.rest.js'],
  ['lib/wmd-editor/Markdown.Editor.js', 'http://raw.github.com/ujifgc/pagedown/master/Markdown.Editor.js'],
  ['lib/wmd-editor/wmd-buttons.png','http://raw.github.com/ujifgc/pagedown/master/wmd-buttons.png']
];

/***********************************************************
 * Function definitions
 **********************************************************/

/**
 * This function gets called when all EXTERNAL_FILES have been fetched.
 * Currently it only informs the user, that the postinstall-script has finished its duty.
 */
var _fetchDone = function _fetchDone () {
  console.log('Done fetching files!');
  console.log('rswiki postinstall script finished!');
};

/**
 * This function asynchronously fetches all the resources given in the EXTERNAL_FILES-array
 */
var _fetchFiles = function _fetchFiles() {
  console.log('Fetching files...');

  var runningRequests = 0;

  EXTERNAL_FILES.forEach(function _element(file) {
    console.log('Retrieving ' + file[1] + '...');

    var readable = request(file[1]);
    runningRequests++;

    readable.on('end', function _end () {
      runningRequests--;
      if (runningRequests === 0) {
        _fetchDone();
      }
    });

    readable.on('error', function _error (err) {
      console.log('Error occured: ' + err);
      runningRequests--;
      if (runningRequests === 0) {
        _fetchDone();
      }
    });

    readable.pipe(fs.createWriteStream(file[0]));
  });
};

/***********************************************************
 * Main application
 **********************************************************/

console.log('rswiki postinstall script running...');

fs.exists('lib/wmd-editor', function _exists (exists) {
  if (!exists) {
    console.log('Creating directory lib/wmd-editor...');
    fs.mkdir('lib/wmd-editor', function _callback (err) {
      if (err) {
        console.log('Error occured: ' + err.constructor.name);
        process.exit(1);
      } else {
        _fetchFiles();
      }
    });
  } else {
    _fetchFiles();
  }
});
<commit_msg>now using the right jquery.rest-plugin...<commit_after>/**
 * @file Postinstall-script for npm-package-manager
 * @copyright 2013 Berne University of Applied Sciences (BUAS) -- {@link http://bfh.ch}
 * @author Pascal Mainini <pascal.mainini@bfh.ch>
 * @version 0.1.1
 *
 * ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING !
 *
 * THIS FILE HAS NO DEFINITIVE LICENSING INFORMATION.
 * LICENSE IS SUBJECT OF CHANGE ANYTIME SOON - DO NOT DISTRIBUTE!
 *
 * ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING !
 *
 * This script is run by npm after the installation. It is responsible for downloading
 * additional dependencies which are not (or not in a form needed) available as npm-packages.
 */

/*jshint node:true, bitwise:true, curly:true, immed:true, indent:2, latedef:true, newcap:true, noarg: true, noempty:true, nonew:true, quotmark:single, undef:true, unused: true, trailing:true, white:false */
/*global EXTERNAL_FILES:true */

/***********************************************************
 * Initialisation
 **********************************************************/

'use strict';

var request = require('request'),
  fs = require('fs');

var EXTERNAL_FILES = [
  ['lib/jquery.js','http://code.jquery.com/jquery-1.9.1.min.js'],
  ['lib/jquery.rest.js','http://raw.github.com/jpillora/jquery.rest/gh-pages/dist/jquery.rest.min.js'],
  ['lib/wmd-editor/Markdown.Editor.js', 'http://raw.github.com/ujifgc/pagedown/master/Markdown.Editor.js'],
  ['lib/wmd-editor/wmd-buttons.png','http://raw.github.com/ujifgc/pagedown/master/wmd-buttons.png']
];

/***********************************************************
 * Function definitions
 **********************************************************/

/**
 * This function gets called when all EXTERNAL_FILES have been fetched.
 * Currently it only informs the user, that the postinstall-script has finished its duty.
 */
var _fetchDone = function _fetchDone () {
  console.log('Done fetching files!');
  console.log('rswiki postinstall script finished!');
};

/**
 * This function asynchronously fetches all the resources given in the EXTERNAL_FILES-array
 */
var _fetchFiles = function _fetchFiles() {
  console.log('Fetching files...');

  var runningRequests = 0;

  EXTERNAL_FILES.forEach(function _element(file) {
    console.log('Retrieving ' + file[1] + '...');

    var readable = request(file[1]);
    runningRequests++;

    readable.on('end', function _end () {
      runningRequests--;
      if (runningRequests === 0) {
        _fetchDone();
      }
    });

    readable.on('error', function _error (err) {
      console.log('Error occured: ' + err);
      runningRequests--;
      if (runningRequests === 0) {
        _fetchDone();
      }
    });

    readable.pipe(fs.createWriteStream(file[0]));
  });
};

/***********************************************************
 * Main application
 **********************************************************/

console.log('rswiki postinstall script running...');

fs.exists('lib/wmd-editor', function _exists (exists) {
  if (!exists) {
    console.log('Creating directory lib/wmd-editor...');
    fs.mkdir('lib/wmd-editor', function _callback (err) {
      if (err) {
        console.log('Error occured: ' + err.constructor.name);
        process.exit(1);
      } else {
        _fetchFiles();
      }
    });
  } else {
    _fetchFiles();
  }
});
<|endoftext|>


<commit_before>const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const webpack = require('webpack');

const distFolder = 'dist';

module.exports = {
    entry: {
        "weave-app": './src/index.tsx',
        /*vendor: [
            "c3",
            "clipboard",
            "codemirror",
            "d3",
            "filesaver.js",
            "fixed-data-table",
            "jquery",
            "lodash",
            "jszip",
            "openlayers",
            "pixi.js",
            "proj4",
            "rc-slider",
            "react",
            "react-addons-update",
            "react-codemirror",
            "react-color",
            "react-dom",
            "react-dropzone",
            "react-notification-system",
            "react-sparklines",
            "immediate",
            "moment",
        ],*/
    },
    plugins: [
        new CleanWebpackPlugin([distFolder]),
        new HtmlWebpackPlugin({
            template: './resources/index.ejs',
        }),
        new HtmlWebpackPlugin({
            filename: 'weave.html',
            template: './resources/weave.ejs',
        }),
        new webpack.optimize.CommonsChunkPlugin({
            children: true,
            async: true,
            minChunks: 3,
        }),
        new CopyWebpackPlugin([
                {flatten: false, context: 'resources/', from: 'css/', to: path.resolve(__dirname, distFolder, 'css')},
                {flatten: true, context: '../WeaveTSJS/css/', from: 'weave-ui.css', to: path.resolve(__dirname, distFolder, 'css/weave-ui.css')},
                {flatten: true, context: 'resources/', from: 'img/*.*', to: path.resolve(__dirname, distFolder, 'img')},
                {flatten: true, context: 'resources/', from: 'css/fonts/*.ttf', to: path.resolve(__dirname, distFolder, 'fonts')},
                {flatten: true, context: 'node_modules/openlayers/css/', from: 'ol.css', to: path.resolve(__dirname, distFolder, 'css')},
                {flatten: true, context: 'node_modules/font-awesome/css/', from: 'font-awesome.css', to: path.resolve(__dirname, distFolder, 'css')},
                {flatten: true, context: 'node_modules/font-awesome/fonts/', from: '*', to: path.resolve(__dirname, distFolder, 'fonts')},
                {context: 'resources/semantic/', from: 'semantic.min.js', to: path.resolve(__dirname, distFolder)},
                {context: 'resources/semantic/', from: 'semantic.min.css', to: path.resolve(__dirname, distFolder, 'css')},
                {context: 'resources/semantic/themes/', from: '*', to: path.resolve(__dirname, distFolder, 'css/themes')},
                {flatten: true, context: '../weave_sessions/', from: "*.weave", to: path.resolve(__dirname, distFolder)},
                {flatten: true, context: 'resources/', from: 'ProjDatabase.zip', to: path.resolve(__dirname, distFolder, 'ProjDatabase.zip')}
        ]),
        new ProgressBarPlugin({ clear: false }),
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            "window.jQuery": "jquery"
        }),
        new webpack.ProvidePlugin({
            React: "React", react: "React", "window.react": "React", "window.React": "React"
        }),
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, distFolder),
    },
    module: {
        rules: [{
            test: /\.tsx?$/,
            use: [
                'babel-loader',
                'ts-loader',
            ],
            exclude: /node_modules/
        },
        {
            test: /\.css$/,
            use: [
                'style-loader',
                'css-loader',
            ],
        },
        {
            test: /\.(png|svg|jpg|gif)$/,
            use: [
                'file-loader',
            ],
        },
        {
            test: /\.(woff|woff2|eot|ttf|otf)$/,
            use: [
                'file-loader',
            ],
        },
        {
            test: /\.(csv|tsv)$/,
            use: [
                'csv-loader',
            ],
        },
        {
            test: /\.xml$/,
            use: [
                'xml-loader',
            ]
        },
        {
            test: /\.json$/,
            use: [
                'json-loader',
            ],
        },
    ]},
    resolve: {
        extensions: [ ".tsx", ".ts", ".js" ],
        alias: {
            weaveapp: path.resolve(__dirname, 'src/weaveapp/'),
        }
    },
    node: {
        fs: 'empty',
    },
};<commit_msg>Remove unnecessary configuration<commit_after>const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const webpack = require('webpack');

const distFolder = 'dist';

module.exports = {
    entry: {
        "weave-app": './src/index.tsx',
    },
    plugins: [
        new CleanWebpackPlugin([distFolder]),
        new HtmlWebpackPlugin({
            template: './resources/index.ejs',
        }),
        new HtmlWebpackPlugin({
            filename: 'weave.html',
            template: './resources/weave.ejs',
        }),
        new webpack.optimize.CommonsChunkPlugin({
            children: true,
            async: true,
            minChunks: 3,
        }),
        new CopyWebpackPlugin([
                {flatten: false, context: 'resources/', from: 'css/', to: path.resolve(__dirname, distFolder, 'css')},
                {flatten: true, context: '../WeaveTSJS/css/', from: 'weave-ui.css', to: path.resolve(__dirname, distFolder, 'css/weave-ui.css')},
                {flatten: true, context: 'resources/', from: 'img/*.*', to: path.resolve(__dirname, distFolder, 'img')},
                {flatten: true, context: 'resources/', from: 'css/fonts/*.ttf', to: path.resolve(__dirname, distFolder, 'fonts')},
                {flatten: true, context: 'node_modules/openlayers/css/', from: 'ol.css', to: path.resolve(__dirname, distFolder, 'css')},
                {flatten: true, context: 'node_modules/font-awesome/css/', from: 'font-awesome.css', to: path.resolve(__dirname, distFolder, 'css')},
                {flatten: true, context: 'node_modules/font-awesome/fonts/', from: '*', to: path.resolve(__dirname, distFolder, 'fonts')},
                {context: 'resources/semantic/', from: 'semantic.min.js', to: path.resolve(__dirname, distFolder)},
                {context: 'resources/semantic/', from: 'semantic.min.css', to: path.resolve(__dirname, distFolder, 'css')},
                {context: 'resources/semantic/themes/', from: '*', to: path.resolve(__dirname, distFolder, 'css/themes')},
                {flatten: true, context: '../weave_sessions/', from: "*.weave", to: path.resolve(__dirname, distFolder)},
                {flatten: true, context: 'resources/', from: 'ProjDatabase.zip', to: path.resolve(__dirname, distFolder, 'ProjDatabase.zip')}
        ]),
        new ProgressBarPlugin({ clear: false }),
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            "window.jQuery": "jquery"
        }),
        new webpack.ProvidePlugin({
            React: "React", react: "React", "window.react": "React", "window.React": "React"
        }),
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, distFolder),
    },
    module: {
        rules: [{
            test: /\.tsx?$/,
            use: [
                'babel-loader',
                'ts-loader',
            ],
            exclude: /node_modules/
        },
        {
            test: /\.css$/,
            use: [
                'style-loader',
                'css-loader',
            ],
        },
        {
            test: /\.(png|svg|jpg|gif)$/,
            use: [
                'file-loader',
            ],
        },
        {
            test: /\.(woff|woff2|eot|ttf|otf)$/,
            use: [
                'file-loader',
            ],
        },
        {
            test: /\.(csv|tsv)$/,
            use: [
                'csv-loader',
            ],
        },
        {
            test: /\.xml$/,
            use: [
                'xml-loader',
            ]
        },
        {
            test: /\.json$/,
            use: [
                'json-loader',
            ],
        },
    ]},
    resolve: {
        extensions: [ ".tsx", ".ts", ".js" ],
        alias: {
            weaveapp: path.resolve(__dirname, 'src/weaveapp/'),
        }
    },
    node: {
        fs: 'empty',
    },
};<|endoftext|>


<commit_before>
/*
  Event bindings and DOM Manipulation.
*/

(function(){

    //Set the default starting folder for browse boxes
    var projectFolder = $("#projectFolder").val();
    $("#projectIconBrowse").attr("nwworkingdir", projectFolder);
    $("#inputFolderBrowse").attr("nwworkingdir", projectFolder);
    $("#outputFolderBrowse").attr("nwworkingdir", projectFolder);

    $("#projectIconHover").click( function () { $("#projectIconBrowse" ).click(); });
    $("#inputFolderIcon" ).click( function () { $("#inputFolderBrowse" ).click(); });
    $("#outputFolderIcon").click( function () { $("#outputFolderBrowse").click(); });

    $("#projectIconBrowse").change(function () {
        var newImg = $("#projectIconBrowse").val();
        $("#projectIcon").attr('src', newImg);
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].projectIcon = newImg;
                scout.helpers.saveSettings();
            }
        }
    });
    $("#inputFolderBrowse").change(function () {
        var newDir = $("#inputFolderBrowse").val();
        newDir = newDir.split('\\').join('\/');
        $("#inputFolder").val(newDir);
        forbidSameFolder();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].inputFolder = newDir;
                scout.helpers.saveSettings();
            }
        }
    });
    $("#outputFolderBrowse").change(function () {
        var newDir = $("#outputFolderBrowse").val();
        newDir = newDir.split('\\').join('\/');
        $("#outputFolder").val(newDir);
        forbidSameFolder();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].outputFolder = newDir;
                scout.helpers.saveSettings();
            }
        }
    });
    $("#outputStyle").change(function () {
        var id = $("#projectID").val();
        var outputStyle = $("#outputStyle").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (id == scout.projects[i].projectID) {
                scout.projects[i].outputStyle = outputStyle;
            }
        }
    });
    $("#inputFolder").on('blur', function () {
        var newDir = $("#inputFolder").val();
        newDir = newDir.split('\\').join('\/');
        forbidSameFolder();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].inputFolder = newDir;
                scout.helpers.saveSettings();
            }
        }
    });
    $("#outputFolder").on('blur', function () {
        var newDir = $("#outputFolder").val();
        newDir = newDir.split('\\').join('\/');
        forbidSameFolder();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].outputFolder = newDir;
                scout.helpers.saveSettings();
            }
        }
    });

    //Clicking the "Status of all Projects" sidebar buttons
    $("#viewStatus").click(function (evt) {
        evt.preventDefault();
        $("#project-settings").addClass('hide');
        $("#printConsoleTitle").removeClass('hide');
        $("#sidebar .active").removeClass('active');
        $("#printConsole .alert, #printConsole .panel").removeClass('hide');
    });

    $('.navbar a[href="#viewStatus"]').click( function() {
        $("#viewStatus").click();
    });

    function forbidSameFolder () {
        var inputDir = $("#inputFolder").val();
        var outputDir = $("#outputFolder").val();
        var id = $("#projectID").val();

        //Update projects object
        for (var i = 0; i < scout.projects.length; i++) {
            if (id == scout.projects[i].projectID) {
                scout.projects[i].inputFolder = inputDir;
                scout.projects[i].outputFolder = outputDir;
            }
        }

        //Check validity of input and output
        if ( inputDir === "" || outputDir === "" ) {
            $("#outputWarning").addClass("hide");
            lockSubmit(id);
        } else if ( (inputDir === outputDir) || (outputDir.startsWith(inputDir + '/')) ) {
            $("#outputWarning").removeClass('hide');
            lockSubmit(id);
        } else {
            $("#outputWarning").addClass("hide");
            unlockSubmit(id);
        }
    }

    $("#inputFolder, #outputFolder").keyup(forbidSameFolder).mouseup(forbidSameFolder).change(forbidSameFolder);

    function lockSubmit (id) {
        id = id || $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (id == scout.projects[i].projectID) {
                scout.projects[i].indicator = "gray-play";
                scout.helpers.updateSidebar();
                scout.helpers.saveSettings();
                $("#sidebar .active").removeClass("active");
                $("#sidebar ." + id).addClass("active");
                return;
            }
        }
    }

    function unlockSubmit (id) {
        id = id || $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            var project  = scout.projects[i];
            var inputDir = project.inputFolder;
            var outputDir = project.outputFolder;
            if (
                (inputDir === "") ||
                (outputDir === "") ||
                (inputDir === outputDir) ||
                (outputDir.startsWith(inputDir + '/')) ||
                (outputDir.startsWith(inputDir + '\\'))
            ) {
                project.indicator = "gray-play";
                scout.helpers.stopWatching( project.projectID );
            } else if (project.indicator == "stop") {
                project.indicator = "stop";
            } else {
                project.indicator = "play";
            }
        }
        scout.helpers.updateSidebar();
        $("#sidebar .active").removeClass("active");
        if (id) {
            $("#sidebar ." + id).addClass("active");
        }
    }

    $("#environment input").change( function (evt) {
        ugui.helpers.buildUGUIArgObject();
        var manuallyUpdateOutputStyle = false;
        if (ugui.args.development.htmlticked) {
            $($("#outputStyle option")[3]).hide();
            $($("#outputStyle option")[4]).hide();

            var isLabelSelected = $($("#outputStyle option")[0]).prop("selected");
            var isNestedSelected = $($("#outputStyle option")[1]).prop("selected");
            //If the first or second items in the dropdown are picked, that's cool, set everything else to the 3rd option
            if (isLabelSelected == false && isNestedSelected == false) {
                //Select "Expanded"
                $($("#outputStyle option")[2]).prop("selected", true);
                manuallyUpdateOutputStyle = true;
            }
        } else {
            $($("#outputStyle option")[3]).show();
            $($("#outputStyle option")[4]).show();
        }

        var environment = $(evt.currentTarget).val();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (id === scout.projects[i].projectID) {
                scout.projects[i].environment = environment;
                if (manuallyUpdateOutputStyle) {
                    scout.projects[i].outputStyle = $("#outputStyle").val();
                }
            }
        }

        scout.helpers.saveSettings();
    });

    /**
     * DELETING A PROJECT
     */
    //Remove modal, enable scrollbar
    function removeModal () {
        $(".modal").slideUp("slow", function() {
            $("body").removeClass('no-overflow');
            //If the navigation is expanded, then close it after exiting the modal
            if ( !$(".navbar-toggle").hasClass("collapsed") ) {
                $(".navbar-toggle").trigger("click");
            }
        });
    }
    //Click "Delete Project"
    $("#delete-project").click(function (evt) {
        evt.preventDefault();
        var projectName = $("#projectName").text();
        $(".project-name").text(projectName);
        $("#confirm-delete").removeClass('gray');
        $("#delete-modal").fadeIn("slow");

        //Remove page scrollbar when modal displays
        $("body").addClass("no-overflow");
    });
    //Confirm delete in the modal
    $("#confirm-delete").click(function (evt) {
        evt.preventDefault();

        if (!$("#confirm-delete").hasClass('gray')) {
            $("#confirm-delete").addClass('gray');

            var id = $("#projectID").val();

            //Remove project from the object
            scout.helpers.removeProject(id);
            //remove all related alerts/messages from the DOM
            $("#printConsole ." + id + " .glyphicon-remove").click();

            //Wipe out UI
            scout.helpers.resetProjectUI();
            $("#printConsole .alert, #printConsole .panel").addClass('hide');
            removeModal();

            if (scout.projects.length > 0) {
                $($("#projects-list > div")[0]).click();
            }
        }

    });
    //When clicking on background, cancel button, or X, remove modal
    $(".modal, #cancel-delete, .modal .glyphicon-remove").click( removeModal );
    //Allow you to click in the modal without triggering the `removeModal` function called when you click its parent element
    $(".modal .modal-content").click( function( evt ) {
        evt.stopPropagation();
    });

    //On page load have this run once
    unlockSubmit();

    scout.helpers.unlockSubmit = unlockSubmit;

    /**
     * OSX Keybindings.
     * On Windows and Ubuntu Scout-App inherits the OS's global clipboard shortcuts.
     * OSX needs you to spoon feed it how to copy and paste.
     */
    function osxKeyBindings() {
        //Keyboard shortcuts
        document.onkeydown = function(pressed) {
            //Check CMD+V and CMD+v keys and paste
            if (
                pressed.metaKey && pressed.keyCode === 86 ||
                pressed.metaKey && pressed.keyCode === 118 ) {
                    pressed.preventDefault();
                    document.execCommand("paste");
                    return false;
            //Check CMD+C and CMD+c keys and copy
            } else if (
                pressed.metaKey && pressed.keyCode === 67 ||
                pressed.metaKey && pressed.keyCode === 99 ) {
                    pressed.preventDefault();
                    document.execCommand("copy");
                    return false;
            //Check CMD+X  and CMD+x and cut
            } else if (
                pressed.metaKey && pressed.keyCode === 88 ||
                pressed.metaKey && pressed.keyCode === 120 ) {
                    pressed.preventDefault();
                    document.execCommand("cut");
                    return false;
            }
        };
    }

    //run once on page load
    if (process.platform == "darwin") {
        osxKeyBindings();
    }

})();
<commit_msg>OS X Key shortcuts close and dev tools<commit_after>
/*
  Event bindings and DOM Manipulation.
*/

(function(){

    //Set the default starting folder for browse boxes
    var projectFolder = $("#projectFolder").val();
    $("#projectIconBrowse").attr("nwworkingdir", projectFolder);
    $("#inputFolderBrowse").attr("nwworkingdir", projectFolder);
    $("#outputFolderBrowse").attr("nwworkingdir", projectFolder);

    $("#projectIconHover").click( function () { $("#projectIconBrowse" ).click(); });
    $("#inputFolderIcon" ).click( function () { $("#inputFolderBrowse" ).click(); });
    $("#outputFolderIcon").click( function () { $("#outputFolderBrowse").click(); });

    $("#projectIconBrowse").change(function () {
        var newImg = $("#projectIconBrowse").val();
        $("#projectIcon").attr('src', newImg);
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].projectIcon = newImg;
                scout.helpers.saveSettings();
            }
        }
    });
    $("#inputFolderBrowse").change(function () {
        var newDir = $("#inputFolderBrowse").val();
        newDir = newDir.split('\\').join('\/');
        $("#inputFolder").val(newDir);
        forbidSameFolder();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].inputFolder = newDir;
                scout.helpers.saveSettings();
            }
        }
    });
    $("#outputFolderBrowse").change(function () {
        var newDir = $("#outputFolderBrowse").val();
        newDir = newDir.split('\\').join('\/');
        $("#outputFolder").val(newDir);
        forbidSameFolder();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].outputFolder = newDir;
                scout.helpers.saveSettings();
            }
        }
    });
    $("#outputStyle").change(function () {
        var id = $("#projectID").val();
        var outputStyle = $("#outputStyle").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (id == scout.projects[i].projectID) {
                scout.projects[i].outputStyle = outputStyle;
            }
        }
    });
    $("#inputFolder").on('blur', function () {
        var newDir = $("#inputFolder").val();
        newDir = newDir.split('\\').join('\/');
        forbidSameFolder();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].inputFolder = newDir;
                scout.helpers.saveSettings();
            }
        }
    });
    $("#outputFolder").on('blur', function () {
        var newDir = $("#outputFolder").val();
        newDir = newDir.split('\\').join('\/');
        forbidSameFolder();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (scout.projects[i].projectID == id) {
                scout.projects[i].outputFolder = newDir;
                scout.helpers.saveSettings();
            }
        }
    });

    //Clicking the "Status of all Projects" sidebar buttons
    $("#viewStatus").click(function (evt) {
        evt.preventDefault();
        $("#project-settings").addClass('hide');
        $("#printConsoleTitle").removeClass('hide');
        $("#sidebar .active").removeClass('active');
        $("#printConsole .alert, #printConsole .panel").removeClass('hide');
    });

    $('.navbar a[href="#viewStatus"]').click( function() {
        $("#viewStatus").click();
    });

    function forbidSameFolder () {
        var inputDir = $("#inputFolder").val();
        var outputDir = $("#outputFolder").val();
        var id = $("#projectID").val();

        //Update projects object
        for (var i = 0; i < scout.projects.length; i++) {
            if (id == scout.projects[i].projectID) {
                scout.projects[i].inputFolder = inputDir;
                scout.projects[i].outputFolder = outputDir;
            }
        }

        //Check validity of input and output
        if ( inputDir === "" || outputDir === "" ) {
            $("#outputWarning").addClass("hide");
            lockSubmit(id);
        } else if ( (inputDir === outputDir) || (outputDir.startsWith(inputDir + '/')) ) {
            $("#outputWarning").removeClass('hide');
            lockSubmit(id);
        } else {
            $("#outputWarning").addClass("hide");
            unlockSubmit(id);
        }
    }

    $("#inputFolder, #outputFolder").keyup(forbidSameFolder).mouseup(forbidSameFolder).change(forbidSameFolder);

    function lockSubmit (id) {
        id = id || $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (id == scout.projects[i].projectID) {
                scout.projects[i].indicator = "gray-play";
                scout.helpers.updateSidebar();
                scout.helpers.saveSettings();
                $("#sidebar .active").removeClass("active");
                $("#sidebar ." + id).addClass("active");
                return;
            }
        }
    }

    function unlockSubmit (id) {
        id = id || $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            var project  = scout.projects[i];
            var inputDir = project.inputFolder;
            var outputDir = project.outputFolder;
            if (
                (inputDir === "") ||
                (outputDir === "") ||
                (inputDir === outputDir) ||
                (outputDir.startsWith(inputDir + '/')) ||
                (outputDir.startsWith(inputDir + '\\'))
            ) {
                project.indicator = "gray-play";
                scout.helpers.stopWatching( project.projectID );
            } else if (project.indicator == "stop") {
                project.indicator = "stop";
            } else {
                project.indicator = "play";
            }
        }
        scout.helpers.updateSidebar();
        $("#sidebar .active").removeClass("active");
        if (id) {
            $("#sidebar ." + id).addClass("active");
        }
    }

    $("#environment input").change( function (evt) {
        ugui.helpers.buildUGUIArgObject();
        var manuallyUpdateOutputStyle = false;
        if (ugui.args.development.htmlticked) {
            $($("#outputStyle option")[3]).hide();
            $($("#outputStyle option")[4]).hide();

            var isLabelSelected = $($("#outputStyle option")[0]).prop("selected");
            var isNestedSelected = $($("#outputStyle option")[1]).prop("selected");
            //If the first or second items in the dropdown are picked, that's cool, set everything else to the 3rd option
            if (isLabelSelected == false && isNestedSelected == false) {
                //Select "Expanded"
                $($("#outputStyle option")[2]).prop("selected", true);
                manuallyUpdateOutputStyle = true;
            }
        } else {
            $($("#outputStyle option")[3]).show();
            $($("#outputStyle option")[4]).show();
        }

        var environment = $(evt.currentTarget).val();
        var id = $("#projectID").val();
        for (var i = 0; i < scout.projects.length; i++) {
            if (id === scout.projects[i].projectID) {
                scout.projects[i].environment = environment;
                if (manuallyUpdateOutputStyle) {
                    scout.projects[i].outputStyle = $("#outputStyle").val();
                }
            }
        }

        scout.helpers.saveSettings();
    });

    /**
     * DELETING A PROJECT
     */
    //Remove modal, enable scrollbar
    function removeModal () {
        $(".modal").slideUp("slow", function() {
            $("body").removeClass('no-overflow');
            //If the navigation is expanded, then close it after exiting the modal
            if ( !$(".navbar-toggle").hasClass("collapsed") ) {
                $(".navbar-toggle").trigger("click");
            }
        });
    }
    //Click "Delete Project"
    $("#delete-project").click(function (evt) {
        evt.preventDefault();
        var projectName = $("#projectName").text();
        $(".project-name").text(projectName);
        $("#confirm-delete").removeClass('gray');
        $("#delete-modal").fadeIn("slow");

        //Remove page scrollbar when modal displays
        $("body").addClass("no-overflow");
    });
    //Confirm delete in the modal
    $("#confirm-delete").click(function (evt) {
        evt.preventDefault();

        if (!$("#confirm-delete").hasClass('gray')) {
            $("#confirm-delete").addClass('gray');

            var id = $("#projectID").val();

            //Remove project from the object
            scout.helpers.removeProject(id);
            //remove all related alerts/messages from the DOM
            $("#printConsole ." + id + " .glyphicon-remove").click();

            //Wipe out UI
            scout.helpers.resetProjectUI();
            $("#printConsole .alert, #printConsole .panel").addClass('hide');
            removeModal();

            if (scout.projects.length > 0) {
                $($("#projects-list > div")[0]).click();
            }
        }

    });
    //When clicking on background, cancel button, or X, remove modal
    $(".modal, #cancel-delete, .modal .glyphicon-remove").click( removeModal );
    //Allow you to click in the modal without triggering the `removeModal` function called when you click its parent element
    $(".modal .modal-content").click( function( evt ) {
        evt.stopPropagation();
    });

    //On page load have this run once
    unlockSubmit();

    scout.helpers.unlockSubmit = unlockSubmit;

    /**
     * OSX Keybindings.
     * On Windows and Ubuntu Scout-App inherits the OS's global clipboard shortcuts.
     * OSX needs you to spoon feed it how to copy and paste.
     */
    function osxKeyBindings () {
        var win = require('nw.gui').Window.get();
        //Keyboard shortcuts
        document.onkeydown = function(pressed) {
            //Check CMD+V and CMD+v keys and paste
            if (
                pressed.metaKey && pressed.keyCode === 86 ||
                pressed.metaKey && pressed.keyCode === 118 ) {
                    pressed.preventDefault();
                    document.execCommand("paste");
                    return false;
            //Check CMD+C and CMD+c keys and copy
            } else if (
                pressed.metaKey && pressed.keyCode === 67 ||
                pressed.metaKey && pressed.keyCode === 99 ) {
                    pressed.preventDefault();
                    document.execCommand("copy");
                    return false;
            //Check CMD+X and CMD+x and cut
            } else if (
                pressed.metaKey && pressed.keyCode === 88 ||
                pressed.metaKey && pressed.keyCode === 120 ) {
                    pressed.preventDefault();
                    document.execCommand("cut");
                    return false;
            //Check CMD+Shift+I and open dev tools
            } else if (
                pressed.metaKey && pressed.shiftKey && pressed.keyCode === 73 ||
                pressed.metaKey && pressed.shiftKey && pressed.keyCode === 105) {
                    win.showDevTools();
                    return false;
            //Check CMD+Q and CMD+q and close the app
            } else if (
                pressed.metaKey && pressed.keyCode === 81||
                pressed.metaKey && pressed.keyCode === 113) {
                    win.on('close', function() {
                        this.hide();
                        this.close(true);
                    });
                    win.close();
                    return false;
            }
        };
    }

    //run once on page load
    if (process.platform == "darwin") {
        osxKeyBindings();
    }

})();
<|endoftext|>


<commit_before>$(function() {

	var SM = new SpriteManager();

	$('#game').hide();

	preloadImages(sprites);

	var zIndex = 1;

	$.each(sprites, function (k, sprite_data) {
		sprite_data.zIndex = zIndex++;
		SM.addSprite((new Sprite(sprite_data)).init($('#game')));
	});

	$('#game').on('click dblclick', function(event) {
		var x = event.pageX - $(this).position().left,
			y = event.pageY - $(this).position().top;

		// honor game field bounds
		x = Math.max(64, x);
		y = Math.max(64, y);
		x = Math.min($(this).width()-64, x);
		y = Math.min($(this).height()-64, y);

		$('.sprite').trigger('move', {
			x : x,
			y : y,
			speed: event.type === 'dblclick' ? 1.6 : 1
		});

	});

	SM.updateSprites();

	$('#game')
		.show()
		.on('resize', function() {
			$(this).find('.sprite').each(function() {
				var x, y;

				if (($(this).position().top + $(this).height()) > $(window).innerHeight()) {
					y = $(window).innerHeight() - ($(this).height() / 2);
				}

				if (($(this).position().left + $(this).width()) > $(window).innerWidth()) {
					x = $(window).innerWidth() - ($(this).width() / 2);
				}

				$(this).trigger('move', {x: x, y: y, force: true});
			});
		});

});
<commit_msg>do not hide and show game frame<commit_after>$(function() {

	var SM = new SpriteManager();

	preloadImages(sprites);

	var zIndex = 1;

	$.each(sprites, function (k, sprite_data) {
		sprite_data.zIndex = zIndex++;
		SM.addSprite((new Sprite(sprite_data)).init($('#game')));
	});

	$('#game').on('click dblclick', function(event) {
		var x = event.pageX - $(this).position().left,
			y = event.pageY - $(this).position().top;

		// honor game field bounds
		x = Math.max(64, x);
		y = Math.max(64, y);
		x = Math.min($(this).width()-64, x);
		y = Math.min($(this).height()-64, y);

		$('.sprite').trigger('move', {
			x : x,
			y : y,
			speed: event.type === 'dblclick' ? 1.6 : 1
		});

	});

	SM.updateSprites();

	$('#game')
		.on('resize', function() {
			$(this).find('.sprite').each(function() {
				var x, y;

				if (($(this).position().top + $(this).height()) > $(window).innerHeight()) {
					y = $(window).innerHeight() - ($(this).height() / 2);
				}

				if (($(this).position().left + $(this).width()) > $(window).innerWidth()) {
					x = $(window).innerWidth() - ($(this).width() / 2);
				}

				$(this).trigger('move', {x: x, y: y, force: true});
			});
		});

});
<|endoftext|>


<commit_before>// An environment!
function makeEnv( keys, values, outer ){
  var env = {
    "values": makeHash(keys, values),
    "outer":  outer
  };
  return(env);
}

// Convenience function for above
function makeHash(keys, values){
  var hash = {};
  for (var i in keys) {
    hash[keys[i]] = values[i];
  }
  return hash;
}

function findEnv( env, key ){
  if( env.values.hasOwnProperty( key ) ){
    return env;
  }

  if( env.outer ){
    return findEnv( env.outer, key );
  }
}

function defInEnv( env, key, value ){
  return (env.values[key] = value);
}

// This function differs from the above
// in that it climbs to the environment
// where the key was originally defined
// to mutate it in place.
function setInEnv( env, key, value ){
  return (findEnv(env, key).values[key] = value);
}

function getFromEnv( env, key ){
  return (findEnv(env, key).values[key]);
}

function values( obj ){
  return Object.keys(obj).map(function(x){ return obj[x] });
}

function arrayp( a ){
  return ( a instanceof Array );
}

function functionp( a ){
  return ( a instanceof Function );
}

function hashp( a ){
  return ( a instanceof Object && !( arrayp(a) ) && !( functionp(a) ));
}

function numberp( a) {
  return (typeof a == "number");
}

function stringp( a) {
  return (typeof a == "string");
}

function brid(x, env){
  if( typeof x == "string" ){ // variable reference
    return getFromEnv(env, x);
  } else if( hashp(x) ){
    // unlike Clojure, our keys cannot be arbitrary objects
    // so let's not evaluate keys as expressions
    return makeHash(Object.keys(x), values(x).map(function(v){ return brid(v, env) }));
  } else if( !arrayp(x) ){ // constant literal
    return x;
  } else if(x.length == 0) {
    return [];
  } else if(x[0] == 'quote'){
    return x[1];
  } else if(x[0] == 'if'){
    var test   = x[1];
    var conseq = x[2];
    var alt    = x[3];
    var branch;
    if( brid(test, env) )
      { branch = conseq }
      else { branch = alt };
    return ( brid( branch, env ));
  } else if(x[0] == 'set!'){
    var v   = x[1];
    var exp = x[2];
    return (setInEnv(env, v, brid(exp, env)));
  } else if(x[0] == 'define'){
    var v   = x[1];
    var exp = x[2];
    return (defInEnv(env, v, brid(exp, env)));
  } else if(x[0] == 'lambda'){
    var vars = x[1];
    var exp  = x[2];
    // is it cheating to use the closure from here?
    var r = function(){ return brid( exp, makeEnv(vars, arguments, env) ) };
    return r;
  } else if(x[0] == 'begin'){
    var args = x.slice(1);
    var r;
    for(var i in args){
      r = brid(args[i], env)
    }
    return r;
  } else if(x[0] == 'eval'){
    var arg = x[1];
    var r = brid( brid(arg, env), env );
    return r;
  } else { // something user defined
    var exps = x.map(function(exp){ return brid(exp, env)});
    var proc = exps.shift();
    return proc.apply(proc, exps);
  }
}

// Grrr, JavaScript
function argsToArray(args){
  var r = [];
  for( var i in args ){
    r.push(args[i]);
  }
  return(r);
}

function plus(){
  return argsToArray(arguments).reduce(function(a,b){return a+b}, 0);
}

function minus(){
  if (arguments.length == 1){
    return -arguments[0];
  } else if (arguments.length > 1){
    return argsToArray(arguments).slice(1).reduce(function(a,b){return a-b}, arguments[0]);
  } else {
    throw "wrong number of arguments to -";
  }
}

function write(s){
  var output = document.getElementById('output');
  output.value += s;
  output.scrollTop = output.scrollHeight;
}

function writeln(s){
  write(s + "\n");
}

function get(hash, key){
  if( hash instanceof Object ){
    if( hash.hasOwnProperty( key ) ){
      return hash[key];
    }
  }
}

function copyHash( hash ){
  var keys = Object.keys(hash);
  var r = {};
  for( var i in keys ){
    var key = keys[i];
    if( hash.hasOwnProperty( key ) ){
      r[key] = hash[key];
    }
  }
  return r;
}

function assoc(hash, key, value){
  var r = copyHash(hash);
  r[key] = value;
  return r;
}

function eqp(a, b){
  return a === b;
}

function equalp(a, b){
  if(typeof(a) != typeof(b)){
    return false;
  }

  if( arrayp(a) ){
    return arrayp(b) && arrayEquals(a,b);
  }

  if( hashp(a) ){
    return hashp(b) && hashEquals(a,b);
  }
  return a == b;
}

function arrayEquals(a, b){
  if( a.length != b.length ){
    return false;
  }
  for( var i in a ){
    if(a[i] != b[i]){
      return false;
    }
  }
  return true;
}

function hashEquals(a, b){
  return arrayEquals(Object.keys(a), Object.keys(b)) && arrayEquals(values(a), values(b))
}

function gt(){
  var greatest = (-Infinity);
  for( var i in arguments ){
    if( arguments[i] <= greatest ){
      return false;
    }
    greatest = arguments[i];
  }
  return true;
}

function gte(){
  var greatest = (-Infinity);
  for( var i in arguments ){
    if( arguments[i] < greatest ){
      return false;
    }
    greatest = arguments[i];
  }
  return true;
}

function lte(){
  var least = (Infinity);
  for( var i in arguments ){
    if( arguments[i] > least ){
      return false;
    }
    least = arguments[i];
  }
  return true;
}

function lt(){
  var least = (Infinity);
  for( var i in arguments ){
    if( arguments[i] >= least ){
      return false;
    }
    least = arguments[i];
  }
  return true;
}

function eq(){
  var it = arguments[0];
  for( var i in arguments ){
    if( arguments[i] != it ){
      return false;
    }
    it = arguments[i];
  }
  return true;
}

function nth(a, n){
  if( arrayp(a) ){
    return a[n];
  }
}

function count(a){
  if( arrayp(a) ){
    return a.length;
  } else if (hashp(a)) {
    return count( Object.keys(a) );
  }
}

function cons(a,as){
  return ([a].concat(as));
}

function map(f, a){
  return a.map(f);
}

function reduce(f, a, init){
  if(typeof init != "undefined"){
    return a.reduce(function(a,b){ return f(a,b) }, init);
  } else {
    return a.reduce(function(a,b){ return f(a,b) });
  }
}

function toJson( obj ){
  return JSON.stringify(obj, fixJson);
}

global = {
  values:{
    'eq?': eqp,
    'equal?': equalp,

    'list?': arrayp,
    'map?': hashp,
    'function?': functionp,
    'number?': numberp,
    'string?': stringp,

    '+': plus,
    '-': minus,
    // TODO: division and modulus
    // TODO: min, max

    '=':  eq,
    '>':  gt,
    '>=': gte,
    '<':  lt,
    '<=': lte,

    'get': get,
    'assoc': assoc,
    'keys': Object.keys,
    'values': values,

    'nth': nth,
    'count': count,
    'cons': cons,
    'map': map,
    'reduce': reduce,

    'print': write,
    'println': writeln,

    'serialize': toJson,
    'unserialize': JSON.parse,
  }
}

function input(){
  return document.getElementById('input').value;
}

function clearInput(){
  return document.getElementById('input').value = '';
}

function fixJson( key, obj ){
  if( functionp(obj) ){
    return "some-lambda"
  } else {
    return obj;
  }
}

function do_repl(){
  var expression = input();
  write( "> " + expression + "\n");
  try{
    var e = JSON.parse(expression);
  } catch(er) {
    write(er + "\n");
    return;
  }
  try{
    var r = brid( e, global );
  } catch(er) {
    write(er + "\n");
    return;
  }
  write( JSON.stringify(r, fixJson) + "\n" );
  clearInput();
}

function hello(){
  return document.getElementById('input').value = JSON.stringify(["println", ["quote", "hello world"]]);
}

function mapexample(){
  return document.getElementById('input').value = JSON.stringify(
    ["map", ["lambda", ["x"], ["+", "x", 1] ], ["quote", [1, 2, 3]] ]
  );
}

prelude = [ "begin",
  // curried multiplication
  ["define", "*", ["lambda", ["n"],
                   ["lambda", ["m"],
                    ["if", ["eq?", "m", 0],
                     0,
                     ["+", "n", [["*", "n"], ["-", "m", 1]]]]]]]
  // factorial
  ["define", "fact", ["lambda", ["n"],
                      ["if", ["eq?", "n", 0],
                       1,
                       [["*", "n"], ["fact", ["-", "n", 1]]]]]]
  ["define", "inc", ["lambda", ["x"], ["+", "x", 1] ] ],
  ["define", "dec", ["lambda", ["x"], ["-", "x", 1] ] ],
  ["define", "not", ["lambda", ["x"], ["if", "x", false, true]]],
  ["define", "zero?", ["lambda", ["x"], ["equal?", "x", 0]]],
  ["define", "pos?", ["lambda", ["x"], [">", "x", 0]]],
  ["define", "neg?", ["lambda", ["x"], ["<", "x", 0]]],
  ["define", "false", false],
  ["define", "true", true],
  ["define", "null", null],
]

brid( prelude, global );
<commit_msg>missing commas<commit_after>// An environment!
function makeEnv( keys, values, outer ){
  var env = {
    "values": makeHash(keys, values),
    "outer":  outer
  };
  return(env);
}

// Convenience function for above
function makeHash(keys, values){
  var hash = {};
  for (var i in keys) {
    hash[keys[i]] = values[i];
  }
  return hash;
}

function findEnv( env, key ){
  if( env.values.hasOwnProperty( key ) ){
    return env;
  }

  if( env.outer ){
    return findEnv( env.outer, key );
  }
}

function defInEnv( env, key, value ){
  return (env.values[key] = value);
}

// This function differs from the above
// in that it climbs to the environment
// where the key was originally defined
// to mutate it in place.
function setInEnv( env, key, value ){
  return (findEnv(env, key).values[key] = value);
}

function getFromEnv( env, key ){
  return (findEnv(env, key).values[key]);
}

function values( obj ){
  return Object.keys(obj).map(function(x){ return obj[x] });
}

function arrayp( a ){
  return ( a instanceof Array );
}

function functionp( a ){
  return ( a instanceof Function );
}

function hashp( a ){
  return ( a instanceof Object && !( arrayp(a) ) && !( functionp(a) ));
}

function numberp( a) {
  return (typeof a == "number");
}

function stringp( a) {
  return (typeof a == "string");
}

function brid(x, env){
  if( typeof x == "string" ){ // variable reference
    return getFromEnv(env, x);
  } else if( hashp(x) ){
    // unlike Clojure, our keys cannot be arbitrary objects
    // so let's not evaluate keys as expressions
    return makeHash(Object.keys(x), values(x).map(function(v){ return brid(v, env) }));
  } else if( !arrayp(x) ){ // constant literal
    return x;
  } else if(x.length == 0) {
    return [];
  } else if(x[0] == 'quote'){
    return x[1];
  } else if(x[0] == 'if'){
    var test   = x[1];
    var conseq = x[2];
    var alt    = x[3];
    var branch;
    if( brid(test, env) )
      { branch = conseq }
      else { branch = alt };
    return ( brid( branch, env ));
  } else if(x[0] == 'set!'){
    var v   = x[1];
    var exp = x[2];
    return (setInEnv(env, v, brid(exp, env)));
  } else if(x[0] == 'define'){
    var v   = x[1];
    var exp = x[2];
    return (defInEnv(env, v, brid(exp, env)));
  } else if(x[0] == 'lambda'){
    var vars = x[1];
    var exp  = x[2];
    // is it cheating to use the closure from here?
    var r = function(){ return brid( exp, makeEnv(vars, arguments, env) ) };
    return r;
  } else if(x[0] == 'begin'){
    var args = x.slice(1);
    var r;
    for(var i in args){
      r = brid(args[i], env)
    }
    return r;
  } else if(x[0] == 'eval'){
    var arg = x[1];
    var r = brid( brid(arg, env), env );
    return r;
  } else { // something user defined
    var exps = x.map(function(exp){ return brid(exp, env)});
    var proc = exps.shift();
    return proc.apply(proc, exps);
  }
}

// Grrr, JavaScript
function argsToArray(args){
  var r = [];
  for( var i in args ){
    r.push(args[i]);
  }
  return(r);
}

function plus(){
  return argsToArray(arguments).reduce(function(a,b){return a+b}, 0);
}

function minus(){
  if (arguments.length == 1){
    return -arguments[0];
  } else if (arguments.length > 1){
    return argsToArray(arguments).slice(1).reduce(function(a,b){return a-b}, arguments[0]);
  } else {
    throw "wrong number of arguments to -";
  }
}

function write(s){
  var output = document.getElementById('output');
  output.value += s;
  output.scrollTop = output.scrollHeight;
}

function writeln(s){
  write(s + "\n");
}

function get(hash, key){
  if( hash instanceof Object ){
    if( hash.hasOwnProperty( key ) ){
      return hash[key];
    }
  }
}

function copyHash( hash ){
  var keys = Object.keys(hash);
  var r = {};
  for( var i in keys ){
    var key = keys[i];
    if( hash.hasOwnProperty( key ) ){
      r[key] = hash[key];
    }
  }
  return r;
}

function assoc(hash, key, value){
  var r = copyHash(hash);
  r[key] = value;
  return r;
}

function eqp(a, b){
  return a === b;
}

function equalp(a, b){
  if(typeof(a) != typeof(b)){
    return false;
  }

  if( arrayp(a) ){
    return arrayp(b) && arrayEquals(a,b);
  }

  if( hashp(a) ){
    return hashp(b) && hashEquals(a,b);
  }
  return a == b;
}

function arrayEquals(a, b){
  if( a.length != b.length ){
    return false;
  }
  for( var i in a ){
    if(a[i] != b[i]){
      return false;
    }
  }
  return true;
}

function hashEquals(a, b){
  return arrayEquals(Object.keys(a), Object.keys(b)) && arrayEquals(values(a), values(b))
}

function gt(){
  var greatest = (-Infinity);
  for( var i in arguments ){
    if( arguments[i] <= greatest ){
      return false;
    }
    greatest = arguments[i];
  }
  return true;
}

function gte(){
  var greatest = (-Infinity);
  for( var i in arguments ){
    if( arguments[i] < greatest ){
      return false;
    }
    greatest = arguments[i];
  }
  return true;
}

function lte(){
  var least = (Infinity);
  for( var i in arguments ){
    if( arguments[i] > least ){
      return false;
    }
    least = arguments[i];
  }
  return true;
}

function lt(){
  var least = (Infinity);
  for( var i in arguments ){
    if( arguments[i] >= least ){
      return false;
    }
    least = arguments[i];
  }
  return true;
}

function eq(){
  var it = arguments[0];
  for( var i in arguments ){
    if( arguments[i] != it ){
      return false;
    }
    it = arguments[i];
  }
  return true;
}

function nth(a, n){
  if( arrayp(a) ){
    return a[n];
  }
}

function count(a){
  if( arrayp(a) ){
    return a.length;
  } else if (hashp(a)) {
    return count( Object.keys(a) );
  }
}

function cons(a,as){
  return ([a].concat(as));
}

function map(f, a){
  return a.map(f);
}

function reduce(f, a, init){
  if(typeof init != "undefined"){
    return a.reduce(function(a,b){ return f(a,b) }, init);
  } else {
    return a.reduce(function(a,b){ return f(a,b) });
  }
}

function toJson( obj ){
  return JSON.stringify(obj, fixJson);
}

global = {
  values:{
    'eq?': eqp,
    'equal?': equalp,

    'list?': arrayp,
    'map?': hashp,
    'function?': functionp,
    'number?': numberp,
    'string?': stringp,

    '+': plus,
    '-': minus,
    // TODO: division and modulus
    // TODO: min, max

    '=':  eq,
    '>':  gt,
    '>=': gte,
    '<':  lt,
    '<=': lte,

    'get': get,
    'assoc': assoc,
    'keys': Object.keys,
    'values': values,

    'nth': nth,
    'count': count,
    'cons': cons,
    'map': map,
    'reduce': reduce,

    'print': write,
    'println': writeln,

    'serialize': toJson,
    'unserialize': JSON.parse,
  }
}

function input(){
  return document.getElementById('input').value;
}

function clearInput(){
  return document.getElementById('input').value = '';
}

function fixJson( key, obj ){
  if( functionp(obj) ){
    return "some-lambda"
  } else {
    return obj;
  }
}

function do_repl(){
  var expression = input();
  write( "> " + expression + "\n");
  try{
    var e = JSON.parse(expression);
  } catch(er) {
    write(er + "\n");
    return;
  }
  try{
    var r = brid( e, global );
  } catch(er) {
    write(er + "\n");
    return;
  }
  write( JSON.stringify(r, fixJson) + "\n" );
  clearInput();
}

function hello(){
  return document.getElementById('input').value = JSON.stringify(["println", ["quote", "hello world"]]);
}

function mapexample(){
  return document.getElementById('input').value = JSON.stringify(
    ["map", ["lambda", ["x"], ["+", "x", 1] ], ["quote", [1, 2, 3]] ]
  );
}

prelude = [ "begin",
  // curried multiplication
  ["define", "*", ["lambda", ["n"],
                   ["lambda", ["m"],
                    ["if", ["eq?", "m", 0],
                     0,
                     ["+", "n", [["*", "n"], ["-", "m", 1]]]]]]],
  // factorial
  ["define", "fact", ["lambda", ["n"],
                      ["if", ["eq?", "n", 0],
                       1,
                       [["*", "n"], ["fact", ["-", "n", 1]]]]]],
  ["define", "inc", ["lambda", ["x"], ["+", "x", 1] ] ],
  ["define", "dec", ["lambda", ["x"], ["-", "x", 1] ] ],
  ["define", "not", ["lambda", ["x"], ["if", "x", false, true]]],
  ["define", "zero?", ["lambda", ["x"], ["equal?", "x", 0]]],
  ["define", "pos?", ["lambda", ["x"], [">", "x", 0]]],
  ["define", "neg?", ["lambda", ["x"], ["<", "x", 0]]],
  ["define", "false", false],
  ["define", "true", true],
  ["define", "null", null],
]

brid( prelude, global );
<|endoftext|>


<commit_before>const {
    /*-1 */COMMENT,
    /* 0 */SPACE,
    /* 1 */STRAP,
    /* 2 */STAMP,
    /* 3 */VALUE,
    /* 4 */QUOTED,
    /* 5 */PIECE,
    /* 6 */EXPRESS,
    /* 7 */SCOPED,
    /* 8 */LABEL,
    /* 9 */PROPERTY,
    skipAssignment,
    getDeclared,
    createScoped,
    createString,
} = require("./common");
var strings = require("../basic/strings");

/**
 * 按语句分割代码
 */
var createExpressList = function (parsed) {
    var list = [];
    for (var cx = 0, dx = parsed.length; cx < dx; cx++) {
        var o = parsed[cx];
        switch (o.type) {
            case LABEL:
                var exp = [o];
                exp.first = exp[0];
                list.push(exp);
                break;
            case STRAP:
            case SCOPED:
            case EXPRESS:
            case VALUE:
            case QUOTED:
                var o0 = skipAssignment(o);
                var exp = [];
                do {
                    exp.push(o);
                    o = parsed[++cx];
                } while (o0 !== o);
                cx--;
                patchExpress(exp);
                list.push(exp);
                break;
            case COMMENT:
            case SPACE:
            case STAMP:
                list.push([o]);
                break;
            default:
                console.log(o.type, 'type');
        }
    }
    return list;
};
var getFunctionEnd = function (first) {
    if (!first) return false;
    var o = first.next;
    if (!o) return false;
    if (first.type === STRAP && first.text === 'function') {
        if (o.type === EXPRESS) o = o.next;
        if (!o) return false;
        if (o.next && !o.next.next) return o.next;
    }
    return false;
}
var patchExpress = function (exp) {
    if (!exp.first) {
        exp.first = exp[0];
    }
    if (!exp.lastUncomment) {
        exp.lastUncomment = exp[exp.length - 1];
    }
    if (exp.first) {
        delete exp.first.prev;
    }
    if (exp.lastUncomment) {
        delete exp.lastUncomment.next;
    }
    var first = exp.first;
    if (first && first.type === QUOTED && /^(['"`])use strict\1/i.test(first.text)) {
        exp.saved = true;
    }
    if (first && first.type === SCOPED && first.entry === '(') {
        var ff = first.first;
        var fn = first.next;
        if (fn && fn.type === SCOPED && fn.entry === '(') {
            var fe = getFunctionEnd(ff);
            if (fe) {
                first.push(fn);
                var fnn = fn.next;
                if (fnn) {
                    first.next = fnn;
                    fnn.prev = first;
                }
                fn.prev = fe;
                fe.next = fn;
                delete fn.next;
                exp.splice(1, 1);
            }
        }
    }
};

function createExpressKey(exp) {
    var keys = [];
    for (var e of exp) {
        if (e.type === EXPRESS) {
            var t = e.text;
            while (t.length > 0) {
                if (/^\./.test(t)) {
                    if (!keys.length) keys.push('');
                    t = t.slice(1);
                }
                var m = /[^\.\[]+/.exec(t);
                if (m) {
                    m = m[0];
                    keys.push(m);
                    t = t.slice(m.length);
                    continue;
                }
                var m = /^\[(['"`])([\s\S]*?)\1\]/.exec(t)
                if (m) {
                    m = m[0];
                    t = t.slice(m.length);
                    m = m.slice(1, m.length - 1);
                    m = strings.decode(m);
                    keys.push(m);
                    continue;
                }
                break;
            }
        }
    }
    return keys.join('.');
}
function needLeft(o) {
    if (o.type === EXPRESS && /^[\.\[]/.test(o.text)) return true;
    if (o.type === SCOPED && o.entry === '[') return true;
    return false;
}
function needRight(o) {
    if (o.type === EXPRESS && /[\.\]]$/.test(o.text)) return true;
    if (o.type === SCOPED && o.entry === '[') return true;
    return false;
}
function renameId(id, amap) {
    var m = /^[^\.]+/.exec(id);
    if (m) {
        var id0 = m[0];
        var w = amap[id0];
        if (w) return w + id.slice(id0.length);
    }
};
function checkRefered(scope) {
    var { used } = scope;
    var map = Object.create(null);
    for (var k in used) {
        var u = used[k];
        for (var o of u) {
            var right = [];
            var e = o;
            while (e) {
                if (right.length) {
                    if (!needRight(right[right.length - 1]) && !needLeft(e)) break;
                }
                right.push(e);
                e = e.next;
            }
            if (right.length) {
                var key = createExpressKey(right);
                var iswrite = false;
                iswrite = !!o.kind || !!e && e.type === STAMP && /=$/.test(e.text);
                if (key) map[key] = map[key] | 1 + iswrite;
            }
        }
    }
    var readed, writed;
    for (var k in map) {
        if (map[k] >> 1) {
            if (!writed) writed = Object.create(null);
            writed[k] = true;
        }
        if (map[k] & 1) {
            if (!readed) readed = Object.create(null);
            readed[k] = true;
        }
    }
    for (var s of scope) {
        if (s.isfunc && s.pass) {
            var [writed0, readed0] = checkRefered(s);
            var { pass, args } = s;
            var amap = {};
            for (var cx = 0, dx = pass.length; cx < dx; cx++) {
                amap[args[cx]] = pass[cx];
            }
            for (var w in writed0) {
                var id = renameId(w, amap);
                if (id) writed[id] = true;
            }
            for (var r in readed0) {
                var id = renameId(r, amap);
                if (id) readed[id] = true;
            }
        }
    }

    return [writed, readed];
}

var getroot = function (pick) {
    if (pick) {
        var match = /^[^\.]+/.exec(pick);
        if (match) match = match[0];
        return match;
    }
}

function washcode(code, pick) {
    var avoid = getroot(pick);
    var needs = Object.assign(Object.create(null), pick ? { [pick]: true } : code.envs);
    var explist = createExpressList(code);
    var maped = Object.create(null);
    for (var exp of explist) {
        exp.scoped = createScoped(exp, true);
        if (avoid && avoid in exp.scoped.used) {
            if (code.vars[avoid] && !code.envs[avoid] && !maped[avoid]) {
                exp.saved = true;
                maped[avoid] = true;
            }
        }
        var [writed, readed] = checkRefered(exp.scoped);
        exp.writed = writed;
        exp.readed = readed;
    }
    var count = 0;
    while (count < explist.length) {
        var saved_count = count;
        for (var exp of explist) {
            if (exp.saved) continue;
            if (!exp.first) {
                exp.saved = true;
                count++;
                break;
            }
            var { writed, readed } = exp;
            for (var w in writed) {
                if (w === avoid) continue;
                if (needs[w] || getroot(w) in code.envs) {
                    exp.saved = true;
                    for (var r in readed) {

                        var rs = r.split('.');
                        while (rs.length) {
                            needs[rs.join('.')] = true;
                            rs.pop();
                        }
                    }
                    count++;
                    break;
                }
            }
        }
        if (saved_count === count) break;
    }
    for (var cx = 0, dx = explist.length; cx < dx; cx++) {
        var exp = explist[cx];
        var prev = explist[cx - 1], next = explist[cx + 1];
        if (!exp.first) {
            if (!exp.saved) continue;
            if (exp.length !== 1 || !prev && !next) continue;
            if (exp[0].type === STAMP) {
                if (prev && !prev.saved || next && !next.saved) {
                    exp.saved = false;
                }
                continue;
            }
            if (next && !next.saved) {
                exp.saved = false;
            }
            continue;
        }
        if (!exp.saved) {
            if (exp[0].type === STRAP && /^(let|var|const)$/.test(exp[0].text)) {
                var save = false, inc = 2;
                while (next && next[0].type === STAMP && /^,$/.test(next[0].text)) {
                    next.saved = false;
                    next = explist[cx + inc++];
                    if (!next) break;
                    if (next.saved) {
                        save = true;
                        break;
                    }
                    next = explist[cx + inc++];
                }
                exp.saved = save;
                if (exp.saved) {
                    if (!prev.saved) prev.saved = true;
                    exp.splice(1, exp.length - 1, ' ');
                    patchExpress(exp);
                }
            }
        }
    }
    explist = explist.filter(e => e.saved);
    var text = explist.map(createString).join("");
    return text;
}

module.exports = washcode;<commit_msg>修复一处错误<commit_after>const {
    /*-1 */COMMENT,
    /* 0 */SPACE,
    /* 1 */STRAP,
    /* 2 */STAMP,
    /* 3 */VALUE,
    /* 4 */QUOTED,
    /* 5 */PIECE,
    /* 6 */EXPRESS,
    /* 7 */SCOPED,
    /* 8 */LABEL,
    /* 9 */PROPERTY,
    skipAssignment,
    getDeclared,
    createScoped,
    createString,
} = require("./common");
var strings = require("../basic/strings");

/**
 * 按语句分割代码
 */
var createExpressList = function (parsed) {
    var list = [];
    for (var cx = 0, dx = parsed.length; cx < dx; cx++) {
        var o = parsed[cx];
        switch (o.type) {
            case LABEL:
                var exp = [o];
                exp.first = exp[0];
                list.push(exp);
                break;
            case STRAP:
            case SCOPED:
            case EXPRESS:
            case VALUE:
            case QUOTED:
                var o0 = skipAssignment(o);
                var exp = [];
                do {
                    exp.push(o);
                    o = parsed[++cx];
                } while (o0 !== o);
                cx--;
                patchExpress(exp);
                list.push(exp);
                break;
            case COMMENT:
            case SPACE:
            case STAMP:
                list.push([o]);
                break;
            default:
                console.log(o.type, 'type');
        }
    }
    return list;
};
var getFunctionEnd = function (first) {
    if (!first) return false;
    var o = first.next;
    if (!o) return false;
    if (first.type === STRAP && first.text === 'function') {
        if (o.type === EXPRESS) o = o.next;
        if (!o) return false;
        if (o.next && !o.next.next) return o.next;
    }
    return false;
}
var patchExpress = function (exp) {
    if (!exp.first) {
        exp.first = exp[0];
    }
    if (!exp.lastUncomment) {
        exp.lastUncomment = exp[exp.length - 1];
    }
    if (exp.first) {
        delete exp.first.prev;
    }
    if (exp.lastUncomment) {
        delete exp.lastUncomment.next;
    }
    var first = exp.first;
    if (first && first.type === QUOTED && /^(['"`])use strict\1/i.test(first.text)) {
        exp.saved = true;
    }
    if (first && first.type === SCOPED && first.entry === '(') {
        var ff = first.first;
        var fn = first.next;
        if (fn && fn.type === SCOPED && fn.entry === '(') {
            var fe = getFunctionEnd(ff);
            if (fe) {
                first.push(fn);
                var fnn = fn.next;
                if (fnn) {
                    first.next = fnn;
                    fnn.prev = first;
                }
                fn.prev = fe;
                fe.next = fn;
                delete fn.next;
                exp.splice(1, 1);
            }
        }
    }
};

function createExpressKey(exp) {
    var keys = [];
    for (var e of exp) {
        if (e.type === EXPRESS) {
            var t = e.text;
            while (t.length > 0) {
                if (/^\./.test(t)) {
                    if (!keys.length) keys.push('');
                    t = t.slice(1);
                }
                var m = /[^\.\[]+/.exec(t);
                if (m) {
                    m = m[0];
                    keys.push(m);
                    t = t.slice(m.length);
                    continue;
                }
                var m = /^\[(['"`])([\s\S]*?)\1\]/.exec(t)
                if (m) {
                    m = m[0];
                    t = t.slice(m.length);
                    m = m.slice(1, m.length - 1);
                    m = strings.decode(m);
                    keys.push(m);
                    continue;
                }
                break;
            }
        }
    }
    return keys.join('.');
}
function needLeft(o) {
    if (o.type === EXPRESS && /^[\.\[]/.test(o.text)) return true;
    if (o.type === SCOPED && o.entry === '[') return true;
    return false;
}
function needRight(o) {
    if (o.type === EXPRESS && /[\.\]]$/.test(o.text)) return true;
    if (o.type === SCOPED && o.entry === '[') return true;
    return false;
}
function renameId(id, amap) {
    var m = /^[^\.]+/.exec(id);
    if (m) {
        var id0 = m[0];
        var w = amap[id0];
        if (w) return w + id.slice(id0.length);
    }
};
function checkRefered(scope) {
    var { used } = scope;
    var map = Object.create(null);
    for (var k in used) {
        var u = used[k];
        for (var o of u) {
            var right = [];
            var e = o;
            while (e) {
                if (right.length) {
                    if (!needRight(right[right.length - 1]) && !needLeft(e)) break;
                }
                right.push(e);
                e = e.next;
            }
            if (right.length) {
                var key = createExpressKey(right);
                var iswrite = false;
                iswrite = !!o.kind || !!e && e.type === STAMP && /(?<![\!\=])\=$/.test(e.text);
                if (key) map[key] = map[key] | 1 + iswrite;
            }
        }
    }
    var readed, writed;
    for (var k in map) {
        if (map[k] >> 1) {
            if (!writed) writed = Object.create(null);
            writed[k] = true;
        }
        if (map[k] & 1) {
            if (!readed) readed = Object.create(null);
            readed[k] = true;
        }
    }
    for (var s of scope) {
        if (s.isfunc && s.pass) {
            var [writed0, readed0] = checkRefered(s);
            var { pass, args } = s;
            var amap = {};
            for (var cx = 0, dx = pass.length; cx < dx; cx++) {
                amap[args[cx]] = pass[cx];
            }
            for (var w in writed0) {
                var id = renameId(w, amap);
                if (id) writed[id] = true;
            }
            for (var r in readed0) {
                var id = renameId(r, amap);
                if (id) readed[id] = true;
            }
        }
    }

    return [writed, readed];
}

var getroot = function (pick) {
    if (pick) {
        var match = /^[^\.]+/.exec(pick);
        if (match) match = match[0];
        return match;
    }
}

function washcode(code, pick) {
    var avoid = getroot(pick);
    var needs = Object.assign(Object.create(null), pick ? { [pick]: true } : code.envs);
    var explist = createExpressList(code);
    var maped = Object.create(null);
    for (var exp of explist) {
        exp.scoped = createScoped(exp, true);
        if (avoid && avoid in exp.scoped.used) {
            if (code.vars[avoid] && !code.envs[avoid] && !maped[avoid]) {
                exp.saved = true;
                maped[avoid] = true;
            }
        }
        var [writed, readed] = checkRefered(exp.scoped);
        exp.writed = writed;
        exp.readed = readed;
    }
    var count = 0;
    while (count < explist.length) {
        var saved_count = count;
        for (var exp of explist) {
            if (exp.saved) continue;
            if (!exp.first) {
                exp.saved = true;
                count++;
                break;
            }
            var { writed, readed } = exp;
            for (var w in writed) {
                if (w === avoid) continue;
                if (needs[w] || getroot(w) in code.envs) {
                    exp.saved = true;
                    for (var r in readed) {

                        var rs = r.split('.');
                        while (rs.length) {
                            needs[rs.join('.')] = true;
                            rs.pop();
                        }
                    }
                    count++;
                    break;
                }
            }
        }
        if (saved_count === count) break;
    }
    for (var cx = 0, dx = explist.length; cx < dx; cx++) {
        var exp = explist[cx];
        var prev = explist[cx - 1], next = explist[cx + 1];
        if (!exp.first) {
            if (!exp.saved) continue;
            if (exp.length !== 1 || !prev && !next) continue;
            if (exp[0].type === STAMP) {
                if (prev && !prev.saved || next && !next.saved) {
                    exp.saved = false;
                }
                continue;
            }
            if (next && !next.saved) {
                exp.saved = false;
            }
            continue;
        }
        if (!exp.saved) {
            if (exp[0].type === STRAP && /^(let|var|const)$/.test(exp[0].text)) {
                var save = false, inc = 2;
                while (next && next[0].type === STAMP && /^,$/.test(next[0].text)) {
                    next.saved = false;
                    next = explist[cx + inc++];
                    if (!next) break;
                    if (next.saved) {
                        save = true;
                        break;
                    }
                    next = explist[cx + inc++];
                }
                exp.saved = save;
                if (exp.saved) {
                    if (!prev.saved) prev.saved = true;
                    exp.splice(1, exp.length - 1, ' ');
                    patchExpress(exp);
                }
            }
        }
    }
    explist = explist.filter(e => e.saved);
    var text = explist.map(createString).join("");
    return text;
}

module.exports = washcode;<|endoftext|>


<commit_before>var testJson = [{
  type: "purchase", f: "avg", field: "amount", operator: ">", value: 5,
  conditions: ["amount", ">", 2, "and", "price", "==", 40]
},
	"and", {
		type: "pageview", f: "count", field: "pid", operator: ">", value: 5,
		conditions: ["amount", ">", 5, "and", "price", "==", "30"]
	},
  "and", {
    type: undefined,
    conditions:["gender", "contains", 'male']

  }];

//purpose: build javascript code based on json condition
//example: buildConditionsCode(["amount", ">", 5, "and", "price", "=", "30"])
//return: string contains compiled javascript code
//param: array of conditions, [field, operator, value, joinoperator, field, operator, value, ...]
function buildConditionsCode(conditions) {
  var i = 0;
  var code = "";
  while (i < conditions.length) {
    //get the next operator (if exist)
    var nextop = i + 3 < conditions.length ? conditions[i + 3] : "";
		if(nextop == 'and') nextop = '&&';
		else if(nextop =='or') nextop = '||';
		else if(nextop !== '') throw "wrong joining operation: " + nextop;

		var operator = conditions[i + 1];
    //append new compiled js code
		if (['>', '<', '>=', '<=', '!==', '=='].indexOf(operator) !== -1)
			code += "(this." + conditions[i] + operator + JSON.stringify(conditions[i + 2]) + ")" + nextop;
		else if([ 'startsWith', 'endsWith',].indexOf(operator)!== -1)
		{
			code += "(this." + conditions[i] + '.' + operator +'(' + JSON.stringify(conditions[i + 2]) + ")==true)" + nextop;

		} else if(operator == 'contains')
		{
			code += "(this." + conditions[i] + '.indexOf(' + JSON.stringify(conditions[i + 2]) + ")!== -1)" + nextop;
		}
		else if(operator == '!contains')
		{
			code += "(this." + conditions[i] + '.indexOf(' + JSON.stringify(conditions[i + 2]) + ")=== -1)" + nextop;
		}
		else if(operator == "!startsWith")
		{
			code += "(!this." + conditions[i] + '.startsWith(' + JSON.stringify(conditions[i + 2]) + "))" + nextop;
		}
		else if(operator == "!endsWith")
		{
			code += "(!this." + conditions[i] + '.endsWith(' + JSON.stringify(conditions[i + 2]) + "))" + nextop;
		}
		else if(operator == 'isset')
		{
			code += "(!this." + conditions[i] + ' !==undefined)' + nextop;
		}
		else if(operator == '!isset')
		{
			code += "(!this." + conditions[i] + ' ===undefined)' + nextop;
		}
		else{
			throw 'not supported operator: ' + operator;
		}
		i += 4;
  }
  return code;
}

function buildReduceChunk(ind, condition) {

}

//purpose: build a piece of map function
//example: buildMapChunk({actiontype: "pageview", conditions: [{f: "count", field: "pid", operator: ">", value: 5, conditions: ["amount", ">", 5, "and", "price", "=", "dd"]})
//return: string contains compiled javascript code
//param: i=index of condition, for iteration purpose, condition=see example
function buildChunk(ind, element) {
  var reducecondcode = "";
  var reduceinitcode = "";
  var reduceaggcode = ""
  var code = "if(this.actiontype==='" + element.type + "'){";
  var conditions = element.conditions;
  var defvalcode = "";
  var aggcode = "";
  //get the condition code
  if (element.conditions === undefined) console.log(element);
  var inlineconditions = buildConditionsCode(element.conditions);

  //if the query is to count then just map 1, but if the query is to sum
  // and calculate average then have to map field's value
  if (element.f === "count") {
    code += "value.f" + ind + "=(" + inlineconditions + ")?1:0;";
    reduceinitcode += "returnObject.f" + ind + "=0;";
    reduceaggcode += "returnObject.f" + ind + "+=value.f" + ind + ";";
    defvalcode += "value.f" + ind + "=0;";
    reducecondcode += "(value.f" + ind + element.operator + JSON.stringify(element.value) + ")";
  }
  else if (element.f === "sum") {
    code += "value.f" + ind + "=(" + inlineconditions + ")?this." + element.field + ":0;";
    reduceinitcode += "returnObject.f" + ind + "=0;";
    reduceaggcode += "returnObject.f" + ind + "+=value.f" + ind + ";";
    defvalcode += "value.f" + ind + "=0;";
    reducecondcode += "(value.f" + ind + element.operator + JSON.stringify(element.value) + ")";
  }
  else if (element.f === "avg") {
    code += "value.f" + ind + "_1=(" + inlineconditions + ")?this." + element.field + ":0;";
    code += "value.f" + ind + "_2=(" + inlineconditions + ")?1:0;";
    reduceinitcode += "returnObject.f" + ind + "_1=0;";
    reduceaggcode += "returnObject.f" + ind + "_1+=value.f" + ind + "_1;";
    reduceinitcode += "returnObject.f" + ind + "_2=0;";
    reduceaggcode += "returnObject.f" + ind + "_2+=value.f" + ind + "_2;";
    defvalcode += "value.f" + ind + "_1=0;";
    defvalcode += "value.f" + ind + "_2=0;";
    reducecondcode += "(1.0*value.f" + ind + "_1/value.f" + ind + "_2" + element.operator + JSON.stringify(element.value) + ")";
  }
  else throw "wrong operator";

  code = defvalcode + code + "};";
  return {
    mapcode: code,
    reduceinitcode: reduceinitcode,
    reducecondcode: reducecondcode,
    reduceaggcode: reduceaggcode
  };
}

//purpose: build a javascript map function from a json query
//example: buildMapFunction(testJson)
//return: string contains compiled javascript code
//param: query=see testJson
function buildMapReduce(query) {
  var mapfunccode = "function(){var value={};";
  var reducecondcode = "";
  var reduceinitcode = "";
  var reduceaggcode = "";

  var i = 0;
  while (i < query.length) {
    if (i % 2 == 0) {
      var tmpcode = buildChunk(i / 2, query[i]);
      mapfunccode += tmpcode.mapcode;
      reduceinitcode += tmpcode.reduceinitcode;
      reducecondcode += tmpcode.reducecondcode;
      reduceaggcode += tmpcode.reduceaggcode;
    }
    else {
			var joinop = query[i];
			if(joinop === 'and') joinop = '&&';
			else if(joinop === 'or') joinop = '||';
			else throw "wrong join operator: " + joinop;
      reducecondcode += joinop;
    }
    i++;
  }
  mapfunccode += "}";

  var reducefunccode = "function(key,values){var returnObject={};" + reduceinitcode + "for(var i in values){var value=values[i];" + reduceaggcode + "};return " + reducecondcode + "?key:null;}";
  return { map: mapfunccode, reduce: reducefunccode };
}
<commit_msg>fix interface<commit_after>var testJson = [{
  type: "purchase", f: "avg", field: "amount", operator: ">", value: 5,
  conditions: ["amount", ">", 2, "and", "price", "==", 40]
},
	"and", {
		type: "pageview", f: "count", field: "pid", operator: ">", value: 5,
		conditions: ["amount", ">", 5, "and", "price", "==", "30"]
	},
  "and", {
    type: undefined, field: 'gender',  operator: 'equal', value: 'male'

  }];

//purpose: build javascript code based on json condition
//example: buildConditionsCode(["amount", ">", 5, "and", "price", "=", "30"])
//return: string contains compiled javascript code
//param: array of conditions, [field, operator, value, joinoperator, field, operator, value, ...]
function buildConditionsCode(conditions) {
  var i = 0;
  var code = "";
  while (i < conditions.length) {
    //get the next operator (if exist)
    var nextop = i + 3 < conditions.length ? conditions[i + 3] : "";
		if(nextop == 'and') nextop = '&&';
		else if(nextop =='or') nextop = '||';
		else if(nextop !== '') throw "wrong joining operation: " + nextop;

		var operator = conditions[i + 1];
    //append new compiled js code
		if (['>', '<', '>=', '<=', '!==', '=='].indexOf(operator) !== -1)
			code += "(this." + conditions[i] + operator + JSON.stringify(conditions[i + 2]) + ")" + nextop;
		else if([ 'startsWith', 'endsWith',].indexOf(operator)!== -1)
		{
			code += "(this." + conditions[i] + '.' + operator +'(' + JSON.stringify(conditions[i + 2]) + ")==true)" + nextop;

		} else if(operator == 'contains')
		{
			code += "(this." + conditions[i] + '.indexOf(' + JSON.stringify(conditions[i + 2]) + ")!== -1)" + nextop;
		}
		else if(operator == '!contains')
		{
			code += "(this." + conditions[i] + '.indexOf(' + JSON.stringify(conditions[i + 2]) + ")=== -1)" + nextop;
		}
		else if(operator == "!startsWith")
		{
			code += "(!this." + conditions[i] + '.startsWith(' + JSON.stringify(conditions[i + 2]) + "))" + nextop;
		}
		else if(operator == "!endsWith")
		{
			code += "(!this." + conditions[i] + '.endsWith(' + JSON.stringify(conditions[i + 2]) + "))" + nextop;
		}
		else if(operator == 'isset')
		{
			code += "(!this." + conditions[i] + ' !==undefined)' + nextop;
		}
		else if(operator == '!isset')
		{
			code += "(!this." + conditions[i] + ' ===undefined)' + nextop;
		}
		else{
			throw 'not supported operator: ' + operator;
		}
		i += 4;
  }
  return code;
}

function buildReduceChunk(ind, condition) {

}

//purpose: build a piece of map function
//example: buildMapChunk({actiontype: "pageview", conditions: [{f: "count", field: "pid", operator: ">", value: 5, conditions: ["amount", ">", 5, "and", "price", "=", "dd"]})
//return: string contains compiled javascript code
//param: i=index of condition, for iteration purpose, condition=see example
function buildChunk(ind, element) {
  var reducecondcode = "";
  var reduceinitcode = "";
  var reduceaggcode = ""
  var code = "if(this.actiontype==='" + element.type + "'){";
  var conditions = element.conditions;
  var defvalcode = "";
  var aggcode = "";
  //get the condition code
  if (element.conditions === undefined) console.log(element);
  var inlineconditions = buildConditionsCode(element.conditions);

  //if the query is to count then just map 1, but if the query is to sum
  // and calculate average then have to map field's value
  if (element.f === "count") {
    code += "value.f" + ind + "=(" + inlineconditions + ")?1:0;";
    reduceinitcode += "returnObject.f" + ind + "=0;";
    reduceaggcode += "returnObject.f" + ind + "+=value.f" + ind + ";";
    defvalcode += "value.f" + ind + "=0;";
    reducecondcode += "(value.f" + ind + element.operator + JSON.stringify(element.value) + ")";
  }
  else if (element.f === "sum") {
    code += "value.f" + ind + "=(" + inlineconditions + ")?this." + element.field + ":0;";
    reduceinitcode += "returnObject.f" + ind + "=0;";
    reduceaggcode += "returnObject.f" + ind + "+=value.f" + ind + ";";
    defvalcode += "value.f" + ind + "=0;";
    reducecondcode += "(value.f" + ind + element.operator + JSON.stringify(element.value) + ")";
  }
  else if (element.f === "avg") {
    code += "value.f" + ind + "_1=(" + inlineconditions + ")?this." + element.field + ":0;";
    code += "value.f" + ind + "_2=(" + inlineconditions + ")?1:0;";
    reduceinitcode += "returnObject.f" + ind + "_1=0;";
    reduceaggcode += "returnObject.f" + ind + "_1+=value.f" + ind + "_1;";
    reduceinitcode += "returnObject.f" + ind + "_2=0;";
    reduceaggcode += "returnObject.f" + ind + "_2+=value.f" + ind + "_2;";
    defvalcode += "value.f" + ind + "_1=0;";
    defvalcode += "value.f" + ind + "_2=0;";
    reducecondcode += "(1.0*value.f" + ind + "_1/value.f" + ind + "_2" + element.operator + JSON.stringify(element.value) + ")";
  }
  else throw "wrong operator";

  code = defvalcode + code + "};";
  return {
    mapcode: code,
    reduceinitcode: reduceinitcode,
    reducecondcode: reducecondcode,
    reduceaggcode: reduceaggcode
  };
}

//purpose: build a javascript map function from a json query
//example: buildMapFunction(testJson)
//return: string contains compiled javascript code
//param: query=see testJson
function buildMapReduce(query) {
  var mapfunccode = "function(){var value={};";
  var reducecondcode = "";
  var reduceinitcode = "";
  var reduceaggcode = "";

  var i = 0;
  while (i < query.length) {
    if (i % 2 == 0) {
      var tmpcode = buildChunk(i / 2, query[i]);
      mapfunccode += tmpcode.mapcode;
      reduceinitcode += tmpcode.reduceinitcode;
      reducecondcode += tmpcode.reducecondcode;
      reduceaggcode += tmpcode.reduceaggcode;
    }
    else {
			var joinop = query[i];
			if(joinop === 'and') joinop = '&&';
			else if(joinop === 'or') joinop = '||';
			else throw "wrong join operator: " + joinop;
      reducecondcode += joinop;
    }
    i++;
  }
  mapfunccode += "}";

  var reducefunccode = "function(key,values){var returnObject={};" + reduceinitcode + "for(var i in values){var value=values[i];" + reduceaggcode + "};return " + reducecondcode + "?key:null;}";
  return { map: mapfunccode, reduce: reducefunccode };
}
<|endoftext|>


<commit_before>"use strict";

var crypto = require('crypto');
var extend = require('extend');
var fs = require('fs');

var logger = require('./logger');

function from_string(string, options) {
  var shasum = crypto.createHash('sha256');
  var reply = {
    resource: string,
    malicious: false,
    scanned: new Date().toISOString(),
    options: options
  };

  return new Promise((fulfill) => {
    shasum.update(string);
    reply.hash = "text::" + shasum.digest('base64');
    logger.debug(`Hash from text "${reply.hash}"`);
    fulfill(reply);
  });
}

function from_filename(filename, options) {
  var shasum = crypto.createHash('sha256');
  var reply = {
    filename: filename,
    malicious: false,
    scanned: new Date().toISOString(),
    options: options
  };

  logger.debug(`Creating hash from ${filename}`);

  return new Promise((fulfill, reject) => {
    var s = fs.ReadStream(filename);
    try {
      s.on('data', (d) => {
        shasum.update(d)
      });
      s.on('end', () => {
        reply.hash = "file::" + shasum.digest('base64');
        logger.debug(`${reply.filename} hashed to "${reply.hash}"`);
        fulfill(reply)
      });
    } catch (ex) {
      reply.hash = ex;
      reject(reply);
    }
  });
}

module.exports = {
  from_string: from_string,
  from_filename: from_filename
};
<commit_msg>refactor: strip `text` and `file` from hashes<commit_after>"use strict";

var crypto = require('crypto');
var extend = require('extend');
var fs = require('fs');

var logger = require('./logger');

function from_string(string, options) {
  var shasum = crypto.createHash('sha256');
  var reply = {
    resource: string,
    malicious: false,
    scanned: new Date().toISOString(),
    options: options
  };

  return new Promise((fulfill) => {
    shasum.update(string);
    reply.hash = shasum.digest('base64');
    logger.debug(`Hash from text "${reply.hash}"`);
    fulfill(reply);
  });
}

function from_filename(filename, options) {
  var shasum = crypto.createHash('sha256');
  var reply = {
    filename: filename,
    malicious: false,
    scanned: new Date().toISOString(),
    options: options
  };

  logger.debug(`Creating hash from ${filename}`);

  return new Promise((fulfill, reject) => {
    var s = fs.ReadStream(filename);
    try {
      s.on('data', (d) => {
        shasum.update(d)
      });
      s.on('end', () => {
        reply.hash = shasum.digest('base64');
        logger.debug(`${reply.filename} hashed to "${reply.hash}"`);
        fulfill(reply)
      });
    } catch (ex) {
      reply.hash = ex;
      reject(reply);
    }
  });
}

module.exports = {
  from_string: from_string,
  from_filename: from_filename
};
<|endoftext|>


<commit_before>jsio('from shared.javascript import bind')
jsio('import server.Server')
jsio('import fan.sha1 as sha1')
jsio('import fan.keys')

exports = Class(server.Server, function(supr) {

	// Stamp all mutations with the user who originated it
	this.mutateItem = function(mutation, origConnection) {
		mutation._user = origConnection.getUser()
		supr(this, 'mutateItem', arguments)
	}

	this.createUser = function(inputEmail, inputPasswordHash, origConnection, callback) {
		var emailToIdKey = fan.keys.userEmailToId(inputEmail)
		this._redisClient.setnx(emailToIdKey, '__fan_tmp_holder', bind(this, function(err, wasCreated) {
			if (err) { throw logger.error('Could not create user email to id ', inputEmail, emailToIdKey, err) }
			if (!wasCreated) {
				callback(null, 'user with email exists')
				return
			}
			var userProps = { 'password_hash': inputPasswordHash, 'email': inputEmail, type: 'user' }
			logger.log("Create user with items", userProps)
			this.createItem(userProps, origConnection, bind(this, function(newItemId) {
				this._redisClient.set(emailToIdKey, newItemId, bind(this, function(err) {
					if (err) { throw logger.error('Could not update user email to id', emailToIdKey, newItemId, err) }
					callback(newItemId)
				}))
			}))
		}))
	}

	this.authenticate = function(inputEmail, inputPasswordHash, callback) {
		if (!inputEmail || !inputPasswordHash) { return callback(null, 'Please give us both email and password') }
		var userIdKey = fan.keys.userEmailToId(inputEmail)

		this._redisClient.get(userIdKey, bind(this, function(err, userIdBytes) {
			if (err) { throw logger.error('Could not retrieve id for key', userIdKey, err) }
			if (!userIdBytes) { return callback(null, 'We couldn\'t find that email in our db') }
			var userId = userIdBytes.toString()

			this.getItemProperty(userId, 'password_hash', bind(this, function(passwordHash, key) {
				var response = (passwordHash == JSON.stringify(inputPasswordHash)) ? userId : null
				callback(response, 'That\'s not the right password')
			}))
		}))
	}
})
<commit_msg>Update to the new fin API introduced in fin [master f183412]<commit_after>jsio('from shared.javascript import bind')
jsio('import server.Server')
jsio('import fan.sha1 as sha1')
jsio('import fan.keys')
jsio('import shared.keys')

exports = Class(server.Server, function(supr) {

	// Stamp all mutations with the user who originated it
	this.mutateItem = function(mutation, origConnection) {
		mutation._user = origConnection.getUser()
		supr(this, 'mutateItem', arguments)
	}

	this.createUser = function(inputEmail, inputPasswordHash, origConnection, callback) {
		var emailToIdKey = fan.keys.userEmailToId(inputEmail)
		this._redisClient.setnx(emailToIdKey, '__fan_tmp_holder', bind(this, function(err, wasCreated) {
			if (err) { throw logger.error('Could not create user email to id ', inputEmail, emailToIdKey, err) }
			if (!wasCreated) {
				callback(null, 'user with email exists')
				return
			}
			var userProps = { 'password_hash': inputPasswordHash, 'email': inputEmail, type: 'user' }
			logger.log("Create user with items", userProps)
			this.createItem(userProps, origConnection, bind(this, function(newItemId) {
				this._redisClient.set(emailToIdKey, newItemId, bind(this, function(err) {
					if (err) { throw logger.error('Could not update user email to id', emailToIdKey, newItemId, err) }
					callback(newItemId)
				}))
			}))
		}))
	}

	this.authenticate = function(inputEmail, inputPasswordHash, callback) {
		if (!inputEmail || !inputPasswordHash) { return callback(null, 'Please give us both email and password') }
		var userIdKey = fan.keys.userEmailToId(inputEmail)

		this._redisClient.get(userIdKey, bind(this, function(err, userIdBytes) {
			if (err) { throw logger.error('Could not retrieve id for key', userIdKey, err) }
			if (!userIdBytes) { return callback(null, 'We couldn\'t find that email in our db') }
			var userId = userIdBytes.toString(),
				key = shared.keys.getItemPropertyKey(userId, 'password_hash')

			this._retrieveBytes(key, bind(this, function(passwordHash, key) {
				var response = (passwordHash == JSON.stringify(inputPasswordHash)) ? userId : null
				callback(response, 'That\'s not the right password')
			}))
		}))
	}
})
<|endoftext|>