<commit_before>/**
    Framework for building object relational database apps
    Copyright (C) 2018  John Rogelstad

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/
/*jslint*/
(function () {
  "use strict";

  var workbook, workbookModel, workbookChild,
    workbookDefaultConifg, workbookLocalConfig,
    workbookList, models, feathers,
    f = require("common-core"),
    model = require("model"),
    dataSource = require("datasource"),
    catalog = require("catalog");

  workbook = {
    name: "Workbook",
    plural: "Workbooks",
    description: "System workbook definition",
    isSystem: true,
    properties: {
      name: {
        description: "Workbook name",
        type: "string"
      },
      description: {
        description: "Description",
        type: "string"
      },
      module: {
        description: "Module",
        type: "string"
      },
      launchConfig: {
        description: "Launch configuration",
        type: "object"
      },
      defaultConfig: {
        description: "Parent of \"parent\" on \"WorkbookDefaultConfig\"",
        type: "object"
      },
      localConfig: {
        description: "Parent of \"parent\" on \"WorkbookLocalConfig\"",
        type: "object"
      }
    }
  };

  workbookDefaultConifg = {
    description: "Workbook default sheet definition",
    isSystem: true,
    isChild: true,
    properties: {
      id: {
        description: "Unique identifier",
        type: "string",
        default: "createId"
      },
      parent: {
        description: "Workbook name",
        type: {
          relation: "Workbook",
          childOf: "defaultConfig"
        }
      },
      name: {
        description: "Sheet name",
        type: "string",
        isRequired: true
      },
      feather: {
        description: "Description",
        type: "string",
        isRequired: true
      },
      form: {
        description: "Form layout",
        type: {
          relation: "Form"
        }
      },
      list: {
        description: "List layout",
        type: "object"
      },
      zoom: {
        description: "Zoom level",
        type: "string",
        default: "100"
      },
      isEditModeEnabled: {
        description: "Flags whether inline editing is allowed",
        type: "boolean",
        default: true
      },
      actions: {
        description: "Menu actions that can be performed on rows",
        type: "object"
      }
    }
  };

  workbookList = {
    description: "Workbook list definition",
    isSystem: true,
    isChild: true,
    properties: {
      columns: {
        description: "Columns",
        type: "object"
      },
      filter: {
        description: "Filter",
        type: "object"
      }
    }
  };

  workbookLocalConfig = f.copy(workbookDefaultConifg);
  workbookLocalConfig.description = "Workbook local sheet definition";
  workbookLocalConfig.properties.parent.type.childOf = "localConfig";
  workbookLocalConfig.properties.list = {
    description: "Parent of \"parent\" on \"WorkbookList\"",
    type: {relation: "WorkbookList"}
  };

  feathers = catalog.store().feathers();
  feathers.Workbook = workbook;
  feathers.WorkbookDefaultConfig = workbookDefaultConifg;
  feathers.WorkbookLocalConfig = workbookLocalConfig;
  feathers.WorkbookList = workbookList;

  var resolveConfig = function (config) {
    config.forEach(function(sheet){
      if (!sheet.id) { sheet.id = f.createId(); }
      if (typeof sheet.form === "string" && sheet.form.length) {
        sheet.form = catalog.store().forms()[sheet.form];
      }
    });
  };

  /**
    Model with special rest API handling for Workbook saves.
    @param {Object} Default data
    return {Object}
  */
  workbookModel = function (data) {
    var that, state, substate, doPut;

    // ..........................................................
    // PUBLIC
    //

    data = data || {};
    if (data.localConfig) { resolveConfig(data.localConfig); }
    if (data.defaultConfig) { resolveConfig(data.defaultConfig); }
    that = model(data, workbook);
    that.idProperty("name");

    that.path = function (name, id) {
      var ret = "/" + name.toSpinalCase();
      if (id) { ret += "/" + id; }
      return ret;
    };

    that.getConfig = function () {
      var d = that.data,
        config = d.defaultConfig();
      if (d.localConfig().length) {
        config = d.localConfig();
      }
      return config;
    };

    // ..........................................................
    // PRIVATE
    //

    doPut = function (context) {
      var cache = that.toJSON(),
        payload = {method: "PUT", path: that.path(that.name, that.data.name()),
          data: cache},
        callback = function (result) {
          if (result) {
            state.send('fetched');
            context.promise.resolve(that.data);
          }
        };

      if (that.isValid()) {
        dataSource.request(payload).then(callback);
      }
    };

    // Update statechart for modified behavior
    state = that.state();
    substate = state.resolve("/Busy/Saving");
    delete substate.substateMap.Posting;
    delete substate.substateMap.Patching;
    substate.substates.length = 0;
    substate.enter(doPut);
    substate = state.resolve("/Ready/Fetched/Dirty");
    substate.event("save", function (promise) {
      substate.goto("/Busy/Saving", {
        context: {promise: promise}
      });
    });

    return that;
  };

  /**
    Workbook configuration model.

    @param {Object} Default data
    return {Object}
  */
  workbookChild = function (data) {
    var that = model(data, workbookLocalConfig);

    that.onChanged("feather", function (property) {
      var id, forms, keys, invalid, feather,
        value = property.newValue(),
        list = that.data.list(),
        columns = list.data.columns(),
        filter = list.data.filter(),
        sort = filter ? filter.sort : false,
        criteria = filter ? filter.criteria : false;

      if (value) {
        // When feather changes, automatically assign
        // the first available form.
        forms = catalog.store().forms();
        keys = Object.keys(forms).sort(function (a, b) {
          if (forms[a].name < forms[b].name) { return -1; }
          return 1;
        });
        id = keys.find(function (key) {
          return value === forms[key].feather;
        });

        // Remove mismatched columns
        feather = catalog.getFeather(value);
        invalid = columns.filter(function (column) {
          return !feather.properties[column.attr];
        });
        invalid.forEach(function (item) {
          var idx = columns.indexOf(item);
          columns.splice(idx, 1);
        });

        // Remove mismatched sort
        if (sort) {
          invalid = sort.filter(function (item) {
            return !feather.properties[item.property];
          });
          invalid.forEach(function (item) {
            var idx = sort.indexOf(item);
            sort.splice(idx, 1);
          });
        }

        // Remove mismatched criteria
        if (criteria) {
          invalid = criteria.filter(function (item) {
            return !feather.properties[item.property];
          });
          invalid.forEach(function (item) {
            var idx = criteria.indexOf(item);
            criteria.splice(idx, 1);
          });
        }
      } else {
        columns.length = 0;
        Object.keys(filter).forEach(function (key) {
          delete filter[key];
        });
      }

      that.data.form(forms[id]);
    });

    that.onValidate(function () {
      var list = that.data.list();

      if (!list.data.columns().length) {
        throw "List must include at least one column.";
      }
    });

    return that;
  };

  models = catalog.store().models();
  models.workbook = workbookModel;
  models.workbookLocalConfig = workbookChild;
  module.exports = workbookModel;

}());
<commit_msg>Update workbook.js<commit_after>/**
    Framework for building object relational database apps
    Copyright (C) 2018  John Rogelstad

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/
/*global require, module*/
/*jslint*/
(function () {
    "use strict";

    var workbook, workbookModel, workbookChild,
            workbookDefaultConifg, workbookLocalConfig,
            workbookList, models, feathers,
            f = require("common-core"),
            model = require("model"),
            dataSource = require("datasource"),
            catalog = require("catalog");

    workbook = {
        name: "Workbook",
        plural: "Workbooks",
        description: "System workbook definition",
        isSystem: true,
        properties: {
            name: {
                description: "Workbook name",
                type: "string"
            },
            description: {
                description: "Description",
                type: "string"
            },
            module: {
                description: "Module",
                type: "string"
            },
            launchConfig: {
                description: "Launch configuration",
                type: "object"
            },
            defaultConfig: {
                description: "Parent of \"parent\" on \"WorkbookDefaultConfig\"",
                type: "object"
            },
            localConfig: {
                description: "Parent of \"parent\" on \"WorkbookLocalConfig\"",
                type: "object"
            }
        }
    };

    workbookDefaultConifg = {
        description: "Workbook default sheet definition",
        isSystem: true,
        isChild: true,
        properties: {
            id: {
                description: "Unique identifier",
                type: "string",
                default: "createId"
            },
            parent: {
                description: "Workbook name",
                type: {
                    relation: "Workbook",
                    childOf: "defaultConfig"
                }
            },
            name: {
                description: "Sheet name",
                type: "string",
                isRequired: true
            },
            feather: {
                description: "Description",
                type: "string",
                isRequired: true
            },
            form: {
                description: "Form layout",
                type: {
                    relation: "Form"
                }
            },
            list: {
                description: "List layout",
                type: "object"
            },
            zoom: {
                description: "Zoom level",
                type: "string",
                default: "100"
            },
            isEditModeEnabled: {
                description: "Flags whether inline editing is allowed",
                type: "boolean",
                default: true
            },
            actions: {
                description: "Menu actions that can be performed on rows",
                type: "object"
            }
        }
    };

    workbookList = {
        description: "Workbook list definition",
        isSystem: true,
        isChild: true,
        properties: {
            columns: {
                description: "Columns",
                type: "object"
            },
            filter: {
                description: "Filter",
                type: "object"
            }
        }
    };

    workbookLocalConfig = f.copy(workbookDefaultConifg);
    workbookLocalConfig.description = "Workbook local sheet definition";
    workbookLocalConfig.properties.parent.type.childOf = "localConfig";
    workbookLocalConfig.properties.list = {
        description: "Parent of \"parent\" on \"WorkbookList\"",
        type: {
            relation: "WorkbookList"
        }
    };

    feathers = catalog.store().feathers();
    feathers.Workbook = workbook;
    feathers.WorkbookDefaultConfig = workbookDefaultConifg;
    feathers.WorkbookLocalConfig = workbookLocalConfig;
    feathers.WorkbookList = workbookList;

    var resolveConfig = function (config) {
        config.forEach(function (sheet) {
            if (!sheet.id) {
                sheet.id = f.createId();
            }
            if (typeof sheet.form === "string" && sheet.form.length) {
                sheet.form = catalog.store().forms()[sheet.form];
            }
        });
    };

    /**
      Model with special rest API handling for Workbook saves.
      @param {Object} Default data
      return {Object}
    */
    workbookModel = function (data) {
        var that, state, substate, doPut;

        // ..........................................................
        // PUBLIC
        //

        data = data || {};
        if (data.localConfig) {
            resolveConfig(data.localConfig);
        }
        if (data.defaultConfig) {
            resolveConfig(data.defaultConfig);
        }
        that = model(data, workbook);
        that.idProperty("name");

        that.path = function (name, id) {
            var ret = "/" + name.toSpinalCase();
            if (id) {
                ret += "/" + id;
            }
            return ret;
        };

        that.getConfig = function () {
            var d = that.data,
                config = d.defaultConfig();
            if (d.localConfig().length) {
                config = d.localConfig();
            }
            return config;
        };

        // ..........................................................
        // PRIVATE
        //

        doPut = function (context) {
            var cache = that.toJSON(),
                payload = {
                    method: "PUT",
                    path: that.path(that.name, that.data.name()),
                    data: cache
                },
                callback = function (result) {
                    if (result) {
                        state.send('fetched');
                        context.promise.resolve(that.data);
                    }
                };

            if (that.isValid()) {
                dataSource.request(payload).then(callback);
            }
        };

        // Update statechart for modified behavior
        state = that.state();
        substate = state.resolve("/Busy/Saving");
        delete substate.substateMap.Posting;
        delete substate.substateMap.Patching;
        substate.substates.length = 0;
        substate.enter(doPut);
        substate = state.resolve("/Ready/Fetched/Dirty");
        substate.event("save", function (promise) {
            substate.goto("/Busy/Saving", {
                context: {
                    promise: promise
                }
            });
        });

        return that;
    };

    /**
      Workbook configuration model.

      @param {Object} Default data
      return {Object}
    */
    workbookChild = function (data) {
        var that = model(data, workbookLocalConfig);

        that.onChanged("feather", function (property) {
            var id, forms, keys, invalid, feather,
                    value = property.newValue(),
                    list = that.data.list(),
                    columns = list.data.columns(),
                    filter = list.data.filter(),
                    sort = filter
                ? filter.sort
                : false,
                    criteria = filter
                ? filter.criteria
                : false;

            if (value) {
                // When feather changes, automatically assign
                // the first available form.
                forms = catalog.store().forms();
                keys = Object.keys(forms).sort(function (a, b) {
                    if (forms[a].name < forms[b].name) {
                        return -1;
                    }
                    return 1;
                });
                id = keys.find(function (key) {
                    return value === forms[key].feather;
                });

                // Remove mismatched columns
                feather = catalog.getFeather(value);
                invalid = columns.filter(function (column) {
                    return !feather.properties[column.attr];
                });
                invalid.forEach(function (item) {
                    var idx = columns.indexOf(item);
                    columns.splice(idx, 1);
                });

                // Remove mismatched sort
                if (sort) {
                    invalid = sort.filter(function (item) {
                        return !feather.properties[item.property];
                    });
                    invalid.forEach(function (item) {
                        var idx = sort.indexOf(item);
                        sort.splice(idx, 1);
                    });
                }

                // Remove mismatched criteria
                if (criteria) {
                    invalid = criteria.filter(function (item) {
                        return !feather.properties[item.property];
                    });
                    invalid.forEach(function (item) {
                        var idx = criteria.indexOf(item);
                        criteria.splice(idx, 1);
                    });
                }
            } else {
                columns.length = 0;
                Object.keys(filter).forEach(function (key) {
                    delete filter[key];
                });
            }

            that.data.form(forms[id]);
        });

        that.onValidate(function () {
            var list = that.data.list();

            if (!list.data.columns().length) {
                throw "List must include at least one column.";
            }
        });

        return that;
    };

    models = catalog.store().models();
    models.workbook = workbookModel;
    models.workbookLocalConfig = workbookChild;
    module.exports = workbookModel;

}());<|endoftext|>


<commit_before>// Copyright (c) 2012-2017, Najjar Chedy
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

define(function (require) {
    "use strict";

    var $ = require('jquery');
    var vis = require('vis');
    var _ = require('underscore');
    require('asm-mode');
    require('selectize');

    function Cfg(hub, container, state) {
        this.container = container;
        this.eventHub = hub.createEventHub();
        this.domRoot = container.getElement();
        this.domRoot.html($('#cfg').html());
        this.functions = state.cfgResult;
        this.defaultCfgOuput = {nodes: [{id: 0, label: 'No Output'}], edges: []};
        this.fnNames = this.functions ? Object.keys(this.functions) : [];
        this.currentFunc = this.fnNames.length ? this.fnNames[0] : "";

        this.networkOpts = {
            autoResize: true,
            locale: 'en',
            edges: {
                arrows: {to: {enabled: true}},
                smooth: {enabled: true},
                physics: false
            },
            nodes: {
                font: {'face': 'monospace', 'align': 'left'}
            },
            layout: {
                improvedLayout: true,
                hierarchical: {
                    enabled: true,
                    sortMethod: "directed",
                    direction: "LR", // LR means Upside/down for some reason!
                    nodeSpacing: 100,
                    levelSeparation: 100
                }
            },
            physics: {
                hierarchicalRepulsion: {
                    nodeDistance: 300
                }
            },
            interaction: {
                navigationButtons: false,
                keyboard: {
                    enabled: true,
                    speed: {x: 10, y: 10, zoom: 0.03},
                    bindToWindow: false
                }
            }
        };

        this.cfgVisualiser = new vis.Network(this.domRoot.find(".graph-placeholder")[0],
            this.defaultCfgOuput, this.networkOpts);
        this.restButton = this.domRoot.find(".show-hide-btn")
            .on('click', _.bind(function () {
                this.networkOpts.interaction.navigationButtons = !this.networkOpts.interaction.navigationButtons;
                this.cfgVisualiser.setOptions(this.networkOpts);
            }, this));

        this._compilerid = state.id;
        this._compilerName = state.compilerName;
        this._editorid = state.editorid;

        this.eventHub.on('compileResult', this.onCompileResult, this);
        this.eventHub.on('compiler', this.onCompiler, this);
        this.eventHub.emit('cfgViewOpened', this._compilerid);
        this.container.on('destroy', function () {
            this.eventHub.emit("cfgViewClosed", this._compilerid, this.cfgVisualiser);
            this.eventHub.unsubscribe();
        }, this);

        container.on('resize', this.resize, this);
        container.on('shown', this.resize, this);

        this.adaptStructure = function (names) {
            var options = [];

            for (var i = 0; i < names.length; ++i) {
                options.push({name: names[i]});
            }
            return options;
        };

        this.select = this.domRoot.find(".function-picker").selectize({
            sortField: 'name',
            valueField: 'name',
            labelField: 'name',
            searchField: ['name'],
            options: this.fnNames.length ? this.adaptStructure(this.fnNames) : [{name: "The input does not contain any function"}],
            items: this.fnNames.length ? [this.currentFunc] : ["Please select a function"]
        }).on('change', _.bind(function (event) {
            this.onFunctionChange(this.functions, event.target.value);
        }, this));

        this.setTitle();
    }

    Cfg.prototype.onCompileResult = function (id, compiler, result) {
        if (this._compilerid === id) {
            if (result.supportsCfg && !$.isEmptyObject(result.cfg)) {
                this.functions = result.cfg;
                this.fnNames = Object.keys(this.functions);
                if (this.fnNames.indexOf(this.currentFunc) === -1)
                    this.currentFunc = this.fnNames[0];
                this.showCfgResults({
                    'nodes': this.functions[this.currentFunc].nodes,
                    'edges': this.functions[this.currentFunc].edges
                });
                this.cfgVisualiser.selectNodes([this.functions[this.currentFunc].nodes[0].id]);
            } else {
                this.showCfgResults(this.defaultCfgOuput);
                this.currentFunc = "";
                this.fnNames = [];
            }

            this.select[0].selectize.destroy();
            this.select = this.domRoot.find(".function-picker").selectize({
                sortField: 'name',
                valueField: 'name',
                labelField: 'name',
                searchField: ['name'],
                options: this.fnNames.length ? this.adaptStructure(this.fnNames) : [{name: "The input does not contain any function"}],
                items: this.fnNames.length ? [this.currentFunc] : ["Please select a function"]
            }).on('change', _.bind(function (event) {
                this.onFunctionChange(this.functions, event.target.value);
            }, this));
        }
    };

    Cfg.prototype.setTitle = function () {
        this.container.setTitle(this._compilerName + " Graph Viewer (Editor #" + this._editorid + ", Compiler #" + this._compilerid + ")");
    };

    Cfg.prototype.showCfgResults = function (data) {
        this.cfgVisualiser.setData(data);
    };

    Cfg.prototype.onCompiler = function (id, compiler, options, editorid) {
        if (id === this._compilerid) {
            this._compilerName = compiler.name;
            this._editorid = editorid;
            this.setTitle();
        }
    };

    Cfg.prototype.onFunctionChange = function (functions, name) {
        if (functions[name]) {
            this.currentFunc = name;
            this.showCfgResults({
                'nodes': functions[name].nodes,
                'edges': functions[name].edges
            });
            this.cfgVisualiser.selectNodes([functions[name].nodes[0].id]);
        }
    };

    Cfg.prototype.resize = function () {
        var height = this.domRoot.height() - this.domRoot.find(".top-bar").outerHeight(true);
        this.cfgVisualiser.setSize('100%', height.toString());
        this.cfgVisualiser.redraw();
    };

    return {
        Cfg: Cfg
    };
});

<commit_msg>Trivial typo fix<commit_after>// Copyright (c) 2012-2017, Najjar Chedy
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

define(function (require) {
    "use strict";

    var $ = require('jquery');
    var vis = require('vis');
    var _ = require('underscore');
    require('asm-mode');
    require('selectize');

    function Cfg(hub, container, state) {
        this.container = container;
        this.eventHub = hub.createEventHub();
        this.domRoot = container.getElement();
        this.domRoot.html($('#cfg').html());
        this.functions = state.cfgResult;
        this.defaultCfgOutput = {nodes: [{id: 0, label: 'No Output'}], edges: []};
        this.fnNames = this.functions ? Object.keys(this.functions) : [];
        this.currentFunc = this.fnNames.length ? this.fnNames[0] : "";

        this.networkOpts = {
            autoResize: true,
            locale: 'en',
            edges: {
                arrows: {to: {enabled: true}},
                smooth: {enabled: true},
                physics: false
            },
            nodes: {
                font: {'face': 'monospace', 'align': 'left'}
            },
            layout: {
                improvedLayout: true,
                hierarchical: {
                    enabled: true,
                    sortMethod: "directed",
                    direction: "LR", // LR means Upside/down for some reason!
                    nodeSpacing: 100,
                    levelSeparation: 100
                }
            },
            physics: {
                hierarchicalRepulsion: {
                    nodeDistance: 300
                }
            },
            interaction: {
                navigationButtons: false,
                keyboard: {
                    enabled: true,
                    speed: {x: 10, y: 10, zoom: 0.03},
                    bindToWindow: false
                }
            }
        };

        this.cfgVisualiser = new vis.Network(this.domRoot.find(".graph-placeholder")[0],
            this.defaultCfgOutput, this.networkOpts);
        this.restButton = this.domRoot.find(".show-hide-btn")
            .on('click', _.bind(function () {
                this.networkOpts.interaction.navigationButtons = !this.networkOpts.interaction.navigationButtons;
                this.cfgVisualiser.setOptions(this.networkOpts);
            }, this));

        this._compilerid = state.id;
        this._compilerName = state.compilerName;
        this._editorid = state.editorid;

        this.eventHub.on('compileResult', this.onCompileResult, this);
        this.eventHub.on('compiler', this.onCompiler, this);
        this.eventHub.emit('cfgViewOpened', this._compilerid);
        this.container.on('destroy', function () {
            this.eventHub.emit("cfgViewClosed", this._compilerid, this.cfgVisualiser);
            this.eventHub.unsubscribe();
        }, this);

        container.on('resize', this.resize, this);
        container.on('shown', this.resize, this);

        this.adaptStructure = function (names) {
            var options = [];

            for (var i = 0; i < names.length; ++i) {
                options.push({name: names[i]});
            }
            return options;
        };

        this.select = this.domRoot.find(".function-picker").selectize({
            sortField: 'name',
            valueField: 'name',
            labelField: 'name',
            searchField: ['name'],
            options: this.fnNames.length ? this.adaptStructure(this.fnNames) : [{name: "The input does not contain any function"}],
            items: this.fnNames.length ? [this.currentFunc] : ["Please select a function"]
        }).on('change', _.bind(function (event) {
            this.onFunctionChange(this.functions, event.target.value);
        }, this));

        this.setTitle();
    }

    Cfg.prototype.onCompileResult = function (id, compiler, result) {
        if (this._compilerid === id) {
            if (result.supportsCfg && !$.isEmptyObject(result.cfg)) {
                this.functions = result.cfg;
                this.fnNames = Object.keys(this.functions);
                if (this.fnNames.indexOf(this.currentFunc) === -1)
                    this.currentFunc = this.fnNames[0];
                this.showCfgResults({
                    'nodes': this.functions[this.currentFunc].nodes,
                    'edges': this.functions[this.currentFunc].edges
                });
                this.cfgVisualiser.selectNodes([this.functions[this.currentFunc].nodes[0].id]);
            } else {
                this.showCfgResults(this.defaultCfgOutput);
                this.currentFunc = "";
                this.fnNames = [];
            }

            this.select[0].selectize.destroy();
            this.select = this.domRoot.find(".function-picker").selectize({
                sortField: 'name',
                valueField: 'name',
                labelField: 'name',
                searchField: ['name'],
                options: this.fnNames.length ? this.adaptStructure(this.fnNames) : [{name: "The input does not contain any function"}],
                items: this.fnNames.length ? [this.currentFunc] : ["Please select a function"]
            }).on('change', _.bind(function (event) {
                this.onFunctionChange(this.functions, event.target.value);
            }, this));
        }
    };

    Cfg.prototype.setTitle = function () {
        this.container.setTitle(this._compilerName + " Graph Viewer (Editor #" + this._editorid + ", Compiler #" + this._compilerid + ")");
    };

    Cfg.prototype.showCfgResults = function (data) {
        this.cfgVisualiser.setData(data);
    };

    Cfg.prototype.onCompiler = function (id, compiler, options, editorid) {
        if (id === this._compilerid) {
            this._compilerName = compiler.name;
            this._editorid = editorid;
            this.setTitle();
        }
    };

    Cfg.prototype.onFunctionChange = function (functions, name) {
        if (functions[name]) {
            this.currentFunc = name;
            this.showCfgResults({
                'nodes': functions[name].nodes,
                'edges': functions[name].edges
            });
            this.cfgVisualiser.selectNodes([functions[name].nodes[0].id]);
        }
    };

    Cfg.prototype.resize = function () {
        var height = this.domRoot.height() - this.domRoot.find(".top-bar").outerHeight(true);
        this.cfgVisualiser.setSize('100%', height.toString());
        this.cfgVisualiser.redraw();
    };

    return {
        Cfg: Cfg
    };
});

<|endoftext|>


<commit_before>/** @jsx m */

"use strict";
require("./AboutPage.scss");

var _ = require("underscore");
var Layout = require("../layouts/FullLayout.js");
var OnUnload = require("../utils/OnUnload.js");

var AboutPage = {};

AboutPage.controller = function(options) {
  OnUnload(this);
  options = _.extend({id: "AboutPage"}, options);
  this.controllers.layout = new Layout.controller(options);
};

AboutPage.view = function(ctrl) {
  var content = (

About

        Replicability is a cornerstone of science, but evidence of independent replications
        is currently disorganized, making it difficult to gauge the reliability of empirical
        findings. Independent verification of data and analyses is another hallmark of science,
        yet is currently challenging in practice because data/syntax are difficult to track down.

        Curate Science aims to solve both of these problems by providing an online platform that
        substantially facilitates these two crucial processes of science. Independent replication
        information and available data/syntax files will automatically be aggregated from pre-existing
        sources (e.g., from PsychFileDrawer.org, Figshare.com). Registered users will be able to add,
        modify, and update such information, including in-line commenting directed at specific elements
        of an article and in-browser analyses for articles with available R syntax files.

        Our vision is that building such a platform will accelerate the growth of cumulative knowledge
        and innovation by facilitating and incentivizing independent replications and verification,
        but also by facilitating the post-publication critique, evaluation, extension, re-analysis,
        and interpretation of findings (see Features, for a flowchart of our core features).

  );

  return new Layout.view(ctrl.controllers.layout, content);
};

module.exports = AboutPage;
<commit_msg>Update AboutPage.js<commit_after>/** @jsx m */

"use strict";
require("./AboutPage.scss");

var _ = require("underscore");
var Layout = require("../layouts/FullLayout.js");
var OnUnload = require("../utils/OnUnload.js");

var AboutPage = {};

AboutPage.controller = function(options) {
  OnUnload(this);
  options = _.extend({id: "AboutPage"}, options);
  this.controllers.layout = new Layout.controller(options);
};

AboutPage.view = function(ctrl) {
  var content = (

About

        Independent verification is the cornerstone of science, however, in practice, the independent verification of published findings is difficult and not rewarded. Hence, gauging the reliability and validity of published scientific findings is typically very difficult (if not impossible). Curate Science is a web application that aims to help in these regards by facilitating and incentivizing the independent verification of published scientific findings in several respects.

        Independent verification is facilitated by enabling researchers to (1) link independent replications to original studies (and eventually linking conceptual replication studies meta-analytically), (2) curate available data/syntax to verify reproducibility of results within the browser, and (3) critically evaluate the interpretation/validity of findings via in-line comments (i.e., post-publication peer review on stereoids given evaluation done in the context of available data and replicability information).

        Curate Science will incentivize independent verififation by (1) prominently displaying recent user contributions on the homepage to reward researchers and (2) offering unique high-utility features that motivate users to regularly use and engage with site content (e.g., notifications of new replications, new activity on articles a user has contributed to, and discovery of new related articles). Furthermore, knowing that other researchers can benefit from one's independent verification activities acts as an incentive to actually engage in those activities. For example, a researcher is more likely to verify the reproducibility of a study's results if they know other researchers' may benefit from those activities (e.g., researchers wanting to re-analyze a study's data from a different theoretical perspective can greatly benefit from a researcher who curated a study's data files to verify reproducibility). See Features, for a flowchart of our core features.

  );

  return new Layout.view(ctrl.controllers.layout, content);
};

module.exports = AboutPage;
<|endoftext|>


<commit_before><commit_msg>fix: #60, remove global translations<commit_after><|endoftext|>


<commit_before>var _plan={
    title:"simple plan",
    template_engine:"go",
    dependency:[
        "markdown",
        "yaml_front_matter",
    ],
    strategies:[
        {
            title:"markdown",
            patterns:["*md"],
            exec:["markdown"],
        },
    ]
};

Wu.setCustomPlan(_plan);
<commit_msg>gen: Fix typo on object field<commit_after>var _plan={
    title:"simple plan",
    template_engine:"go",
    dependencies:[
        "markdown",
    ],
    strategies:[
        {
            title:"markdown",
            patterns:["*md"],
            exec:["markdown"],
        },
    ]
};

Wu.setCustomPlan(_plan);
<|endoftext|>


<commit_before>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Control panel around a content node.
 * Dynamically adjusts its size to fit its contents.
 *
 * @author Sam Reid
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );

  /**
   * @param {Node} content
   * @param {object} options
   * @constructor
   */
  function Panel( content, options ) {

    var thisNode = this;

    // default options
    options = _.extend( {
      fill: 'white',
      stroke: 'black',
      lineWidth: 1, // width of the background border
      xMargin: 5,
      yMargin: 5,
      cornerRadius: 10, // radius of the rounded corners on the background
      resize: true, // dynamically resize when content bounds change
      backgroundPickable: false
    }, options );

    Node.call( thisNode );

    // correct size will be set by updateBackground
    var background = new Rectangle( 0, 0, 1, 1, {stroke: options.stroke, lineWidth: options.lineWidth, fill: options.fill, pickable: options.backgroundPickable, lineDash: options.lineDash} );
    this.background = background;
    this.addChild( background );
    this.addChild( content );

    // Adjust the background size to match the content.
    var updateBackground = function() {
      background.setRect( 0, 0, content.width + ( 2 * options.xMargin ), content.height + ( 2 * options.yMargin ), options.cornerRadius, options.cornerRadius );

      // Prevent oscillation and stack overflow due to numerical imprecision, see https://github.com/phetsims/sun/issues/110
      if ( background.center.distanceSquared( content.center ) > 1E-6 ) {
        content.center = background.center;
      }
    };
    if ( options.resize ) {
      content.addEventListener( 'bounds', function() {
        updateBackground();
      } );
    }
    updateBackground();

    // Apply options after the layout is done, so that options that use the bounds will work properly.
    this.mutate( options );
  }

  inherit( Node, Panel, {

    //Setters for the background rectangle stroke
    set stroke( s ) { this.background.stroke = s; },

    //Getter for the background rectangle stroke
    get stroke() {return this.background.stroke;}
  } );

  return Panel;
} );<commit_msg>Add port of EmissionRateControlSliderNode<commit_after> // Copyright 2002-2013, University of Colorado Boulder

/**
 * Control panel around a content node.
 * Dynamically adjusts its size to fit its contents.
 *
 * @author Sam Reid
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );

  /**
   * @param {Node} content
   * @param {object} options
   * @constructor
   */
  function Panel( content, options ) {

    var thisNode = this;

    // default options
    options = _.extend( {
      fill: 'white',
      stroke: 'black',
      lineWidth: 1, // width of the background border
      xMargin: 5,
      yMargin: 5,
      cornerRadius: 10, // radius of the rounded corners on the background
      resize: true, // dynamically resize when content bounds change
      backgroundPickable: false
    }, options );

    Node.call( thisNode );

    // correct size will be set by updateBackground
    var background = new Rectangle( 0, 0, 1, 1, {stroke: options.stroke, lineWidth: options.lineWidth, fill: options.fill, pickable: options.backgroundPickable, lineDash: options.lineDash} );
    this.background = background;
    this.addChild( background );
    this.addChild( content );

    // Adjust the background size to match the content.
    var updateBackground = function() {
      background.setRect( 0, 0, content.width + ( 2 * options.xMargin ), content.height + ( 2 * options.yMargin ), options.cornerRadius, options.cornerRadius );

      // Prevent oscillation and stack overflow due to numerical imprecision, see https://github.com/phetsims/sun/issues/110
      if ( background.center.distanceSquared( content.center ) > 1E-6 ) {
        content.center = background.center;
      }
    };
    if ( options.resize ) {
      content.addEventListener( 'bounds', function() {
        updateBackground();
      } );
    }
    updateBackground();

    // Apply options after the layout is done, so that options that use the bounds will work properly.
    this.mutate( options );
  }

  inherit( Node, Panel, {

    //Setters for the background rectangle stroke
    set stroke( s ) { this.background.stroke = s; },

    //Getter for the background rectangle stroke
    get stroke() {return this.background.stroke;}
  } );

  return Panel;
} );<|endoftext|>


<commit_before>
const RG = require('./rg');

RG.Factory = require('./factory');
RG.Factory.Battle = require('./factory.battle');

/* GameMaster objects reacts to various events caused by player and other
 * actors, and shapes the game world based on them. For example,
 * GameMaster can:
 *   - start battles on the area player entered
 *   - spawn special events and actors
 *   - spawn special items etc.
 */
const GameMaster = function(pool, game) {
    this.eventPool = pool;
    this.player = null;
    this.game = game;
    this.fact = new RG.Factory.Battle(game);

    // Lookup table for battles by level ID
    this.battles = {};

    this.setPlayer = player => {
        this.player = player;
    };
    this.setWorld = world => {this.world = world;};

    this.hasNotify = true;
    this.notify = (evtName, args) => {
        if (evtName === RG.EVT_LEVEL_CHANGED) {
            console.log('GameMaster EVT_LEVEL_CHANGED triggered');
            const {actor, target, src} = args;
            if (actor.isPlayer()) {
                const srcID = src.getID();
                if (this.battles.hasOwnProperty(srcID)) {
                    const battleLevel = this.battles.getLevel().getID();
                    if (battleLevel.getID() === target.getID()) {
                        // Entered a battle
                        console.log('Player entered battle. Getting sel obj');
                        actor.add(new RG.Component.InBattle());
                        // Get army selection object
                        const obj = this.getSelectionObject(actor, this.battles[srcID]);
                        actor.getBrain().setSelectionObject(obj);
                    }
                }
            }
        }
        else if (evtName === RG.EVT_TILE_CHANGED) {
            console.log('EVT_TILE_CHANGED triggered');
            // Should spawn battle etc event
            if (!this.player) {
                console.log('\tBut player is NULL for the moment');
                return;
            }
            console.log('\tPlayer not null. Creating battle');
            const level = this.player.getLevel();
            const id = level.getID();
            if (!this.battles.hasOwnProperty(id)) {
                this.battles[id] = this.fact.createBattle(level);
                this.game.addBattle(this.battles[id]);
            }
        }
        else if (evtName === RG.EVT_BATTLE_OVER) {
            const {battle} = args;
            if (battle) {
                this.addBadgesForActors(battle);
                this.moveActorsOutOfBattle(battle);
            }
            else {
                const json = JSON.stringify(args);
                RG.err('Game.Master', 'notify',
                    `Args ${json} does not contain "battle"`);
            }
            console.log('GameMaster registered battle over');
            RG.gameMsg('Battle is over!');
            // TODO delete the battle (but keep the level)
        }
    };
    RG.POOL.listenEvent(RG.EVT_LEVEL_CHANGED, this);
    RG.POOL.listenEvent(RG.EVT_TILE_CHANGED, this);
    RG.POOL.listenEvent(RG.EVT_BATTLE_OVER, this);

    /* Adds BattleBadges after a battle is over. */
    this.addBadgesForActors = battle => {
        const armies = battle.getArmies();
        armies.forEach(army => {
            const actors = army.getActors();
            const ids = actors.map(actor => actor.getID());

            actors.forEach(actor => {
                const badge = new RG.Component.BattleBadge();
                if (army.isDefeated()) {
                    badge.setStatus('Defeated');
                }
                else {
                    badge.setStatus('Won');
                }
                const battleData = {
                    name: battle.getName(),
                    allies: ids
                };
                badge.setData(battleData);
                actor.add(badge);

                let name = actor.getName();
                name = `Battle-tested ${name}`;
                actor.setName(name);
            });
        });
    };

    /* Moves actors out of the battle level into the parent level of the battle
     * (at the moment this is always Area.Tile level. */
    this.moveActorsOutOfBattle = battle => {
        const level = battle.getLevel();
        const conns = level.getConnections();

        if (!conns || conns.length === 0) {
            RG.err('Game.Master', 'moveActorsOutOfBattle',
                'No exit connnection in level');
        }

        const exit = conns[0];
        const targetLevel = exit.getTargetLevel();

        const armies = battle.getArmies();
        armies.forEach(army => {
            const actors = army.getActors();
            actors.forEach(actor => {
                if (level.removeActor(actor)) {
                    targetLevel.addActorToFreeCell(actor);
                }
                else {
                    const json = JSON.stringify(actor.toJSON());
                    RG.err('Game.Master', 'moveActorsOutOfBattle',
                        `removeActor failed for actor ${json}`);
                }
            });
        });

    };

    /* Returns the selection object for player to select an army. */
    this.getSelectionObject = function(player, battle) {
        return {
            showMenu: () => true,
            getMenu: () => {
                RG.gameMsg('Please select an army to join:');
                const armies = battle.getArmies();
                const menuObj = {};
                armies.forEach((army, i) => {
                    menuObj[i] = ' Army ' + army.getName();
                });
                menuObj['Any other key'] = 'Take no side';
                return menuObj;
            },
            select: code => {
                const selection = RG.codeToIndex(code);
                const armies = battle.getArmies();
                if (selection < armies.length) {
                    return () => {
                        armies[selection].addActor(player);
                    };
                }
                return null;
            }
        };
    };

    /* Serializes the object into JSON. */
    this.toJSON = function() {
        const keys = Object.keys(this.battles);
        const battles = {};
        keys.forEach(id => {
            battles[id] = this.battles[id].toJSON();
        });
        return {
            battles
        };
    };
};

module.exports = GameMaster;
<commit_msg>Added missing index to this.battles.<commit_after>
const RG = require('./rg');

RG.Factory = require('./factory');
RG.Factory.Battle = require('./factory.battle');

/* GameMaster objects reacts to various events caused by player and other
 * actors, and shapes the game world based on them. For example,
 * GameMaster can:
 *   - start battles on the area player entered
 *   - spawn special events and actors
 *   - spawn special items etc.
 */
const GameMaster = function(pool, game) {
    this.eventPool = pool;
    this.player = null;
    this.game = game;
    this.fact = new RG.Factory.Battle(game);

    // Lookup table for battles by level ID
    this.battles = {};

    this.setPlayer = player => {
        this.player = player;
    };
    this.setWorld = world => {this.world = world;};

    this.hasNotify = true;
    this.notify = (evtName, args) => {
        if (evtName === RG.EVT_LEVEL_CHANGED) {
            console.log('GameMaster EVT_LEVEL_CHANGED triggered');
            const {actor, target, src} = args;
            if (actor.isPlayer()) {
                const srcID = src.getID();
                if (this.battles.hasOwnProperty(srcID)) {
                    const battleLevel = this.battles[srcID].getLevel();
                    if (battleLevel.getID() === target.getID()) {
                        // Entered a battle
                        console.log('Player entered battle. Getting sel obj');
                        actor.add(new RG.Component.InBattle());
                        // Get army selection object
                        const obj = this.getSelectionObject(actor, this.battles[srcID]);
                        actor.getBrain().setSelectionObject(obj);
                    }
                }
            }
        }
        else if (evtName === RG.EVT_TILE_CHANGED) {
            console.log('EVT_TILE_CHANGED triggered');
            // Should spawn battle etc event
            if (!this.player) {
                console.log('\tBut player is NULL for the moment');
                return;
            }
            console.log('\tPlayer not null. Creating battle');
            const level = this.player.getLevel();
            const id = level.getID();
            if (!this.battles.hasOwnProperty(id)) {
                this.battles[id] = this.fact.createBattle(level);
                this.game.addBattle(this.battles[id]);
            }
        }
        else if (evtName === RG.EVT_BATTLE_OVER) {
            const {battle} = args;
            if (battle) {
                this.addBadgesForActors(battle);
                this.moveActorsOutOfBattle(battle);
            }
            else {
                const json = JSON.stringify(args);
                RG.err('Game.Master', 'notify',
                    `Args ${json} does not contain "battle"`);
            }
            console.log('GameMaster registered battle over');
            RG.gameMsg('Battle is over!');
            // TODO delete the battle (but keep the level)
        }
    };
    RG.POOL.listenEvent(RG.EVT_LEVEL_CHANGED, this);
    RG.POOL.listenEvent(RG.EVT_TILE_CHANGED, this);
    RG.POOL.listenEvent(RG.EVT_BATTLE_OVER, this);

    /* Adds BattleBadges after a battle is over. */
    this.addBadgesForActors = battle => {
        const armies = battle.getArmies();
        armies.forEach(army => {
            const actors = army.getActors();
            const ids = actors.map(actor => actor.getID());

            actors.forEach(actor => {
                const badge = new RG.Component.BattleBadge();
                if (army.isDefeated()) {
                    badge.setStatus('Defeated');
                }
                else {
                    badge.setStatus('Won');
                }
                const battleData = {
                    name: battle.getName(),
                    allies: ids
                };
                badge.setData(battleData);
                actor.add(badge);

                let name = actor.getName();
                name = `Battle-tested ${name}`;
                actor.setName(name);
            });
        });
    };

    /* Moves actors out of the battle level into the parent level of the battle
     * (at the moment this is always Area.Tile level. */
    this.moveActorsOutOfBattle = battle => {
        const level = battle.getLevel();
        const conns = level.getConnections();

        if (!conns || conns.length === 0) {
            RG.err('Game.Master', 'moveActorsOutOfBattle',
                'No exit connnection in level');
        }

        const exit = conns[0];
        const targetLevel = exit.getTargetLevel();

        const armies = battle.getArmies();
        armies.forEach(army => {
            const actors = army.getActors();
            actors.forEach(actor => {
                if (level.removeActor(actor)) {
                    targetLevel.addActorToFreeCell(actor);
                }
                else {
                    const json = JSON.stringify(actor.toJSON());
                    RG.err('Game.Master', 'moveActorsOutOfBattle',
                        `removeActor failed for actor ${json}`);
                }
            });
        });

    };

    /* Returns the selection object for player to select an army. */
    this.getSelectionObject = function(player, battle) {
        return {
            showMenu: () => true,
            getMenu: () => {
                RG.gameMsg('Please select an army to join:');
                const armies = battle.getArmies();
                const menuObj = {};
                armies.forEach((army, i) => {
                    menuObj[i] = ' Army ' + army.getName();
                });
                menuObj['Any other key'] = 'Take no side';
                return menuObj;
            },
            select: code => {
                const selection = RG.codeToIndex(code);
                const armies = battle.getArmies();
                if (selection < armies.length) {
                    return () => {
                        armies[selection].addActor(player);
                    };
                }
                return null;
            }
        };
    };

    /* Serializes the object into JSON. */
    this.toJSON = function() {
        const keys = Object.keys(this.battles);
        const battles = {};
        keys.forEach(id => {
            battles[id] = this.battles[id].toJSON();
        });
        return {
            battles
        };
    };
};

module.exports = GameMaster;
<|endoftext|>


<commit_before>const path = require("path");
const promisify = require("promisify-node");
const fse = promisify(require("fs-extra"));
const os = require('os');
const exec = require('../../utils/execPromise');
const utils = require("./utils");

module.exports = function generateNativeCode() {
  const combyne = require("combyne");
  const js_beautify = require("js-beautify").js_beautify;
  const beautify = function (input) {
    return js_beautify(input, {
      "brace_style": "end-expand",
      "max_preserve_newlines": 2,
      "preserve_newlines": true,
      "indent_size": 2,
      "indent_char": " "
    });
  };

  // Customize the delimiters so as to not process `{{{` or `}}}`.
  combyne.settings.delimiters = {
    START_RAW: "{{=",
    END_RAW: "=}}"
  };

  var partials = {
    asyncFunction: utils.readLocalFile("templates/partials/async_function.cc"),
    callbackHelpers: utils.readLocalFile("templates/partials/callback_helpers.cc"),
    convertFromV8: utils.readLocalFile("templates/partials/convert_from_v8.cc"),
    convertToV8: utils.readLocalFile("templates/partials/convert_to_v8.cc"),
    doc: utils.readLocalFile("templates/partials/doc.cc"),
    fields: utils.readLocalFile("templates/partials/fields.cc"),
    guardArguments: utils.readLocalFile("templates/partials/guard_arguments.cc"),
    syncFunction: utils.readLocalFile("templates/partials/sync_function.cc"),
    fieldAccessors: utils.readLocalFile("templates/partials/field_accessors.cc"),
    traits: utils.readLocalFile("templates/partials/traits.h")
  };

  var templates = {
    class_content: utils.readLocalFile("templates/templates/class_content.cc"),
    struct_content: utils.readLocalFile("templates/templates/struct_content.cc"),
    class_header: utils.readLocalFile("templates/templates/class_header.h"),
    struct_header: utils.readLocalFile("templates/templates/struct_header.h"),
    binding: utils.readLocalFile("templates/templates/binding.gyp"),
    nodegitCC: utils.readLocalFile("templates/templates/nodegit.cc"),
    nodegitJS: utils.readLocalFile("templates/templates/nodegit.js"),
    enums: utils.readLocalFile("templates/templates/enums.js")
  };

  var filters = {
    and: require("../templates/filters/and"),
    argsInfo: require("../templates/filters/args_info"),
    cppToV8: require("../templates/filters/cpp_to_v8"),
    defaultValue: require("../templates/filters/default_value"),
    fieldsInfo: require("../templates/filters/fields_info"),
    hasReturnType: require("../templates/filters/has_return_type"),
    hasReturnValue: require("../templates/filters/has_return_value"),
    isDoublePointer: require("../templates/filters/is_double_pointer"),
    isFixedLengthString: require("../templates/filters/is_fixed_length_string"),
    isOid: require("../templates/filters/is_oid"),
    isPayload: require("../templates/filters/is_payload"),
    isPointer: require("../templates/filters/is_pointer"),
    isV8Value: require("../templates/filters/is_v8_value"),
    jsArgsCount: require("../templates/filters/js_args_count"),
    or: require("../templates/filters/or"),
    payloadFor: require("../templates/filters/payload_for"),
    replace: require("../templates/filters/replace"),
    returnsCount: require("../templates/filters/returns_count"),
    returnsInfo: require("../templates/filters/returns_info"),
    titleCase: require("../templates/filters/title_case"),
    toBool: require('../templates/filters/to_bool'),
    unPointer: require("../templates/filters/un_pointer"),
    upper: require("../templates/filters/upper")
  };

  // Convert Buffers to Combyne templates.
  Object.keys(templates).forEach(function(template) {
    templates[template] = combyne(templates[template]);

    // Attach all filters to all templates.
    Object.keys(filters).forEach(function(filter) {
      templates[template].registerFilter(filter, filters[filter]);
    });
  });

  // Attach all partials to select templates.
  Object.keys(partials).forEach(function(partial) {
    templates.class_header.registerPartial(partial, combyne(partials[partial]));
    templates.class_content.registerPartial(partial, combyne(partials[partial]));
    templates.struct_header.registerPartial(partial, combyne(partials[partial]));
    templates.struct_content.registerPartial(partial, combyne(partials[partial]));
  });

  // Determine which definitions to actually include in the source code.
  // This might not be needed anymore but to be frank I'm not totally positive
  const idefs = require("../output/idefs");
  var enabled = idefs.filter(function(idef) {
    return !idef.ignore;
  });

  const tempDirPath = path.join(os.tmpdir(), 'nodegit_build');
  const tempSrcDirPath = path.join(tempDirPath, "src");
  const tempIncludeDirPath = path.join(tempDirPath, "include");

  const finalSrcDirPath = path.join(__dirname, '../../src');
  const finalIncludeDirPath = path.join(__dirname, '../../include');

  fse.remove(tempDirPath).then(function() {
    return fse.copy(path.resolve(__dirname, "../templates/manual/include"), tempIncludeDirPath);
  }).then(function() {
    return fse.copy(path.resolve(__dirname, "../templates/manual/src"), tempSrcDirPath);
  }).then(function() {
    // Write out single purpose templates.
    utils.writeLocalFile("../binding.gyp", beautify(templates.binding.render(enabled)), "binding.gyp");
    utils.writeFile(path.join(tempSrcDirPath, "nodegit.cc"), templates.nodegitCC.render(enabled), "nodegit.cc");
    utils.writeLocalFile("../lib/nodegit.js", beautify(templates.nodegitJS.render(enabled)), "nodegit.js");
    // Write out all the classes.
    enabled.forEach(function(idef) {
      if (idef.type && idef.type != "enum") {
        utils.writeFile(
          path.format({dir: tempSrcDirPath, name: idef.filename, ext: ".cc"}),
          templates[idef.type + "_content"].render(idef),
          idef.type + "_content.cc"
        );

        utils.writeFile(
          path.format({dir: tempIncludeDirPath, name: idef.filename, ext: ".h"}),
          templates[idef.type + "_header"].render(idef),
          idef.type + "_header.h"
        );
      }
    });

    utils.writeLocalFile("../lib/enums.js", beautify(templates.enums.render(enabled)), "enums.js");
  }).then(function() {
    return exec("command -v astyle").then(function(astyle) {
      if (astyle) {
        return exec(
          "astyle --options=\".astylerc\" "
          + tempSrcDirPath + "/*.cc "
          + tempIncludeDirPath + "/*.h"
        ).then(function() {
          return exec(
            "rm "
            + tempSrcDirPath + "/*.cc.orig "
            + tempIncludeDirPath + "/*.h.orig "
          );
        });
      }
    }, function() {})
  }).then(function() {
    return Promise.all([
      utils.syncDirs(tempSrcDirPath, finalSrcDirPath),
      utils.syncDirs(tempIncludeDirPath, finalIncludeDirPath),
    ]);
  }).then(function() {
    return fse.remove(tempDirPath);
  }).catch(console.log);

};

if (require.main === module) {
  module.exports();
}
<commit_msg>Remove path.format since it's not available in all node versions<commit_after>const path = require("path");
const promisify = require("promisify-node");
const fse = promisify(require("fs-extra"));
const os = require('os');
const exec = require('../../utils/execPromise');
const utils = require("./utils");

module.exports = function generateNativeCode() {
  const combyne = require("combyne");
  const js_beautify = require("js-beautify").js_beautify;
  const beautify = function (input) {
    return js_beautify(input, {
      "brace_style": "end-expand",
      "max_preserve_newlines": 2,
      "preserve_newlines": true,
      "indent_size": 2,
      "indent_char": " "
    });
  };

  // Customize the delimiters so as to not process `{{{` or `}}}`.
  combyne.settings.delimiters = {
    START_RAW: "{{=",
    END_RAW: "=}}"
  };

  var partials = {
    asyncFunction: utils.readLocalFile("templates/partials/async_function.cc"),
    callbackHelpers: utils.readLocalFile("templates/partials/callback_helpers.cc"),
    convertFromV8: utils.readLocalFile("templates/partials/convert_from_v8.cc"),
    convertToV8: utils.readLocalFile("templates/partials/convert_to_v8.cc"),
    doc: utils.readLocalFile("templates/partials/doc.cc"),
    fields: utils.readLocalFile("templates/partials/fields.cc"),
    guardArguments: utils.readLocalFile("templates/partials/guard_arguments.cc"),
    syncFunction: utils.readLocalFile("templates/partials/sync_function.cc"),
    fieldAccessors: utils.readLocalFile("templates/partials/field_accessors.cc"),
    traits: utils.readLocalFile("templates/partials/traits.h")
  };

  var templates = {
    class_content: utils.readLocalFile("templates/templates/class_content.cc"),
    struct_content: utils.readLocalFile("templates/templates/struct_content.cc"),
    class_header: utils.readLocalFile("templates/templates/class_header.h"),
    struct_header: utils.readLocalFile("templates/templates/struct_header.h"),
    binding: utils.readLocalFile("templates/templates/binding.gyp"),
    nodegitCC: utils.readLocalFile("templates/templates/nodegit.cc"),
    nodegitJS: utils.readLocalFile("templates/templates/nodegit.js"),
    enums: utils.readLocalFile("templates/templates/enums.js")
  };

  var filters = {
    and: require("../templates/filters/and"),
    argsInfo: require("../templates/filters/args_info"),
    cppToV8: require("../templates/filters/cpp_to_v8"),
    defaultValue: require("../templates/filters/default_value"),
    fieldsInfo: require("../templates/filters/fields_info"),
    hasReturnType: require("../templates/filters/has_return_type"),
    hasReturnValue: require("../templates/filters/has_return_value"),
    isDoublePointer: require("../templates/filters/is_double_pointer"),
    isFixedLengthString: require("../templates/filters/is_fixed_length_string"),
    isOid: require("../templates/filters/is_oid"),
    isPayload: require("../templates/filters/is_payload"),
    isPointer: require("../templates/filters/is_pointer"),
    isV8Value: require("../templates/filters/is_v8_value"),
    jsArgsCount: require("../templates/filters/js_args_count"),
    or: require("../templates/filters/or"),
    payloadFor: require("../templates/filters/payload_for"),
    replace: require("../templates/filters/replace"),
    returnsCount: require("../templates/filters/returns_count"),
    returnsInfo: require("../templates/filters/returns_info"),
    titleCase: require("../templates/filters/title_case"),
    toBool: require('../templates/filters/to_bool'),
    unPointer: require("../templates/filters/un_pointer"),
    upper: require("../templates/filters/upper")
  };

  // Convert Buffers to Combyne templates.
  Object.keys(templates).forEach(function(template) {
    templates[template] = combyne(templates[template]);

    // Attach all filters to all templates.
    Object.keys(filters).forEach(function(filter) {
      templates[template].registerFilter(filter, filters[filter]);
    });
  });

  // Attach all partials to select templates.
  Object.keys(partials).forEach(function(partial) {
    templates.class_header.registerPartial(partial, combyne(partials[partial]));
    templates.class_content.registerPartial(partial, combyne(partials[partial]));
    templates.struct_header.registerPartial(partial, combyne(partials[partial]));
    templates.struct_content.registerPartial(partial, combyne(partials[partial]));
  });

  // Determine which definitions to actually include in the source code.
  // This might not be needed anymore but to be frank I'm not totally positive
  const idefs = require("../output/idefs");
  var enabled = idefs.filter(function(idef) {
    return !idef.ignore;
  });

  const tempDirPath = path.join(os.tmpdir(), 'nodegit_build');
  const tempSrcDirPath = path.join(tempDirPath, "src");
  const tempIncludeDirPath = path.join(tempDirPath, "include");

  const finalSrcDirPath = path.join(__dirname, '../../src');
  const finalIncludeDirPath = path.join(__dirname, '../../include');

  fse.remove(tempDirPath).then(function() {
    return fse.copy(path.resolve(__dirname, "../templates/manual/include"), tempIncludeDirPath);
  }).then(function() {
    return fse.copy(path.resolve(__dirname, "../templates/manual/src"), tempSrcDirPath);
  }).then(function() {
    // Write out single purpose templates.
    utils.writeLocalFile("../binding.gyp", beautify(templates.binding.render(enabled)), "binding.gyp");
    utils.writeFile(path.join(tempSrcDirPath, "nodegit.cc"), templates.nodegitCC.render(enabled), "nodegit.cc");
    utils.writeLocalFile("../lib/nodegit.js", beautify(templates.nodegitJS.render(enabled)), "nodegit.js");
    // Write out all the classes.
    enabled.forEach(function(idef) {
      if (idef.type && idef.type != "enum") {
        utils.writeFile(
          path.join(tempSrcDirPath, idef.filename + ".cc"),
          templates[idef.type + "_content"].render(idef),
          idef.type + "_content.cc"
        );

        utils.writeFile(
          path.join(tempIncludeDirPath, idef.filename + ".h"),
          templates[idef.type + "_header"].render(idef),
          idef.type + "_header.h"
        );
      }
    });

    utils.writeLocalFile("../lib/enums.js", beautify(templates.enums.render(enabled)), "enums.js");
  }).then(function() {
    return exec("command -v astyle").then(function(astyle) {
      if (astyle) {
        return exec(
          "astyle --options=\".astylerc\" "
          + tempSrcDirPath + "/*.cc "
          + tempIncludeDirPath + "/*.h"
        ).then(function() {
          return exec(
            "rm "
            + tempSrcDirPath + "/*.cc.orig "
            + tempIncludeDirPath + "/*.h.orig "
          );
        });
      }
    }, function() {})
  }).then(function() {
    return Promise.all([
      utils.syncDirs(tempSrcDirPath, finalSrcDirPath),
      utils.syncDirs(tempIncludeDirPath, finalIncludeDirPath),
    ]);
  }).then(function() {
    return fse.remove(tempDirPath);
  }).catch(console.log);

};

if (require.main === module) {
  module.exports();
}
<|endoftext|>


<commit_before>// Copyright 2013-2015, University of Colorado Boulder

/**
 * Control panel around a content node.
 * Dynamically adjusts its size to fit its contents.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chris Malley (PixelZoom, Inc.)
 * @author John Blanco
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );
  var sun = require( 'SUN/sun' );
  var Tandem = require( 'TANDEM/Tandem' );

  // phet-io modules
  var TPanel = require( 'ifphetio!PHET_IO/types/sun/TPanel' );

  // valid values for options.align
  var ALIGN_VALUES = [ 'left', 'center', 'right' ];

  var DEFAULT_OPTIONS = {
    fill: 'white',
    stroke: 'black',
    lineWidth: 1, // width of the background border
    xMargin: 5,
    yMargin: 5,
    cornerRadius: 10, // radius of the rounded corners on the background
    resize: true, // dynamically resize when content bounds change
    backgroundPickable: false,

    // {string} horizontal alignment of content in the pane, see ALIGN_VALUES
    // All alignments are equal when the content width >= minWidth
    // Left is the default alignment so when there are multiple panels, their content will left align, see #252
    align: 'left',

    minWidth: 0, // minimum width of the panel
    tandem: Tandem.tandemRequired(),
    phetioType: TPanel
  };
  assert && Object.freeze( DEFAULT_OPTIONS );

  /**
   * @param {Node} content
   * @param {Object} [options]
   * @constructor
   */
  function Panel( content, options ) {

    options = _.extend( {}, DEFAULT_OPTIONS, options );

    var self = this;

    assert && assert( _.includes( ALIGN_VALUES, options.align ), 'invalid align: ' + options.align );

    Node.call( this );

    // correct size will be set by updateBackground
    var background = new Rectangle( 0, 0, 1, 1, {
      lineWidth: options.lineWidth,
      pickable: options.backgroundPickable,
      lineDash: options.lineDash,
      cornerRadius: options.cornerRadius
    } );
    this.background = background; // @private
    // update the fill and stroke
    this.setStroke( options.stroke );
    this.setFill( options.fill );

    this.addChild( background );
    this.addChild( content );

    // flag for preventing recursion
    var backgroundUpdateInProgress = false;

    // Adjust the background size to match the content.
    var updateBackground = function() {

      // Check that an update isn't already in progress, lest we end up with some nasty recursion.  For details, please
      // see https://github.com/phetsims/sun/issues/110 and https://github.com/phetsims/molecule-shapes/issues/130.
      if ( backgroundUpdateInProgress ) {
        return;
      }

      // Bail out (and make the background invisible) if our bounds are invalid
      background.visible = content.bounds.isValid();
      if ( !background.visible ) {
        return;
      }

      backgroundUpdateInProgress = true;

      // size the background to fit the content
      var backgroundWidth = Math.max( options.minWidth, content.width + ( 2 * options.xMargin ) );
      background.setRect( 0, 0, backgroundWidth, content.height + ( 2 * options.yMargin ) );

      // Align the content within the background. If the content width >= minWidth, then all alignments are equivalent.
      if ( options.align === 'center' ) {
        content.center = background.center;
      }
      else if ( options.align === 'left' ) {

        // Use backgroundWidth instead of background.width because they differ by the background lineWidth
        content.left = background.centerX - backgroundWidth / 2 + options.xMargin;
        content.centerY = background.centerY;
      }
      else { /* right */

        // Use backgroundWidth instead of background.width because they differ by the background lineWidth
        content.right = background.centerX + backgroundWidth / 2 - options.xMargin;
        content.centerY = background.centerY;
      }

      // clear the recursion-prevention flag
      backgroundUpdateInProgress = false;
    };

    if ( options.resize ) {
      content.on( 'bounds', updateBackground );
    }
    updateBackground();

    this.disposePanel = function() {
      if ( options.resize ) {
        content.off( 'bounds', updateBackground );
      }
    };

    // Apply options after the layout is done, so that options that use the bounds will work properly.
    this.mutate( options );
  }

  sun.register( 'Panel', Panel );

  inherit( Node, Panel, {

    // @public
    dispose: function() {
      this.disposePanel();
    },

    // @public - Change the background rectangle's stroke (can be overridden)
    setStroke: function( stroke ) {
      this.background.stroke = stroke;
    },

    // @public - Get the background rectangle's stroke (can be overridden)
    getStroke: function() {
      return this.background.stroke;
    },

    // @public - Getter/setter for background stroke
    set stroke( value ) { this.setStroke( value ); },
    get stroke() { return this.getStroke(); },

    // @public - Change the background rectangle's fill (can be overridden)
    setFill: function( fill ) {
      this.background.fill = fill;
    },

    // @public - Get the background rectangle's fill (can be overridden)
    getFill: function() {
      return this.background.fill;
    },

    // @public - Getter/setter for background fill
    set fill( value ) { this.setFill( value ); },
    get fill() { return this.getFill(); }
  }, {

    // @static @public (read-only)
    DEFAULT_OPTIONS: DEFAULT_OPTIONS
  } );

  return Panel;
} );<commit_msg>Added missing dispose call, see https://github.com/phetsims/scenery/issues/603<commit_after>// Copyright 2013-2015, University of Colorado Boulder

/**
 * Control panel around a content node.
 * Dynamically adjusts its size to fit its contents.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chris Malley (PixelZoom, Inc.)
 * @author John Blanco
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );
  var sun = require( 'SUN/sun' );
  var Tandem = require( 'TANDEM/Tandem' );

  // phet-io modules
  var TPanel = require( 'ifphetio!PHET_IO/types/sun/TPanel' );

  // valid values for options.align
  var ALIGN_VALUES = [ 'left', 'center', 'right' ];

  var DEFAULT_OPTIONS = {
    fill: 'white',
    stroke: 'black',
    lineWidth: 1, // width of the background border
    xMargin: 5,
    yMargin: 5,
    cornerRadius: 10, // radius of the rounded corners on the background
    resize: true, // dynamically resize when content bounds change
    backgroundPickable: false,

    // {string} horizontal alignment of content in the pane, see ALIGN_VALUES
    // All alignments are equal when the content width >= minWidth
    // Left is the default alignment so when there are multiple panels, their content will left align, see #252
    align: 'left',

    minWidth: 0, // minimum width of the panel
    tandem: Tandem.tandemRequired(),
    phetioType: TPanel
  };
  assert && Object.freeze( DEFAULT_OPTIONS );

  /**
   * @param {Node} content
   * @param {Object} [options]
   * @constructor
   */
  function Panel( content, options ) {

    options = _.extend( {}, DEFAULT_OPTIONS, options );

    var self = this;

    assert && assert( _.includes( ALIGN_VALUES, options.align ), 'invalid align: ' + options.align );

    Node.call( this );

    // correct size will be set by updateBackground
    var background = new Rectangle( 0, 0, 1, 1, {
      lineWidth: options.lineWidth,
      pickable: options.backgroundPickable,
      lineDash: options.lineDash,
      cornerRadius: options.cornerRadius
    } );
    this.background = background; // @private
    // update the fill and stroke
    this.setStroke( options.stroke );
    this.setFill( options.fill );

    this.addChild( background );
    this.addChild( content );

    // flag for preventing recursion
    var backgroundUpdateInProgress = false;

    // Adjust the background size to match the content.
    var updateBackground = function() {

      // Check that an update isn't already in progress, lest we end up with some nasty recursion.  For details, please
      // see https://github.com/phetsims/sun/issues/110 and https://github.com/phetsims/molecule-shapes/issues/130.
      if ( backgroundUpdateInProgress ) {
        return;
      }

      // Bail out (and make the background invisible) if our bounds are invalid
      background.visible = content.bounds.isValid();
      if ( !background.visible ) {
        return;
      }

      backgroundUpdateInProgress = true;

      // size the background to fit the content
      var backgroundWidth = Math.max( options.minWidth, content.width + ( 2 * options.xMargin ) );
      background.setRect( 0, 0, backgroundWidth, content.height + ( 2 * options.yMargin ) );

      // Align the content within the background. If the content width >= minWidth, then all alignments are equivalent.
      if ( options.align === 'center' ) {
        content.center = background.center;
      }
      else if ( options.align === 'left' ) {

        // Use backgroundWidth instead of background.width because they differ by the background lineWidth
        content.left = background.centerX - backgroundWidth / 2 + options.xMargin;
        content.centerY = background.centerY;
      }
      else { /* right */

        // Use backgroundWidth instead of background.width because they differ by the background lineWidth
        content.right = background.centerX + backgroundWidth / 2 - options.xMargin;
        content.centerY = background.centerY;
      }

      // clear the recursion-prevention flag
      backgroundUpdateInProgress = false;
    };

    if ( options.resize ) {
      content.on( 'bounds', updateBackground );
    }
    updateBackground();

    this.disposePanel = function() {
      if ( options.resize ) {
        content.off( 'bounds', updateBackground );
      }
    };

    // Apply options after the layout is done, so that options that use the bounds will work properly.
    this.mutate( options );
  }

  sun.register( 'Panel', Panel );

  inherit( Node, Panel, {

    // @public
    dispose: function() {
      this.disposePanel();
      Node.prototype.dispose.call( this );
    },

    // @public - Change the background rectangle's stroke (can be overridden)
    setStroke: function( stroke ) {
      this.background.stroke = stroke;
    },

    // @public - Get the background rectangle's stroke (can be overridden)
    getStroke: function() {
      return this.background.stroke;
    },

    // @public - Getter/setter for background stroke
    set stroke( value ) { this.setStroke( value ); },
    get stroke() { return this.getStroke(); },

    // @public - Change the background rectangle's fill (can be overridden)
    setFill: function( fill ) {
      this.background.fill = fill;
    },

    // @public - Get the background rectangle's fill (can be overridden)
    getFill: function() {
      return this.background.fill;
    },

    // @public - Getter/setter for background fill
    set fill( value ) { this.setFill( value ); },
    get fill() { return this.getFill(); }
  }, {

    // @static @public (read-only)
    DEFAULT_OPTIONS: DEFAULT_OPTIONS
  } );

  return Panel;
} );<|endoftext|>


<commit_before>"use strict";

const fs = require( "fs" );
const path = require( "path" );
const root = __dirname;
const rootNodeModules = path.join( root, "node_modules" );
const rootPackageLock = path.join( root, "package-lock.json" );
const rootSandbox = path.join( root, "sandbox" );
const rootTemplatePartials = path.join( root, "template", "partials" );
const rootNotes = path.join( root, ".notes" );
const rootServer = path.join( root, "server" );
const rootTasks = path.join( root, "tasks" );
const rootSource = path.join( root, "source" );
const rootHobo = path.join( rootNodeModules, "properjs-hobo" );
const child_process = require( "child_process" );
const config = require( "./clutch.config" );

// Note that with `npm@5` there have been some hiccups
// The ultimate resolve was to trash the `.npm` cache

// 1.0: Fresh `node_modules`
console.log( "Installing node_modules..." );

// child_process.execSync( `rm -rf ${rootPackageLock}` );
// child_process.execSync( `rm -rf ${rootNodeModules}` );
child_process.execSync( "npm i" );

// 2.0 Create sandbox
console.log( "Creating sandbox..." );

if ( !fs.existsSync( rootSandbox ) ) {
    child_process.execSync( `mkdir ${rootSandbox}` );
    child_process.execSync( `mkdir ${path.join( rootSandbox, "authorizations" )}` );
}

// 3.0 Create template partials
console.log( "Creating template partials..." );

if ( !fs.existsSync( rootTemplatePartials ) ) {
    child_process.execSync( `mkdir ${rootTemplatePartials}` );
}

// 4.0 Create notes
console.log( "Creating notes..." );

if ( !fs.existsSync( rootNotes ) ) {
    child_process.execSync( `touch ${rootNotes}` );
}

// 5.0 Create source
console.log( "Creating source...?" );

if ( !fs.existsSync( rootSource ) ) {
    child_process.execSync( `./node_modules/.bin/clutch source` );
}

// 6.0 Hobo.js build
console.log( "Building properjs-hobo..." );

child_process.execSync( `cd ${rootHobo} && npm install && npm run build -- '${config.browser.hobo}'` );

// 7.0 server install
console.log( "Installing server node_modules..." );

child_process.execSync( `cd ${rootServer} && npm i` );

// 8.0 tasks install
console.log( "Installing tasks node_modules..." );

if ( fs.existsSync( rootTasks ) ) {
    child_process.execSync( `cd ${rootTasks} && npm i` );
}

// 9.0 done
console.log( "Done!" );
<commit_msg>local install clutch-cli only for install. Fixes #51.<commit_after>"use strict";

const fs = require( "fs" );
const path = require( "path" );
const root = __dirname;
const rootNodeModules = path.join( root, "node_modules" );
const rootPackageLock = path.join( root, "package-lock.json" );
const rootSandbox = path.join( root, "sandbox" );
const rootTemplatePartials = path.join( root, "template", "partials" );
const rootNotes = path.join( root, ".notes" );
const rootServer = path.join( root, "server" );
const rootTasks = path.join( root, "tasks" );
const rootSource = path.join( root, "source" );
const rootHobo = path.join( rootNodeModules, "properjs-hobo" );
const child_process = require( "child_process" );
const config = require( "./clutch.config" );

// Note that with `npm@5` there have been some hiccups
// The ultimate resolve was to trash the `.npm` cache

// 1.0: Fresh `node_modules`
console.log( "Installing node_modules..." );

// child_process.execSync( `rm -rf ${rootPackageLock}` );
// child_process.execSync( `rm -rf ${rootNodeModules}` );
child_process.execSync( "npm i" );

// 2.0 Create sandbox
console.log( "Creating sandbox..." );

if ( !fs.existsSync( rootSandbox ) ) {
    child_process.execSync( `mkdir ${rootSandbox}` );
    child_process.execSync( `mkdir ${path.join( rootSandbox, "authorizations" )}` );
}

// 3.0 Create template partials
console.log( "Creating template partials..." );

if ( !fs.existsSync( rootTemplatePartials ) ) {
    child_process.execSync( `mkdir ${rootTemplatePartials}` );
}

// 4.0 Create notes
console.log( "Creating notes..." );

if ( !fs.existsSync( rootNotes ) ) {
    child_process.execSync( `touch ${rootNotes}` );
}

// 5.0 Create source
console.log( "Creating source...?" );

if ( !fs.existsSync( rootSource ) ) {
    child_process.execSync( `npm install clutch-cli` );
    child_process.execSync( `./node_modules/.bin/clutch source` );
}

// 6.0 Hobo.js build
console.log( "Building properjs-hobo..." );

child_process.execSync( `cd ${rootHobo} && npm install && npm run build -- '${config.browser.hobo}'` );

// 7.0 server install
console.log( "Installing server node_modules..." );

child_process.execSync( `cd ${rootServer} && npm i` );

// 8.0 tasks install
console.log( "Installing tasks node_modules..." );

if ( fs.existsSync( rootTasks ) ) {
    child_process.execSync( `cd ${rootTasks} && npm i` );
}

// 9.0 done
console.log( "Done!" );
<|endoftext|>