<commit_before>;(function() {
  "use strict";

  angular.
    module("bookApp").
    component("bookApp", {
      template: `
        Add new book

{{book.title}}

{{book.author}}

{{book.rate}}

{{book.description}}

      `,
      controller: BookAppController
    });

  BookAppController.$inject = ["$scope"];

  function BookAppController($scope) {
    let vm = this,
        bookRef = firebase.database().ref("Books");

    vm.books = [];

    bookRef.on("value", function(snapshot) {
      // vm.users.push(snapshot.val());
      snapshot.forEach(function(subSnap) {
        vm.books.push(subSnap.val());
      });

      if(!$scope.$$phase) $scope.$apply();
    });
  }
})();<commit_msg>Update book-app.component.js<commit_after>;(function() {
  "use strict";

  angular.
    module("bookApp").
    component("bookApp", {
      template: `

Add new book

{{book.title}}

{{book.rate}}

{{book.author}}

{{book.descroption}}

      `,
      controller: BookAppController
    });

  BookAppController.$inject = ["$scope"];

  function BookAppController($scope) {
    let vm = this,
        bookRef = firebase.database().ref("Books");

    vm.books = [];

    bookRef.on("value", function(snapshot) {
      // vm.users.push(snapshot.val());
      snapshot.forEach(function(subSnap) {
        vm.books.push(subSnap.val());
      });

      if(!$scope.$$phase) $scope.$apply();
    });
  }
})();
<|endoftext|>


<commit_before>define([
    'angular',
    'lodash',
    'app/core/utils/datemath',
    'moment',
    './directives',
    './autogrow',
    './query_ctrl',
],
       function (angular, _, dateMath) {
           'use strict';

           var module = angular.module('grafana.services');

           module.factory('RaspimonPandasDatasource', function($q, backendSrv) {

               // the datasource object passed to constructor is the same
               // defined in config.js named `current`
               function RaspimonPandasDatasource(datasource) {
                   this.name = datasource.name;
                   this.type = "raspimon_pandas";
                   this.url  = datasource.url;
                   // jsonData is a dictionary created by the controller and
                   // resued by raspimon_pandas to track new configuration items
                   if (datasource.jsonData) {
                       this.topic_filters = datasource.jsonData.topic_filters;
                   }
                   else {
                       this.topic_filters = [];
                   }
                   this.supportMetrics = true;
               }

               // performs an HTTP GET request to datasource using the
               // backendSrv
               RaspimonPandasDatasource.prototype._get = function(relativeUrl) {
                   return backendSrv.datasourceRequest({
                       method: 'GET',
                       url: this.url + relativeUrl,
                   });
               };

               // performs an HTTP POST request to datasource using the
               // backendSrv
               RaspimonPandasDatasource.prototype._post = function(relativeUrl, data) {
                   return backendSrv.datasourceRequest({
                       method: 'POST',
                       url: this.url + relativeUrl,
                       data: data,
                   });
               };

               // Receives a query configuration (as defined in query editor),
               // an array of data as returned by datasource request, and
               // returns it as a time-series object expected by Grafana.
               var transformToTimeSeries = function(query, data) {
                   var dps = [];
                   _.each(data, function(v) {
                       var mul = query.mul || 1.0;
                       var add = query.add || 0.0;
                       // multiply timestamp by 1000 to transform from float
                       // seconds to integer miliseconds
                       var t = Math.round(v[1] * 1000);
                       if (v[0] === null) dps.push([null, t]);
                       else dps.push([v[0]*mul + add, t]);
                   });
                   console.log(data);
                   console.log(dps);
                   // a time-series has 'target' string and 'datapoints' array
                   return {
                       target: query.alias || query.topic,
                       datapoints: dps,
                   };
               };

               // a facility which allow to cache call to functions which return
               // a promise
               var buildCachedPromiseMethod = function(func) {
                   var promise;
                   return function() {
                       if (!promise) promise = func(this);
                       return promise;
                   }
               };

               // This function processes all queries in array `options.target`
               // using the configuration of `options` object. It requests every
               // query to datasource server and transforms its response into a
               // time-series expected by Grafana.
               RaspimonPandasDatasource.prototype.query = function(options) {
                   console.log('options: ' + JSON.stringify(options));
                   var self = this; // forward declaration
                   // get from & to in seconds
                   var from = Math.floor(dateMath.parse(options.range.from) / 1000);
                   var to = Math.ceil(dateMath.parse(options.range.to) / 1000);
                   var maxDataPoints = options.maxDataPoints
                   var qs = [];

                   // take only not hidden `targets` and with a proper topic
                   _.each(options.targets, function(target) {
                       if (target.topic && !target.hide) qs.push(target);
                   });

                   if (_.isEmpty(qs)) {
                       var d = $q.defer();
                       d.resolve({ data: [] });
                       return d.promise;
                   }

                   var buildQueryUrl = function(topic, aggregator) {
                       return "/raspimon_pandas/api/pandas/" + aggregator + "/" + topic + "/" + from + "/" + to + "/" + maxDataPoints;
                   };

                   // chain all promises, one per each element at qs (targets)
                   var promises = []
                   _.each(qs, function(q) {
                       var funcs_list = [];
                       _.each(q.functions, function(x) {
                           if (x.name) {
                               var args = x.args || "";
                               funcs_list.push( x.name+"("+ args + ")" );
                           }
                       });
                       promises.push( self._post(buildQueryUrl(q.topic, q.consolidateby || "last"),
                                                 funcs_list)
                                      .then(function(response) {
                                          return transformToTimeSeries(q, response.data);
                                      }) );
                   });

                   return $q.all(promises).then(function(result) {
                       // this is the object expected by Grafana
                       return { data: result };
                   });
               };

               // test connectivity requesting the list of topics (all topics)
               RaspimonPandasDatasource.prototype.testDatasource = function () {
                   return this._get('/raspimon_pandas/api/topics').then(function(topics) {
                       if (!topics) return { status: "error", message: "Unable to connect to data source" };
                       return { status: "success", message: "Data source is working", title: "Success" };
                   });
               };

               // facility to process array responses given by datasource
               var array_promise_callback = function(result) {
                   if (result.data && _.isArray(result.data)) {
                       return result.data.sort();
                   }
                   return [];
               };

               var contains_any = function(filters) {
                   return function(x) {
                       var any = false;
                       for (var i=0; i<filters.length && !any; ++i) {
                           any = (x.indexOf(filters[i]) > -1);
                       }
                       return any;
                   };
               };

               // Facility to request topics list from query editor.
               RaspimonPandasDatasource.prototype.getTopicsList = buildCachedPromiseMethod(function(self) {
                   return self._get('/raspimon_pandas/api/topics').then(array_promise_callback)
               })

               // Returns the list of topics filtered by using topic_filters
               // property as declared at datasource configuration.
               RaspimonPandasDatasource.prototype.getTopicsListFiltered = function() {
                   var self = this;
                   return this.getTopicsList().then(function(result) {
                       if (self.topic_filters && self.topic_filters.length > 0) {
                           return result.filter(contains_any(self.topic_filters));
                       }
                       else {
                           return result;
                       }
                   });
               };

               // facility to request aggregators list from query editor
               RaspimonPandasDatasource.prototype.getAggregatorsList = buildCachedPromiseMethod(function(self) {
                   return self._get('/raspimon_pandas/api/aggregators').then(array_promise_callback);
               });

               return RaspimonPandasDatasource;
           });
       });
<commit_msg>minor generalizations<commit_after>define([
    'angular',
    'lodash',
    'app/core/utils/datemath',
    'moment',
    './directives',
    './autogrow',
    './query_ctrl',
],
       function (angular, _, dateMath) {
           'use strict';

           var module = angular.module('grafana.services');

           module.factory('RaspimonPandasDatasource', function($q, backendSrv) {

               // the datasource object passed to constructor is the same
               // defined in config.js named `current`
               function RaspimonPandasDatasource(datasource) {
                   this.name = datasource.name;
                   this.type = "raspimon_pandas";
                   this.url  = datasource.url;
                   // jsonData is a dictionary created by the controller and
                   // resued by raspimon_pandas to track new configuration items
                   if (datasource.jsonData) {
                       this.topic_filters = datasource.jsonData.topic_filters;
                   }
                   else {
                       this.topic_filters = [];
                   }
                   this.supportMetrics = true;
               }

               // performs an HTTP GET request to datasource using the
               // backendSrv
               RaspimonPandasDatasource.prototype._get = function(relativeUrl) {
                   return backendSrv.datasourceRequest({
                       method: 'GET',
                       url: this.url + relativeUrl,
                   });
               };

               // performs an HTTP POST request to datasource using the
               // backendSrv
               RaspimonPandasDatasource.prototype._post = function(relativeUrl, data) {
                   return backendSrv.datasourceRequest({
                       method: 'POST',
                       url: this.url + relativeUrl,
                       data: data,
                   });
               };

               // Receives a query configuration (as defined in query editor),
               // an array of data as returned by datasource request, and
               // returns it as a time-series object expected by Grafana.
               var transformToTimeSeries = function(query, data) {
                   var dps = [];
                   _.each(data, function(v) {
                       var mul = query.mul || 1.0;
                       var add = query.add || 0.0;
                       // multiply timestamp by 1000 to transform from float
                       // seconds to integer miliseconds
                       var t = Math.round(v[1] * 1000);
                       if (v[0] === null) dps.push([null, t]);
                       else dps.push([v[0]*mul + add, t]);
                   });
                   // a time-series has 'target' string and 'datapoints' array
                   return {
                       target: query.alias || query.topic,
                       datapoints: dps,
                   };
               };

               // a facility which allow to cache call to functions which return
               // a promise
               var buildCachedPromiseMethod = function(func) {
                   var promise;
                   return function() {
                       if (!promise) promise = func(this);
                       return promise;
                   }
               };

               // This function processes all queries in array `options.target`
               // using the configuration of `options` object. It requests every
               // query to datasource server and transforms its response into a
               // time-series expected by Grafana.
               RaspimonPandasDatasource.prototype.query = function(options) {
                   console.log('options: ' + JSON.stringify(options));
                   var self = this; // forward declaration
                   // get from & to in seconds
                   var from = Math.floor(dateMath.parse(options.range.from) / 1000);
                   var to = Math.ceil(dateMath.parse(options.range.to) / 1000);
                   var maxDataPoints = options.maxDataPoints
                   var qs = [];

                   // take only not hidden `targets` and with a proper topic
                   _.each(options.targets, function(target) {
                       if (target.topic && !target.hide) qs.push(target);
                   });

                   if (_.isEmpty(qs)) {
                       var d = $q.defer();
                       d.resolve({ data: [] });
                       return d.promise;
                   }

                   var buildQueryUrl = function(topic, aggregator) {
                       return "/raspimon_pandas/api/pandas/" + aggregator + "/" + topic + "/" + from + "/" + to + "/" + maxDataPoints;
                   };

                   // chain all promises, one per each element at qs (targets)
                   var promises = []
                   _.each(qs, function(q) {
                       var funcs_list = [];
                       _.each(q.functions, function(x) {
                           if (x.name) {
                               var args = x.args || "";
                               funcs_list.push( x.name+"("+ args + ")" );
                           }
                       });
                       promises.push( self._post(buildQueryUrl(q.topic, q.consolidateby || "last"),
                                                 funcs_list)
                                      .then(function(response) {
                                          return transformToTimeSeries(q, response.data);
                                      }) );
                   });

                   return $q.all(promises).then(function(result) {
                       // this is the object expected by Grafana
                       return { data: result };
                   });
               };

               // test connectivity requesting the list of topics (all topics)
               RaspimonPandasDatasource.prototype.testDatasource = function () {
                   return this._get('/raspimon_pandas/api/topics').then(function(topics) {
                       if (!topics) return { status: "error", message: "Unable to connect to data source" };
                       return { status: "success", message: "Data source is working", title: "Success" };
                   });
               };

               // facility to process array responses given by datasource
               var array_promise_callback = function(result) {
                   if (result.data && _.isArray(result.data)) {
                       return result.data.sort();
                   }
                   return [];
               };

               var contains_any = function(filters) {
                   return function(x) {
                       var any = false;
                       for (var i=0; i<filters.length && !any; ++i) {
                           any = (x.indexOf(filters[i]) > -1);
                       }
                       return any;
                   };
               };

               // Facility to request topics list from query editor.
               RaspimonPandasDatasource.prototype.getTopicsList = buildCachedPromiseMethod(function(self) {
                   return self._get('/raspimon_pandas/api/topics').then(array_promise_callback)
               })

               // Returns the list of topics filtered by using topic_filters
               // property as declared at datasource configuration.
               RaspimonPandasDatasource.prototype.getTopicsListFiltered = function() {
                   var self = this;
                   return this.getTopicsList().then(function(result) {
                       if (self.topic_filters && self.topic_filters.length > 0) {
                           return result.filter(contains_any(self.topic_filters));
                       }
                       else {
                           return result;
                       }
                   });
               };

               // facility to request aggregators list from query editor
               RaspimonPandasDatasource.prototype.getAggregatorsList = buildCachedPromiseMethod(function(self) {
                   return self._get('/raspimon_pandas/api/aggregators').then(array_promise_callback);
               });

               return RaspimonPandasDatasource;
           });
       });
<|endoftext|>


<commit_before><commit_msg>PostItemView view 8<commit_after><|endoftext|>


<commit_before>/*
 Copyright 2017 Michael Hughes

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/**
 * Implements functions for converting to/from a Maidenhead Locator using WGS84 latitude and longitude
 * coordinates.
 *
 * Original description of system by @see {@link http://www.arrl.org/grid-squares|ARRL}
 * @module
 */

const firstLevelDivisions = 18;
const secondLevelDivisions = 10;
const thirdLevelDivisions =  24;
const stargingLongitude = -180;
const startingLatitude = -90;

const alphabet = [
  'a',
  'b',
  'c',
  'd',
  'e',
  'f',
  'g',
  'h',
  'i',
  'j',
  'k',
  'l',
  'm',
  'n',
  'o',
  'p',
  'q',
  'r',
  's',
  't',
  'u',
  'v',
  'w',
  'x'
];

const charMap = alphabet.reduce((accumulator, val, idx) => {
  /* eslint no-param-reassign: 0 */
  accumulator[idx] = val;
  return accumulator;
},{});

/**
 * Converts to a Maidenhead Locator Square from a WGS84 decimal latitude, longitude pair
 * @param {number} latitude A WGS84 decimal latitude
 * @param {number} longitude A WGS84 decimal longitude
 * @return {string} A Maidenhead Locator Square
 */
export function mhLocatorFromLatLng(latitude, longitude) {

}

/**
 * Converts to a decimal WGS84 latitude, longitude pair from a Maidenhead Locator Square
 * @param {string} mhLocator A Maiden Locator Square
 * @return {object} A point object with latitude and longitude
 */
export function latLngFromMhLocator(mhLocator) {

}
<commit_msg>Add, currently, non-functional Maidenhead Locator implementation<commit_after>/*
 Copyright 2017 Michael Hughes

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

import { boundCheckAndAdd, boundCheckAndRetrieve } from './Common';

/**
 * Implements functions for converting to/from a Maidenhead Locator using WGS84 latitude and longitude
 * coordinates.
 *
 * Original description of system by @see {@link http://www.arrl.org/grid-squares|ARRL}
 * @module
 */

const firstLevelDivisions = 18;
const secondLevelDivisions = 10;
const thirdLevelDivisions =  24;
const stargingLongitude = -180;
const startingLatitude = -90;

const alphabet = [
  'a',
  'b',
  'c',
  'd',
  'e',
  'f',
  'g',
  'h',
  'i',
  'j',
  'k',
  'l',
  'm',
  'n',
  'o',
  'p',
  'q',
  'r',
  's',
  't',
  'u',
  'v',
  'w',
  'x'
];

const charMap = alphabet.reduce((accumulator, val, idx) => {
  /* eslint no-param-reassign: 0 */
  accumulator[idx] = val;
  return accumulator;
},{});

/**
 * Converts to a Maidenhead Locator Square from a WGS84 decimal latitude, longitude pair
 * @param {number} latitude A WGS84 decimal latitude
 * @param {number} longitude A WGS84 decimal longitude
 * @return {string} A Maidenhead Locator Square
 */
export function mhLocatorFromLatLng(latitude, longitude) {
  const characters = [];

  // First level calculations

  boundCheckAndAdd(Math.floor(longitude / firstLevelDivisions), characters, alphabet);
  boundCheckAndAdd(Math.floor(latitude / firstLevelDivisions), characters, alphabet);
}

/**
 * Converts to a decimal WGS84 latitude, longitude pair from a Maidenhead Locator Square
 * @param {string} mhLocator A Maiden Locator Square
 * @return {object} A point object with latitude and longitude
 */
export function latLngFromMhLocator(mhLocator) {

}
<|endoftext|>


<commit_before>"use strict";

function BackToMapButton() {

    var _map = null;
    var _this = this;

    var _cnt = null;
    var _btn = null;

    // вспомогательно: относительно окна выравниваем кнопку
    var _$building_info = null;

    var _onClick = function () {
        _map.setMode('viewing');

        if (_map.current_building) {
            _map.current_building.exit();
            _map.current_building = null;
        }

        if (_map.current_area) {
            _map.current_area.exit();
            _map.current_area = null;
        }

        _map.svgRemoveAllNodes();
        _map.draw_childs(_map.data["buildings"]);

        if (_map.initial_map_position != null) {
            /* TODO:: необходимо удостовериться, что параметр scale используется и используется правильно*/
            _map.moveTo(
                _map.initial_map_position.x,
                _map.initial_map_position.y,
                _map.initial_map_position.scale,
                400,
                'easeInOutCubic'
            );
        }

    };

    _this.init = function (parent_div_selector, link_to_map) {
        _map = link_to_map;
        _cnt = $('

').addClass('back_to_map_button');
        _cnt.appendTo($(parent_div_selector));
        _btn = $('Обратно на карту');
        //noinspection JSUnresolvedFunction
        _btn.on('click', _onClick);
        _cnt.append(_btn);

        _$building_info = $('.building_info');

    };

    _this.show = function () {

        // хардкод - подгоняем под длину анимации, прописанной в css (+200 ms на возможный лаг)
        setTimeout(__show, 1000);

    };
    var __show = function () {
        // фиксируем
        var building_info_top = _$building_info.offset().top;
        var building_info_height = _$building_info.height();

        // считаем
        var btn_top = building_info_top + building_info_height;
        var btn_left = _$building_info.offset().left;

        // позиционируем
        _btn.css('top', btn_top + 'px');
        _btn.css('left', btn_left + 'px');

        // показываем
        _btn.css('opacity','1');
        _cnt.css('display', 'block');
    };

    _this.hide = function () {
        _cnt.css('display', 'none');
        _btn.css('opacity', '0');
    }

}
<commit_msg>master: minor: comment.<commit_after>"use strict";

function BackToMapButton() {

    var _map = null;
    var _this = this;

    var _cnt = null;
    var _btn = null;

    // вспомогательно: относительно окна выравниваем кнопку
    var _$building_info = null;

    var _onClick = function () {
        _map.setMode('viewing');

        if (_map.current_building) {
            _map.current_building.exit();
            _map.current_building = null;
        }

        if (_map.current_area) {
            _map.current_area.exit();
            _map.current_area = null;
        }

        _map.svgRemoveAllNodes();
        _map.draw_childs(_map.data["buildings"]);

        if (_map.initial_map_position != null) {
            /* TODO:: необходимо удостовериться, что параметр scale используется и используется правильно*/
            _map.moveTo(
                _map.initial_map_position.x,
                _map.initial_map_position.y,
                _map.initial_map_position.scale,
                400,
                'easeInOutCubic'
            );
        }

    };

    _this.init = function (parent_div_selector, link_to_map) {
        _map = link_to_map;
        _cnt = $('

').addClass('back_to_map_button');
        _cnt.appendTo($(parent_div_selector));
        _btn = $('Обратно на карту');
        //noinspection JSUnresolvedFunction
        _btn.on('click', _onClick);
        _cnt.append(_btn);

        // фиксируем вспомогательный элемент
        _$building_info = $('.building_info');

    };

    _this.show = function () {

        // хардкод - подгоняем под длину анимации, прописанной в css (+200 ms на возможный лаг)
        setTimeout(__show, 1000);

    };
    var __show = function () {
        // фиксируем
        var building_info_top = _$building_info.offset().top;
        var building_info_height = _$building_info.height();

        // считаем
        var btn_top = building_info_top + building_info_height;
        var btn_left = _$building_info.offset().left;

        // позиционируем
        _btn.css('top', btn_top + 'px');
        _btn.css('left', btn_left + 'px');

        // показываем
        _btn.css('opacity','1');
        _cnt.css('display', 'block');
    };

    _this.hide = function () {
        _cnt.css('display', 'none');
        _btn.css('opacity', '0');
    }

}
<|endoftext|>


<commit_before>const Promise = require("bluebird");
const fs = Promise.promisifyAll(require('fs'));
const mkdirpAsync = Promise.promisify(require('mkdirp'));
const mkdirpSync = require('mkdirp');
const path = require('path');
const fsExtra = require('fs-extra');

function getFileStoreDir() {
    let base = process.env.MCDIR;
    base = base.split(':')[0];
    if (!base.endsWith('/')) {
        base += '/';
    }
    return base
}

function getFileStoreDirs() {
    let base = process.env.MCDIR;
    return base.split(':');
}

// NOTE: dir for temp uploads should be in same file system
// as dir for file store; a rename is used to position the final
// version of the upload file - this is called at build time;
// ref: line 12 in directories.js
function getTmpUploadDir() {
    let path = getFileStoreDir() + "uploadTmp/";
    mkdirpSync(path);
    return path;
}

// note filesId must be the file record usesid, if this is set
// otherwise, it is the file record id
function* removeFileInStore(fileId) {
    return yield fs.unlinkAsync(datafilePath(fileId));
}

function* removeFileByPath(path) {
    return yield fs.unlinkAsync(path);
}

function datafileDir(fileId) {
    let base = getFileStoreDir();
    let part = fileId.split("-")[1];
    let partA = part.substring(0, 2);
    let partB = part.substring(2);
    return path.join(base, partA, partB);
}

function datafilePath(fileId) {
    let dir = datafileDir(fileId);
    return path.join(dir, fileId);
}

function constructFileDirPath(fileId) {
    let part = fileId.split("-")[1];
    let partA = part.substring(0, 2);
    let partB = part.substring(2);
    return path.join(partA, partB)
}

function datafilePathFromDir(dir, fileId) {
    let fileDir = constructFileDirPath(fileId);
    return path.join(dir, fileDir, fileId);
}

function datafilePathsFromFile(file, orig) {
    let filePaths = [];
    let fileId = file.usesid !== '' ? file.usesid : file.id;
    let dirs = getFileStoreDirs();
    dirs.forEach(d => {
        if (orig) {
            filePaths.push(datafilePathFromDir(d, fileId));
        } else {
            filePaths.push(getPathUsingConversion(d, fileId, file.mediatype.mime));
        }
    });
    return filePaths;
}

function getPathUsingConversion(dir, fileId, mime) {
    let fileDir = constructFileDirPath(fileId);
    if (isConvertedImage(mime)) {
        return path.join(dir, fileDir, '.conversion', fileId + '.jpg');
    } else if (isOfficeDoc(mime)) {
        return path.join(dir, fileDir, '.conversion', fileId + '.pdf');
    } else {
        return path.join(dir, fileDir, fileId);
    }
}

function isOfficeDoc(mime) {
    return (mime === "application/vnd.ms-excel") ||
        (mime === "application/vnd.ms-powerpoint") ||
        (mime === "application/msword") ||
        (mime === "application/vnd.openxmlformats-officedocument.presentationml.presentation") ||
        (mime === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") ||
        (mime === "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
}

function isConvertedImage(mime) {
    switch (mime) {
        case 'image/tiff':
            return true;
        case 'image/x-ms-bmp':
            return true;
        case 'image/bmp':
            return true;
        default:
            return false;
    }
}

function* datafilePathExists(fileId) {
    let path = datafilePath(fileId);
    return yield fsExtra.pathExists(path);
}

function* moveToStore(sourcePath, fileId) {
    let destPath = datafilePath(fileId);
    let destDir = path.dirname(destPath);
    yield mkdirpAsync(destDir);
    yield fsExtra.copy(sourcePath, destPath);
    yield fs.unlinkAsync(sourcePath);
}

function mediaTypeDescriptionsFromMime(mime) {
    // if there is a semi-colen - strip media type of additional information
    let pos = mime.indexOf(';');
    if (pos > -1) {
        mime = mime.substring(pos - 1)
    }
    let description = mediaTypeDescriptions[mime];
    if (!description) {
        description = mime
    }
    return {
        description: description,
        mime: mime,
    }
}

const mediaTypeDescriptions = {
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Spreadsheet",
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "Word",
    "application/vnd.openxmlformats-officedocument.presentationml.presentation": "Presentation",
    "Composite Document File V2 Document, No summary info": "Composite Document File",
    "application/vnd.ms-powerpoint.presentation.macroEnabled.12": "MS-PowerPoint",
    "text/xml": "XML",
    "image/jpeg": "JPEG",
    "application/postscript": "Postscript",
    "image/png": "PNG",
    "application/json": "JSON",
    "image/vnd.ms-modi": "MS-Document Imaging",
    "application/vnd.ms-xpsdocument": "MS-Postscript",
    "image/vnd.radiance": "Radiance",
    "application/vnd.sealedmedia.softseal.pdf": "Softseal PDF",
    "application/vnd.hp-PCL": "PCL",
    "application/xslt+xml": "XSLT",
    "image/gif": "GIF",
    "application/matlab": "Matlab",
    "application/pdf": "PDF",
    "application/xml": "XML",
    "application/vnd.ms-excel": "MS-Excel",
    "image/bmp": "BMP",
    "image/x-ms-bmp": "BMP",
    "image/tiff": "TIFF",
    "image/vnd.adobe.photoshop": "Photoshop",
    "application/pkcs7-signature": "PKCS",
    "image/vnd.dwg": "DWG",
    "application/octet-stream": "Binary",
    "application/rtf": "RTF",
    "text/plain": "Text",
    "application/vnd.ms-powerpoint": "MS-PowerPoint",
    "application/x-troff-man": "TROFF",
    "video/x-ms-wmv": "WMV Video",
    "application/vnd.chemdraw+xml": "ChemDraw",
    "text/html": "HTML",
    "video/mpeg": "MPEG Video",
    "text/csv": "CSV",
    "application/zip": "ZIP",
    "application/msword": "MS-Word",
    "unknown": "Unknown",
};

module.exports = {
    getTmpUploadDir,
    moveToStore,
    datafilePath,
    datafilePathExists,
    removeFileInStore,
    removeFileByPath,
    mediaTypeDescriptionsFromMime,
    datafilePathsFromFile,
    isConvertedImage,
    isOfficeDoc
};<commit_msg>Catch exception when attempting to delete a file<commit_after>const Promise = require("bluebird");
const fs = Promise.promisifyAll(require('fs'));
const mkdirpAsync = Promise.promisify(require('mkdirp'));
const mkdirpSync = require('mkdirp');
const path = require('path');
const fsExtra = require('fs-extra');

function getFileStoreDir() {
    let base = process.env.MCDIR;
    base = base.split(':')[0];
    if (!base.endsWith('/')) {
        base += '/';
    }
    return base
}

function getFileStoreDirs() {
    let base = process.env.MCDIR;
    return base.split(':');
}

// NOTE: dir for temp uploads should be in same file system
// as dir for file store; a rename is used to position the final
// version of the upload file - this is called at build time;
// ref: line 12 in directories.js
function getTmpUploadDir() {
    let path = getFileStoreDir() + "uploadTmp/";
    mkdirpSync(path);
    return path;
}

// note filesId must be the file record usesid, if this is set
// otherwise, it is the file record id
function* removeFileInStore(fileId) {
    try {
        return yield fs.unlinkAsync(datafilePath(fileId));
    } catch (e) {
        return true;
    }
}

function* removeFileByPath(path) {
    return yield fs.unlinkAsync(path);
}

function datafileDir(fileId) {
    let base = getFileStoreDir();
    let part = fileId.split("-")[1];
    let partA = part.substring(0, 2);
    let partB = part.substring(2);
    return path.join(base, partA, partB);
}

function datafilePath(fileId) {
    let dir = datafileDir(fileId);
    return path.join(dir, fileId);
}

function constructFileDirPath(fileId) {
    let part = fileId.split("-")[1];
    let partA = part.substring(0, 2);
    let partB = part.substring(2);
    return path.join(partA, partB)
}

function datafilePathFromDir(dir, fileId) {
    let fileDir = constructFileDirPath(fileId);
    return path.join(dir, fileDir, fileId);
}

function datafilePathsFromFile(file, orig) {
    let filePaths = [];
    let fileId = file.usesid !== '' ? file.usesid : file.id;
    let dirs = getFileStoreDirs();
    dirs.forEach(d => {
        if (orig) {
            filePaths.push(datafilePathFromDir(d, fileId));
        } else {
            filePaths.push(getPathUsingConversion(d, fileId, file.mediatype.mime));
        }
    });
    return filePaths;
}

function getPathUsingConversion(dir, fileId, mime) {
    let fileDir = constructFileDirPath(fileId);
    if (isConvertedImage(mime)) {
        return path.join(dir, fileDir, '.conversion', fileId + '.jpg');
    } else if (isOfficeDoc(mime)) {
        return path.join(dir, fileDir, '.conversion', fileId + '.pdf');
    } else {
        return path.join(dir, fileDir, fileId);
    }
}

function isOfficeDoc(mime) {
    return (mime === "application/vnd.ms-excel") ||
        (mime === "application/vnd.ms-powerpoint") ||
        (mime === "application/msword") ||
        (mime === "application/vnd.openxmlformats-officedocument.presentationml.presentation") ||
        (mime === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") ||
        (mime === "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
}

function isConvertedImage(mime) {
    switch (mime) {
        case 'image/tiff':
            return true;
        case 'image/x-ms-bmp':
            return true;
        case 'image/bmp':
            return true;
        default:
            return false;
    }
}

function* datafilePathExists(fileId) {
    let path = datafilePath(fileId);
    return yield fsExtra.pathExists(path);
}

function* moveToStore(sourcePath, fileId) {
    let destPath = datafilePath(fileId);
    let destDir = path.dirname(destPath);
    yield mkdirpAsync(destDir);
    yield fsExtra.copy(sourcePath, destPath);
    yield fs.unlinkAsync(sourcePath);
}

function mediaTypeDescriptionsFromMime(mime) {
    // if there is a semi-colen - strip media type of additional information
    let pos = mime.indexOf(';');
    if (pos > -1) {
        mime = mime.substring(pos - 1)
    }
    let description = mediaTypeDescriptions[mime];
    if (!description) {
        description = mime
    }
    return {
        description: description,
        mime: mime,
    }
}

const mediaTypeDescriptions = {
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Spreadsheet",
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "Word",
    "application/vnd.openxmlformats-officedocument.presentationml.presentation": "Presentation",
    "Composite Document File V2 Document, No summary info": "Composite Document File",
    "application/vnd.ms-powerpoint.presentation.macroEnabled.12": "MS-PowerPoint",
    "text/xml": "XML",
    "image/jpeg": "JPEG",
    "application/postscript": "Postscript",
    "image/png": "PNG",
    "application/json": "JSON",
    "image/vnd.ms-modi": "MS-Document Imaging",
    "application/vnd.ms-xpsdocument": "MS-Postscript",
    "image/vnd.radiance": "Radiance",
    "application/vnd.sealedmedia.softseal.pdf": "Softseal PDF",
    "application/vnd.hp-PCL": "PCL",
    "application/xslt+xml": "XSLT",
    "image/gif": "GIF",
    "application/matlab": "Matlab",
    "application/pdf": "PDF",
    "application/xml": "XML",
    "application/vnd.ms-excel": "MS-Excel",
    "image/bmp": "BMP",
    "image/x-ms-bmp": "BMP",
    "image/tiff": "TIFF",
    "image/vnd.adobe.photoshop": "Photoshop",
    "application/pkcs7-signature": "PKCS",
    "image/vnd.dwg": "DWG",
    "application/octet-stream": "Binary",
    "application/rtf": "RTF",
    "text/plain": "Text",
    "application/vnd.ms-powerpoint": "MS-PowerPoint",
    "application/x-troff-man": "TROFF",
    "video/x-ms-wmv": "WMV Video",
    "application/vnd.chemdraw+xml": "ChemDraw",
    "text/html": "HTML",
    "video/mpeg": "MPEG Video",
    "text/csv": "CSV",
    "application/zip": "ZIP",
    "application/msword": "MS-Word",
    "unknown": "Unknown",
};

module.exports = {
    getTmpUploadDir,
    moveToStore,
    datafilePath,
    datafilePathExists,
    removeFileInStore,
    removeFileByPath,
    mediaTypeDescriptionsFromMime,
    datafilePathsFromFile,
    isConvertedImage,
    isOfficeDoc
};<|endoftext|>


<commit_before>/**
 * This tiny wrapper file checks for known node flags and appends them
 * when found, before invoking the "real" _babel-node(1) executable.
 */

import getV8Flags from "v8flags";
import path from "path";

let args = [path.join(__dirname, "_babel-node")];

let babelArgs = process.argv.slice(2);
let userArgs;

// separate node arguments from script arguments
const argSeparator = babelArgs.indexOf("--");
if (argSeparator > -1) {
  userArgs = babelArgs.slice(argSeparator); // including the  --
  babelArgs = babelArgs.slice(0, argSeparator);
}

/**
 * Replace dashes with underscores in the v8Flag name
 * Also ensure that if the arg contains a value (e.g. --arg=true)
 * that only the flag is returned.
 */
function getNormalizedV8Flag(arg) {
  const matches = arg.match(/--(.+)/);

  if (matches) {
    return `--${matches[1].replace(/-/g, "_")}`;
  }

  return arg;
}

getV8Flags(function(err, v8Flags) {
  babelArgs.forEach(function(arg) {
    const flag = arg.split("=")[0];

    switch (flag) {
      case "-d":
        args.unshift("--debug");
        break;

      case "debug":
      case "--debug":
      case "--debug-brk":
      case "--inspect":
        args.unshift(arg);
        break;

      case "-gc":
        args.unshift("--expose-gc");
        break;

      case "--nolazy":
        args.unshift(flag);
        break;

      default:
        if (
          v8Flags.indexOf(getNormalizedV8Flag(flag)) >= 0 ||
          arg.indexOf("--trace") === 0
        ) {
          args.unshift(arg);
        } else {
          args.push(arg);
        }
        break;
    }
  });

  // append arguments passed after --
  if (argSeparator > -1) {
    args = args.concat(userArgs);
  }

  try {
    const kexec = require("kexec");
    kexec(process.argv[0], args);
  } catch (err) {
    if (err.code !== "MODULE_NOT_FOUND") throw err;

    const child_process = require("child_process");
    const proc = child_process.spawn(process.argv[0], args, {
      stdio: "inherit",
    });
    proc.on("exit", function(code, signal) {
      process.on("exit", function() {
        if (signal) {
          process.kill(process.pid, signal);
        } else {
          process.exit(code);
        }
      });
    });
  }
});
<commit_msg>Reinstate `--inspect-brk`, lost when making babel-node standalone (#7423) [skip ci]<commit_after>/**
 * This tiny wrapper file checks for known node flags and appends them
 * when found, before invoking the "real" _babel-node(1) executable.
 */

import getV8Flags from "v8flags";
import path from "path";

let args = [path.join(__dirname, "_babel-node")];

let babelArgs = process.argv.slice(2);
let userArgs;

// separate node arguments from script arguments
const argSeparator = babelArgs.indexOf("--");
if (argSeparator > -1) {
  userArgs = babelArgs.slice(argSeparator); // including the  --
  babelArgs = babelArgs.slice(0, argSeparator);
}

/**
 * Replace dashes with underscores in the v8Flag name
 * Also ensure that if the arg contains a value (e.g. --arg=true)
 * that only the flag is returned.
 */
function getNormalizedV8Flag(arg) {
  const matches = arg.match(/--(.+)/);

  if (matches) {
    return `--${matches[1].replace(/-/g, "_")}`;
  }

  return arg;
}

getV8Flags(function(err, v8Flags) {
  babelArgs.forEach(function(arg) {
    const flag = arg.split("=")[0];

    switch (flag) {
      case "-d":
        args.unshift("--debug");
        break;

      case "debug":
      case "--debug":
      case "--debug-brk":
      case "--inspect":
      case "--inspect-brk":
        args.unshift(arg);
        break;

      case "-gc":
        args.unshift("--expose-gc");
        break;

      case "--nolazy":
        args.unshift(flag);
        break;

      default:
        if (
          v8Flags.indexOf(getNormalizedV8Flag(flag)) >= 0 ||
          arg.indexOf("--trace") === 0
        ) {
          args.unshift(arg);
        } else {
          args.push(arg);
        }
        break;
    }
  });

  // append arguments passed after --
  if (argSeparator > -1) {
    args = args.concat(userArgs);
  }

  try {
    const kexec = require("kexec");
    kexec(process.argv[0], args);
  } catch (err) {
    if (err.code !== "MODULE_NOT_FOUND") throw err;

    const child_process = require("child_process");
    const proc = child_process.spawn(process.argv[0], args, {
      stdio: "inherit",
    });
    proc.on("exit", function(code, signal) {
      process.on("exit", function() {
        if (signal) {
          process.kill(process.pid, signal);
        } else {
          process.exit(code);
        }
      });
    });
  }
});
<|endoftext|>


<commit_before>/*
@deploy
@title Search HN Who is hiring?
@input
{
  "content-type" : "application/json"
}
@output
{
  "content-type" : "application/json"
}
*/

var _     = require('underscore')
  , sift  = require('sift')
  ;

module.exports = function(req, res, next) {
  this.request('a7medkamel/tm-data/exec/master/hn/who_is_hiring.js', function(err, httpResponse, body){
    if (err) {
      next(err);
      return;
    }

    var query = req.body;
    if (!query) {
      var qs = req.query['query'];

      if (_.isEmpty(qs)) {
        query = {};
      } else if (_.isString(qs)) {
        query = { text : new RegExp(qs) };
      } else if (_.isArray(qs)) {
        query = { text : new RegExp(qs.join('|')) };
      }
    }

    var jobs = JSON.parse(body);

    var found = _.filter(jobs, function(job){
      if (!job.text) {
        return;
      }

      var text = job.text.toLowerCase();
      return !!_.find(query, function(term){ return text.indexOf(term) != -1; });
    });

    res.send(found);
  })
};<commit_msg>update from oncue.io ui<commit_after>/*
@deploy
@title Search HN Who is hiring?
@input
{
  "content-type" : "application/json"
}
@output
{
  "content-type" : "application/json"
}
*/

var _ = require('underscore');

module.exports = function(req, res, next) {
  var query = req.param('query');

  this.request('a7medkamel/tm-data/exec/master/hn/who_is_hiring.js', function(err, httpResponse, body){
    if (err) {
      next(err);
      return;
    }

    if (_.isEmpty(query)) {
      query = [];
    }

    if (_.isString(query)) {
      query = [query]
    }

    var jobs = JSON.parse(body);

    var found = _.filter(jobs, function(job){
      if (!job.text) {
        return;
      }

      var text = job.text.toLowerCase();
      return !!_.find(query, function(term){ return text.indexOf(term) != -1; });
    });

    res.send(found);
  })
};<|endoftext|>


<commit_before>// 1. Write two functions, each which return a fixed number (different from each other) when called.

function foo() {
  return 3;
}

foo(); // 3

function bar() {
  return 4;
}

bar(); // 3

// 2. Write an `add(..)` function that takes two numbers and adds them and returns the result.
//    Call `add(..)` with the results of your two functions from (1) and print the result to the console.

function add(a, b) {
  return a + b;
}

add(foo(), bar()); // 7

// 3. Write an `add2(..)` that takes two functions instead of two numbers,
//    and it calls those two functions and then sends those values to `add(..)`,
//    just like you did in (2) above.

function add2(fn1, fn2) {
  return add(fn1(), fn2());
}

add2(foo, bar); // 7

// 4. Replace your two functions from (1) with a single function
//    that takes a value and returns a function back,
//    where the returned function will return the value when it's called.

function foo2(value) {
  return function bar2() {
    return value;
  };
}

foo2(3)(); // 3

// 5. Write an `addn(..)` that can take an array of 2 or more functions, and using only `add2(..)`,
//    adds them together. Try it with a loop. Try it without a loop (recursion).
//    Try it with built-in array functional helpers (map/reduce).

// LOOP
function addn(arrayOfFns) {
  return add2(arrayOfFns[0], arrayOfFns[1]);
}

var arrayOfFns = [foo, bar, baz];

addn(arrayOfFns); // 7

function baz() {
  return 7;
}

var arrayOfFns = [foo, bar, baz];

addn(arrayOfFns); // 14

// RECURSION<commit_msg>update exercise<commit_after>// 1. Write two functions, each which return a fixed number (different from each other) when called.

function foo() {
  return 3;
}

foo(); // 3

function bar() {
  return 4;
}

bar(); // 3

// 2. Write an `add(..)` function that takes two numbers and adds them and returns the result.
//    Call `add(..)` with the results of your two functions from (1) and print the result to the console.

function add(a, b) {
  return a + b;
}

add(foo(), bar()); // 7

// 3. Write an `add2(..)` that takes two functions instead of two numbers,
//    and it calls those two functions and then sends those values to `add(..)`,
//    just like you did in (2) above.

function add2(fn1, fn2) {
  return add(fn1(), fn2());
}

add2(foo, bar); // 7

// 4. Replace your two functions from (1) with a single function
//    that takes a value and returns a function back,
//    where the returned function will return the value when it's called.

function foo2(value) {
  return function bar2() {
    return value;
  };
}

foo2(3)(); // 3

// 5. Write an `addn(..)` that can take an array of 2 or more functions, and using only `add2(..)`,
//    adds them together. Try it with a loop. Try it without a loop (recursion).
//    Try it with built-in array functional helpers (map/reduce).

// LOOP

// RECURSION

function foo(num) {
  return function() {
    return num;
  }
}

three = foo(3);
four = foo(4);
five = foo(5);

function add(a, b) {
  return a + b;
}

function addFn(fn1, fn2) {
  return add(fn1(), fn2());
}

function addN(car, ...cdr) {
  if (cdr.length == 1) return car() + cdr[0]();

  var fn = cdr.pop()
  sumFn = function() {
    return addFn(car, fn);
  }
  return addN(sumFn, ...cdr);
}

addN(three, four, five);<|endoftext|>


<commit_before>if("undefined"==typeof OGX)var OGX=function(){};OGX.prototype.FlexCalendarDayRenderer=function(e){"use strict";function r(e,r,a){for(var n,d=0;d<u[e][r].length;d++)if(n=u[e][r][d],n.__id__===a)return n;return!1}function a(e,r){var a={},n=c.max_hour-c.min_hour+1,d=e.height(),_=d/n,l=100*_/d,t=r.start.split(":"),o=Number(t[0])+Number(t[1])/60-c.min_hour;return a.h_pc=Math.round(l*(r.length/60)*100)/100,a.h=Math.round(_*(r.length/60)*100)/100,a.y_pc=Math.round(o*l*100)/100,a.y=Math.round(o*_*100)/100,a}function n(e,r){return Math.max(e.top,r.top)<Math.min(e.bottom,r.bottom)}function d(e,r,d,_){var l,t,o,i,c,s=a(e,r),x=e.children(".ogx_flex_calendar_day_renderer_column").length,u=!1;if(0===x)e.html('

'),u=e.children(".ogx_flex_calendar_day_renderer_column:first");else{for(var h=0;h<x;h++){if(c=!1,l=e.children(".ogx_flex_calendar_day_renderer_column:eq("+h+")").children(".ogx_flex_calendar_day_renderer_apt").length,l>0){for(var y=0;y<l;y++)if(t=e.children(".ogx_flex_calendar_day_renderer_column:eq("+h+")").children(".ogx_flex_calendar_day_renderer_apt:eq("+y+")"),o=t.position().top,i=t.height(),n({top:s.y,bottom:s.y+s.h},{top:o,bottom:o+i})){c=!0;break}if(!c){u=e.children(".ogx_flex_calendar_day_renderer_column:eq("+h+")");break}}if(u)break}u||(e.append('

'),u=e.children(".ogx_flex_calendar_day_renderer_column:last"))}r.__id__=f,u.append('

'+r.start+''+r.label+"

"),f++}function _(e,r,a,n){e.html('

'),l(e);var _=e.find(".ogx_flex_calendar_day_renderer_columns:first");for(var t in r)for(var o=0;o<r[t].length;o++)d(_,r[t][o],a,n.categories)}function l(e){for(var r=e.find(".ogx_flex_calendar_day_renderer_hours:first"),a="",n=c.min_hour;n<c.max_hour+1;n++)a+='
'+n+"
";r.html(a)}function t(){for(var e in s)c.hasOwnProperty(e)||(c[e]=s[e])}function o(){return"undefined"==typeof moment?void console.log("%c CRITICAL ERROR - moment.js not found! ","background:#222; color: #FF0000"):void t()}"undefined"!=typeof e&&null!==e||(e={});var i,c=e,s={min_hour:6,max_hour:22},f=1,x=!1,u={};this.render=function(e,r,a){"undefined"==typeof a&&(a=moment()),moment.isMoment(a)||(a=moment(a));var n=a.format("YYYY-MM-DD");u[n]=OGX.FlexCalendarDataHelper.getDay(a,r),i=$(e),_(i,u[n],n,r),this.listenApt(!0)},this.listenApt=function(e){e?i.on("click",".ogx_flex_calendar_day_renderer_apt",function(e){return $(this).hasClass("ogx_flex_calendar_day_renderer_selected_apt")?($(this).removeClass("ogx_flex_calendar_day_renderer_selected_apt"),i.trigger(OGX.FlexCalendarDayRenderer.UNSELECT,r(x.data("date"),x.data("time"),Number(x.data("id")))),void(x=null)):(x&&x.removeClass("ogx_flex_calendar_day_renderer_selected_apt"),$(this).addClass("ogx_flex_calendar_day_renderer_selected_apt"),x=$(this),void i.trigger(OGX.FlexCalendarDayRenderer.SELECT,r(x.data("date"),x.data("time"),Number(x.data("id")))))}):i.off("click",".ogx_flex_calendar_day_renderer_apt")},this.destroy=function(){this.listenApt(!1)},o()},OGX.FlexCalendarDayRenderer=function(e){"use strict";return new OGX.prototype.FlexCalendarDayRenderer(e)},OGX.FlexCalendarDayRenderer.SELECT="FlexCalendarDayRendererSelect",OGX.FlexCalendarDayRenderer.UNSELECT="FlexCalendarDayRendererUnselect";<commit_msg><commit_after>if("undefined"==typeof OGX)var OGX=function(){};OGX.prototype.FlexCalendarDayRenderer=function(e){"use strict";function r(e,r,a){for(var n,d=0;d<u[e][r].length;d++)if(n=u[e][r][d],n.__id__===a)return n;return!1}function a(e,r){var a={},n=c.max_hour-c.min_hour+1,d=e.height(),_=d/n,t=100*_/d,l=r.start.split(":"),o=Number(l[0])+Number(l[1])/60-c.min_hour;return a.h_pc=Math.round(t*(r.length/60)*100)/100,a.h=Math.round(_*(r.length/60)*100)/100,a.y_pc=Math.round(o*t*100)/100,a.y=Math.round(o*_*100)/100,a}function n(e,r){return Math.max(e.top,r.top)<Math.min(e.bottom,r.bottom)}function d(e,r,d,_){var t,l,o,i,c,s=a(e,r),x=e.children(".ogx_flex_calendar_day_renderer_column").length,u=!1;if(0===x)e.html('

'),u=e.children(".ogx_flex_calendar_day_renderer_column:first");else{for(var h=0;h<x;h++){if(c=!1,t=e.children(".ogx_flex_calendar_day_renderer_column:eq("+h+")").children(".ogx_flex_calendar_day_renderer_apt").length,t>0){for(var m=0;m<t;m++)if(l=e.children(".ogx_flex_calendar_day_renderer_column:eq("+h+")").children(".ogx_flex_calendar_day_renderer_apt:eq("+m+")"),o=l.position().top,i=l.height(),n({top:s.y,bottom:s.y+s.h},{top:o,bottom:o+i})){c=!0;break}if(!c){u=e.children(".ogx_flex_calendar_day_renderer_column:eq("+h+")");break}}if(u)break}u||(e.append('

'),u=e.children(".ogx_flex_calendar_day_renderer_column:last"))}r.__id__=f,u.append('

'+r.start+''+r.label+"

"),f++}function _(e,r,a,n){e.html('

'),t(e);var _=e.find(".ogx_flex_calendar_day_renderer_columns:first");for(var l in r)for(var o=0;o<r[l].length;o++)d(_,r[l][o],a,n.categories)}function t(e){for(var r=e.find(".ogx_flex_calendar_day_renderer_hours:first"),a="",n=c.min_hour;n<c.max_hour+1;n++)a+='
'+n+"
";r.html(a)}function l(){for(var e in s)c.hasOwnProperty(e)||(c[e]=s[e])}function o(){return"undefined"==typeof moment?void console.log("%c CRITICAL ERROR - moment.js not found! ","background:#222; color: #FF0000"):void l()}"undefined"!=typeof e&&null!==e||(e={});var i,c=e,s={min_hour:6,max_hour:22},f=1,x=!1,u={};this.render=function(e,r,a){"undefined"==typeof a&&(a=moment()),moment.isMoment(a)||(a=moment(a));var n=a.format("YYYY-MM-DD");u[n]=OGX.FlexCalendarDataHelper.getDay(a,r),i=$(e),_(i,u[n],n,r),this.listenApt(!0)},this.update=function(e,r,a){"undefined"==typeof a&&(a=moment()),moment.isMoment(a)||(a=moment(a));var n=a.format("YYYY-MM-DD");u[n]=OGX.FlexCalendarDataHelper.getDay(a,r),i=$(e),_(i,u[n],n,r)},this.listenApt=function(e){e?i.on("click",".ogx_flex_calendar_day_renderer_apt",function(e){return $(this).hasClass("ogx_flex_calendar_day_renderer_selected_apt")?($(this).removeClass("ogx_flex_calendar_day_renderer_selected_apt"),i.trigger(OGX.FlexCalendarDayRenderer.UNSELECT,r(x.data("date"),x.data("time"),Number(x.data("id")))),void(x=null)):(x&&x.removeClass("ogx_flex_calendar_day_renderer_selected_apt"),$(this).addClass("ogx_flex_calendar_day_renderer_selected_apt"),x=$(this),void i.trigger(OGX.FlexCalendarDayRenderer.SELECT,r(x.data("date"),x.data("time"),Number(x.data("id")))))}):i.off("click",".ogx_flex_calendar_day_renderer_apt")},this.destroy=function(){this.listenApt(!1)},o()},OGX.FlexCalendarDayRenderer=function(e){"use strict";return new OGX.prototype.FlexCalendarDayRenderer(e)},OGX.FlexCalendarDayRenderer.SELECT="FlexCalendarDayRendererSelect",OGX.FlexCalendarDayRenderer.UNSELECT="FlexCalendarDayRendererUnselect";<|endoftext|>


<commit_before>(function (angular) {

     var module = angular.module('dynamic-form', ['ng']);

     module.directive(
         'dynamicTableForm',
         ['$compile', '$parse', function ($compile, $parse) {
              return {
                  restrict: 'EA',
                  priority: 1000,
                  terminal: true,
                  scope: {
                      fieldsExpr: '&fields',
                      dataExpr: '&data'
                  },
                  compile: function (element, attr, linker) {
                      return function ($scope, $element, $attr) {

                          var typeTemplates = {};

                          angular.forEach(
                              $element.children(),
                              function (childElem) {

                                  if (! childElem.getAttribute('dynamic-field-type')) {
                                      return;
                                  }

                                  childElem = angular.element(childElem);

                                  var typeName = childElem.attr('dynamic-field-type');
                                  typeTemplates[typeName] = childElem;

                              }
                          );

                          $element.html('');

                          function linkFunctionForFieldType(type) {
                              var match = type.match(/^(\w+)\<.*\>$/);
                              if (match) {
                                  // it's a collection type.
                                  // TODO: implement collection types.
                                  return function () {};
                              }
                              else {
                                  var template = typeTemplates[type];
                                  if (template) {
                                      return $compile(template);
                                  }
                                  else {
                                      // unknown type, so no-op.
                                      return function () {};
                                  }
                              }
                          }

                          function buildRows(fields, oldFields) {
                              if (fields === oldFields) {
                                  return;
                              }

                              // FIXME: Need to remember what scopes we created here so that
                              // if we get run again we can destroy them all before we make
                              // new ones.

                              // empty the table in case we've already got some stuff in there
                              $element.html('');

                              var data = $scope.dataExpr($scope);

                              angular.forEach(
                                  fields,
                                  function (field) {

                                      var rowElem = angular.element(
                                          '

'
                                      );
                                      var captionElem = angular.element(
                                          ''
                                      );
                                      var bodyElem = angular.element(
                                          '

'
                                      );
                                      rowElem.append(captionElem);
                                      rowElem.append(bodyElem);

                                      function updateCaption(newCaption) {
                                          captionElem.text(field.caption);
                                      }

                                      function updateFieldType(newType) {
                                          bodyElem.html('');
                                          var fieldScope = $scope.$new(true);
                                          fieldScope.config = field;

                                          var modelGet = $parse(field.model);
                                          var modelSet = modelGet.assign;

                                          var lastValue = fieldScope.value = modelGet(data);

                                          // make fieldScope.value an alias of the model
                                          $scope.$watch(
                                              function () {
                                                  var parentValue = modelGet(data);
                                                  if (parentValue !== fieldScope.value) {
                                                      // out of sync and need to copy
                                                      if (parentValue !== lastValue) {
                                                          // parent changed and has precedence
                                                          lastValue = fieldScope.value = parentValue;
                                                      }
                                                      else {
                                                          // update the parent
                                                          parentValue = lastValue = fieldScope.value;
                                                          modelSet(
                                                              data,
                                                              fieldScope.value
                                                          );
                                                      }
                                                  }
                                                  return parentValue;
                                              }
                                          );
                                          var link = linkFunctionForFieldType(field.type);
                                          link(
                                              fieldScope,
                                              function (clonedElement) {
                                                  bodyElem.append(clonedElement);
                                              }
                                          );
                                      }

                                      $scope.$watch(
                                          function () {
                                              return field.caption;
                                          },
                                          updateCaption
                                      );

                                      $scope.$watch(
                                          function () {
                                              return field.type;
                                          },
                                          updateFieldType
                                      );

                                      $element.append(rowElem);
                                  }
                              );
                          }

                          $scope.$watch(
                              function () {
                                  return $scope.fieldsExpr($scope);
                              },
                              buildRows,
                              true
                          );
                          $scope.$watch(
                              function () {
                                  return $scope.dataExpr($scope);
                              },
                              function () {
                                  buildRows($scope.fieldsExpr($scope));
                              },
                              false
                          );

                      };
                  }
              };
         }]
     );

})(angular);
<commit_msg>Assign a class for each row, named after the model.<commit_after>(function (angular) {

     var module = angular.module('dynamic-form', ['ng']);

     module.directive(
         'dynamicTableForm',
         ['$compile', '$parse', function ($compile, $parse) {
              return {
                  restrict: 'EA',
                  priority: 1000,
                  terminal: true,
                  scope: {
                      fieldsExpr: '&fields',
                      dataExpr: '&data'
                  },
                  compile: function (element, attr, linker) {
                      return function ($scope, $element, $attr) {

                          var typeTemplates = {};

                          angular.forEach(
                              $element.children(),
                              function (childElem) {

                                  if (! childElem.getAttribute('dynamic-field-type')) {
                                      return;
                                  }

                                  childElem = angular.element(childElem);

                                  var typeName = childElem.attr('dynamic-field-type');
                                  typeTemplates[typeName] = childElem;

                              }
                          );

                          $element.html('');

                          function linkFunctionForFieldType(type) {
                              var match = type.match(/^(\w+)\<.*\>$/);
                              if (match) {
                                  // it's a collection type.
                                  // TODO: implement collection types.
                                  return function () {};
                              }
                              else {
                                  var template = typeTemplates[type];
                                  if (template) {
                                      return $compile(template);
                                  }
                                  else {
                                      // unknown type, so no-op.
                                      return function () {};
                                  }
                              }
                          }

                          function buildRows(fields, oldFields) {
                              if (fields === oldFields) {
                                  return;
                              }

                              // FIXME: Need to remember what scopes we created here so that
                              // if we get run again we can destroy them all before we make
                              // new ones.

                              // empty the table in case we've already got some stuff in there
                              $element.html('');

                              var data = $scope.dataExpr($scope);

                              angular.forEach(
                                  fields,
                                  function (field) {

                                      var rowElem = angular.element(
                                          '

'
                                      );
                                      var captionElem = angular.element(
                                          ''
                                      );
                                      var bodyElem = angular.element(
                                          '

'
                                      );
                                      rowElem.append(captionElem);
                                      rowElem.append(bodyElem);

                                      function updateCaption(newCaption) {
                                          captionElem.text(field.caption);
                                      }

                                      function updateFieldType(newType) {
                                          bodyElem.html('');
                                          var fieldScope = $scope.$new(true);
                                          fieldScope.config = field;

                                          rowElem.addClass('control-group--' +
                                              field.model.replace(/([a-z])([A-Z])/g,
                                                  function (m) {
                                                      return m[0] + '-' + m[1];
                                                  }
                                              ).toLowerCase()
                                          );

                                          var modelGet = $parse(field.model);
                                          var modelSet = modelGet.assign;

                                          var lastValue = fieldScope.value = modelGet(data);

                                          // make fieldScope.value an alias of the model
                                          $scope.$watch(
                                              function () {
                                                  var parentValue = modelGet(data);
                                                  if (parentValue !== fieldScope.value) {
                                                      // out of sync and need to copy
                                                      if (parentValue !== lastValue) {
                                                          // parent changed and has precedence
                                                          lastValue = fieldScope.value = parentValue;
                                                      }
                                                      else {
                                                          // update the parent
                                                          parentValue = lastValue = fieldScope.value;
                                                          modelSet(
                                                              data,
                                                              fieldScope.value
                                                          );
                                                      }
                                                  }
                                                  return parentValue;
                                              }
                                          );
                                          var link = linkFunctionForFieldType(field.type);
                                          link(
                                              fieldScope,
                                              function (clonedElement) {
                                                  bodyElem.append(clonedElement);
                                              }
                                          );
                                      }

                                      $scope.$watch(
                                          function () {
                                              return field.caption;
                                          },
                                          updateCaption
                                      );

                                      $scope.$watch(
                                          function () {
                                              return field.type;
                                          },
                                          updateFieldType
                                      );

                                      $element.append(rowElem);
                                  }
                              );
                          }

                          $scope.$watch(
                              function () {
                                  return $scope.fieldsExpr($scope);
                              },
                              buildRows,
                              true
                          );
                          $scope.$watch(
                              function () {
                                  return $scope.dataExpr($scope);
                              },
                              function () {
                                  buildRows($scope.fieldsExpr($scope));
                              },
                              false
                          );

                      };
                  }
              };
         }]
     );

})(angular);
<|endoftext|>


<commit_before>#! /usr/bin/env node

/* A script for converting javascript challenge code into JSON.
  * Each challenge should have sections marked with comments '/// keyword:',
  * For example:
  *   /// solution:
  *   function MySolution()...
  *
  *   /// tests:
  *   assert(MySolution(2) === 3)...
  *
  * */

// TODO: fix script to remove empty string at end of the last property (i.e., test),
// otherwise an empty test case is added which is problematic.

const commandLineArgs = require('command-line-args');
const fs = require('fs');
const acorn = require('acorn');
const mongoose = require('mongoose');

const optionDefinitions = [
  { name: 'force', type: Boolean, descr: 'Overwrite output files forcefully.' },
  { name: 'help', alias: 'h', type: Boolean, descr: 'Print help message' },
  { name: 'infile', alias: 'f', type: String, multiple: true, descr: 'Input files' },
  { name: 'outfile', alias: 'o', type: String, descr: 'Output JSON file' },
  { name: 'verbose', alias: 'v', type: Boolean, descr: 'Run in verbose mode' }
];

// Regexp definitions for the script
const re = {
  lineComment: /^\/\/\//,
  lineCommentStartsWithProp: /^\/\/\/\s+(\w+):/,
  lineCommentWithProp: /^\/\/\/\s+(\w+):\s*$/,
  lineCommentWithPropAndText: /^\/\/\/\s+(\w+):\s*(\S.*)$/,
  lineCommentWithText: /^\/\/\/\s(.*)$/,
  endComment: /^\/\/\/\s+end\s+$/
};

const opts = commandLineArgs(optionDefinitions);

if (opts.help) {
  usage(0);
}

const expectedProps = {
  title: String,
  type: String,
  description: String,
  challengeSeed: 'Code',
  solutions: 'Code',
  tests: 'Code'
};

const optionalProps = {
  difficulty: Number,
  bencmark: 'Code',
  categories: String,
  head: 'Code',
  tail: 'Code',
  images: String,
  naive: 'Code',
  id: String
};

const allProps = Object.assign({}, expectedProps, optionalProps);

if (!opts.infile || opts.infile.length === 0) {
  console.error('Error. No input files were given.');
  usage(1);
}

const propParser = {
  state: 'IDLE',
  currFile: null,
  prop: null,
  propValue: [],
  files: {},
  continuedComments: false
};

opts.infile.forEach(file => {
  processFile(propParser, file, expectedProps);
});

const result = formatResult(propParser.files);

printToOutput(result);

//---------------------------------------------------------------------------
// HELPER FUNCTIONS
//---------------------------------------------------------------------------

function processFile(parser, file, props) {
  const buffer = fs.readFileSync(file);
  parser.currFile = file;
  parser.files[file] = {};
  checkFileSyntax(buffer);

  const lines = buffer.toString().split('\n');
  lines.forEach(line => {
    processLine(parser, line);
  });

  if (parser.propValue.length > 0) {
    finishCurrProp(parser);
  }

  verifyExpectedProps(parser, file, props);
}

/* Checks the code syntax in given buffer using acorn. */
function checkFileSyntax(buffer) {
  try {
    acorn.parse(buffer);
  }
  catch (err) {
    console.error(`Parsing failed: ${err}`);
    process.exit(1);
  }
}

/* Processes one line with regex and extracts prop values. */
function processLine(parser, line) {
  if (parser.continuedComments && !re.lineComment.test(line)) {
    finishCurrProp(parser);
    return;
  }
  parser.continuedComments = false;

  let propLegal = false;
  if (re.lineCommentStartsWithProp.test(line)) {
    const matches = line.match(re.lineCommentStartsWithProp);
    propLegal = isPropLegal(matches[1]);
  }

  if (propLegal && re.lineCommentWithProp.test(line)) {
    const matches = line.match(re.lineCommentWithProp);
    if (parser.prop !== null) {
      finishCurrProp(parser);
    }
    parser.prop = matches[1];
  }
  else if (propLegal && re.lineCommentWithPropAndText.test(line)) {
    const matches = line.match(re.lineCommentWithPropAndText);
    if (parser.prop !== null) {
      finishCurrProp(parser);
    }
    parser.prop = matches[1];
    parser.propValue.push(matches[2]);
    finishCurrProp(parser);
  }
  else if (re.lineCommentWithText.test(line)) {
    const matches = line.match(re.lineCommentWithText);
    parser.propValue.push(matches[1]);
    parser.continuedComments = true;
  }
  else if (re.endComment.test(line)) {
    finishCurrProp(parser);
  }
  else if (parser.prop !== null) {
    parser.propValue.push(line);
    // if prop is solutions, combine strings into one string with newline
    if (parser.prop === 'solutions' || parser.prop === 'naive') {
      if (parser.propValue.length > 1) {
        parser.propValue = [parser.propValue.join('\n')];
      }
    }
  }
}

/* Adds current property value into the parser for the current file being processed. Resets
 * the prop value after this. */
function finishCurrProp(parser) {
  // shave off ending empty string from arrays:
  if (parser.propValue.slice(-1).toString() === '') {
    parser.propValue.splice(-1);
  }

  let newPropVal;

  // keep solutions string in an array
  if (parser.prop === 'solutions') {
    newPropVal = parser.propValue;
  }
  else if (parser.propValue.length === 1) {
    newPropVal = parser.propValue[0] || parser.propValue;
  }
  else newPropVal = parser.propValue;

  if (typeof parser.files[parser.currFile][parser.prop] === 'undefined') {
    parser.files[parser.currFile][parser.prop] = newPropVal;
    parser.files[parser.currFile][parser.prop].num = 1;
  }
  else if (typeof parser.files[parser.currFile][parser.prop] === 'string') {
    const oldValue = parser.files[parser.currFile][parser.prop];
    parser.files[parser.currFile][parser.prop] = [oldValue, newPropVal];
    parser.files[parser.currFile][parser.prop].num = 2;
  }
  else if (typeof parser.files[parser.currFile][parser.prop] === 'object') {
    if (parser.files[parser.currFile][parser.prop].num === 1) {
      // Need to wrap the value in an array first.
      parser.files[parser.currFile][parser.prop] = [
        parser.files[parser.currFile][parser.prop],
        newPropVal
      ];
      parser.files[parser.currFile][parser.prop].num = 2;
    }
    else {
      parser.files[parser.currFile][parser.prop].push(newPropVal);
      parser.files[parser.currFile][parser.prop].num += 1;
    }
  }

  parser.propValue = [];
  parser.prop = null;
}

/* Verifies that the parsed file contains expected props like 'solution' etc.*/
function verifyExpectedProps(parser, file, props) {
  Object.keys(props).forEach(prop => {
    if (parser.files[file][prop] === undefined) {
      console.warn(`Prop ${prop} missing from file ${file}`);
    }

    // Add unique IDs to files, unless they already exist
    if (!parser.files[file].id) {
      const id = mongoose.Types.ObjectId();
      parser.files[file].id = id;
      fs.appendFileSync(file, `/// id: ${id}\n`);
    }
  });
}

/* Formats the result as JSON. */
function formatResult(parsedFiles) {
  const challenges = Object.keys(parsedFiles).map(filename =>
    parsedFiles[filename]
  );

  const finalFormat = {
    name: 'ArcadeMode Interview Questions',
    order: '',
    time: '',
    helpRoom: '',
    challenges
  };

  return JSON.stringify(finalFormat, null, 2);
}

/* Prints the results to given output file. */
function printToOutput (res) {
  if (opts.outfile) {
    if (!fs.existsSync(opts.outfile) || opts.force) {
      fs.writeFileSync(opts.outfile, res);
    }
  }
  else {
    console.log(res);
  }
}

/* Prints the usage of the script and exits. */
function usage(exitCode = 0) {
  console.log('Usage: bin/js2json_challenges.js [opts] -f <files>+\n');
  optionDefinitions.forEach(opt => {
    if (opt.alias) {
      console.log(`\t--${opt.name},-${opt.alias}\t- ${opt.descr}`);
    }
    else {
      console.log(`\t--${opt.name}\t\t- ${opt.descr}`);
    }
  });
  process.exit(exitCode);
}

function isPropLegal(propName) {
  return allProps.hasOwnProperty(propName);
}
<commit_msg>Added feature to skip some challenges if /// WIP is included in the file.<commit_after>#! /usr/bin/env node

/* A script for converting javascript challenge code into JSON.
  * Each challenge should have sections marked with comments '/// keyword:',
  * For example:
  *   /// solution:
  *   function MySolution()...
  *
  *   /// tests:
  *   assert(MySolution(2) === 3)...
  *
  * */

// TODO: fix script to remove empty string at end of the last property (i.e., test),
// otherwise an empty test case is added which is problematic.

const commandLineArgs = require('command-line-args');
const fs = require('fs');
const acorn = require('acorn');
const mongoose = require('mongoose');

const optionDefinitions = [
  { name: 'force', type: Boolean, descr: 'Overwrite output files forcefully.' },
  { name: 'help', alias: 'h', type: Boolean, descr: 'Print help message' },
  { name: 'infile', alias: 'f', type: String, multiple: true, descr: 'Input files' },
  { name: 'outfile', alias: 'o', type: String, descr: 'Output JSON file' },
  { name: 'verbose', alias: 'v', type: Boolean, descr: 'Run in verbose mode' }
];

// Regexp definitions for the script
const re = {
  lineComment: /^\/\/\//,
  lineCommentStartsWithProp: /^\/\/\/\s+(\w+):/,
  lineCommentWithProp: /^\/\/\/\s+(\w+):\s*$/,
  lineCommentWithPropAndText: /^\/\/\/\s+(\w+):\s*(\S.*)$/,
  lineCommentWithText: /^\/\/\/\s(.*)$/,
  endComment: /^\/\/\/\s+end\s+$/,
  workInProgress: /^\/\/\/\s+WIP/i
};

const opts = commandLineArgs(optionDefinitions);

if (opts.help) {
  usage(0);
}

const expectedProps = {
  title: String,
  type: String,
  description: String,
  challengeSeed: 'Code',
  solutions: 'Code',
  tests: 'Code'
};

const optionalProps = {
  difficulty: Number,
  bencmark: 'Code',
  categories: String,
  head: 'Code',
  tail: 'Code',
  images: String,
  naive: 'Code',
  id: String
};

const allProps = Object.assign({}, expectedProps, optionalProps);

if (!opts.infile || opts.infile.length === 0) {
  console.error('Error. No input files were given.');
  usage(1);
}

const propParser = {
  state: 'IDLE',
  currFile: null,
  prop: null,
  propValue: [],
  files: {},
  continuedComments: false
};

opts.infile.forEach(file => {
  processFile(propParser, file, expectedProps);
});

const result = formatResult(propParser.files);

printToOutput(result);

//---------------------------------------------------------------------------
// HELPER FUNCTIONS
//---------------------------------------------------------------------------

function processFile(parser, file, props) {
  const buffer = fs.readFileSync(file);
  parser.currFile = file;
  parser.files[file] = {};
  checkFileSyntax(buffer);

  const lines = buffer.toString().split('\n');
  if (!workInProgress(lines)) {
    lines.forEach(line => {
      processLine(parser, line);
    });

    if (parser.propValue.length > 0) {
      finishCurrProp(parser);
    }

    verifyExpectedProps(parser, file, props);
  }
  else {
    console.log('Skipping WIP file ' + file);
  }
}

/* Checks the code syntax in given buffer using acorn. */
function checkFileSyntax(buffer) {
  try {
    acorn.parse(buffer);
  }
  catch (err) {
    console.error(`Parsing failed: ${err}`);
    process.exit(1);
  }
}

/* Processes one line with regex and extracts prop values. */
function processLine(parser, line) {
  if (parser.continuedComments && !re.lineComment.test(line)) {
    finishCurrProp(parser);
    return;
  }
  parser.continuedComments = false;

  let propLegal = false;
  if (re.lineCommentStartsWithProp.test(line)) {
    const matches = line.match(re.lineCommentStartsWithProp);
    propLegal = isPropLegal(matches[1]);
  }

  if (propLegal && re.lineCommentWithProp.test(line)) {
    const matches = line.match(re.lineCommentWithProp);
    if (parser.prop !== null) {
      finishCurrProp(parser);
    }
    parser.prop = matches[1];
  }
  else if (propLegal && re.lineCommentWithPropAndText.test(line)) {
    const matches = line.match(re.lineCommentWithPropAndText);
    if (parser.prop !== null) {
      finishCurrProp(parser);
    }
    parser.prop = matches[1];
    parser.propValue.push(matches[2]);
    finishCurrProp(parser);
  }
  else if (re.lineCommentWithText.test(line)) {
    const matches = line.match(re.lineCommentWithText);
    parser.propValue.push(matches[1]);
    parser.continuedComments = true;
  }
  else if (re.endComment.test(line)) {
    finishCurrProp(parser);
  }
  else if (parser.prop !== null) {
    parser.propValue.push(line);
    // if prop is solutions, combine strings into one string with newline
    if (parser.prop === 'solutions' || parser.prop === 'naive') {
      if (parser.propValue.length > 1) {
        parser.propValue = [parser.propValue.join('\n')];
      }
    }
  }
}

/* Adds current property value into the parser for the current file being processed. Resets
 * the prop value after this. */
function finishCurrProp(parser) {
  // shave off ending empty string from arrays:
  if (parser.propValue.slice(-1).toString() === '') {
    parser.propValue.splice(-1);
  }

  let newPropVal;

  // keep solutions string in an array
  if (parser.prop === 'solutions') {
    newPropVal = parser.propValue;
  }
  else if (parser.propValue.length === 1) {
    newPropVal = parser.propValue[0] || parser.propValue;
  }
  else newPropVal = parser.propValue;

  if (typeof parser.files[parser.currFile][parser.prop] === 'undefined') {
    parser.files[parser.currFile][parser.prop] = newPropVal;
    parser.files[parser.currFile][parser.prop].num = 1;
  }
  else if (typeof parser.files[parser.currFile][parser.prop] === 'string') {
    const oldValue = parser.files[parser.currFile][parser.prop];
    parser.files[parser.currFile][parser.prop] = [oldValue, newPropVal];
    parser.files[parser.currFile][parser.prop].num = 2;
  }
  else if (typeof parser.files[parser.currFile][parser.prop] === 'object') {
    if (parser.files[parser.currFile][parser.prop].num === 1) {
      // Need to wrap the value in an array first.
      parser.files[parser.currFile][parser.prop] = [
        parser.files[parser.currFile][parser.prop],
        newPropVal
      ];
      parser.files[parser.currFile][parser.prop].num = 2;
    }
    else {
      parser.files[parser.currFile][parser.prop].push(newPropVal);
      parser.files[parser.currFile][parser.prop].num += 1;
    }
  }

  parser.propValue = [];
  parser.prop = null;
}

/* Verifies that the parsed file contains expected props like 'solution' etc.*/
function verifyExpectedProps(parser, file, props) {
  Object.keys(props).forEach(prop => {
    if (parser.files[file][prop] === undefined) {
      console.warn(`Prop ${prop} missing from file ${file}`);
    }

    // Add unique IDs to files, unless they already exist
    if (!parser.files[file].id) {
      const id = mongoose.Types.ObjectId();
      parser.files[file].id = id;
      fs.appendFileSync(file, `/// id: ${id}\n`);
    }
  });
}

/* Formats the result as JSON. */
function formatResult(parsedFiles) {
  const challenges = Object.keys(parsedFiles).map(filename =>
    parsedFiles[filename]
  );

  const finalFormat = {
    name: 'ArcadeMode Interview Questions',
    order: '',
    time: '',
    helpRoom: '',
    challenges
  };

  return JSON.stringify(finalFormat, null, 2);
}

/* Prints the results to given output file. */
function printToOutput (res) {
  if (opts.outfile) {
    if (!fs.existsSync(opts.outfile) || opts.force) {
      fs.writeFileSync(opts.outfile, res);
    }
  }
  else {
    console.log(res);
  }
}

/* Prints the usage of the script and exits. */
function usage(exitCode = 0) {
  console.log('Usage: bin/js2json_challenges.js [opts] -f <files>+\n');
  optionDefinitions.forEach(opt => {
    if (opt.alias) {
      console.log(`\t--${opt.name},-${opt.alias}\t- ${opt.descr}`);
    }
    else {
      console.log(`\t--${opt.name}\t\t- ${opt.descr}`);
    }
  });
  process.exit(exitCode);
}

function isPropLegal(propName) {
  return allProps.hasOwnProperty(propName);
}

function workInProgress(lines) {
  let wip = false;
  lines.forEach(line => {
    if (line.match(re.workInProgress)) {
      wip = true;
    }
  });
  return wip;
}

<|endoftext|>


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

// Initializing FOAM_BOOT_DIR.
var FOAM_BOOT_DIR = global.FOAM_BOOT_DIR || '';

global.window = global;
global.document = global;

// Loading all FOAM models.
var modelsfiles =
    fs.readFileSync(path.join(FOAM_BOOT_DIR, 'FOAMmodels.js'));
vm.runInThisContext(modelsfiles);

for (var loadingLoopIndex = 0; loadingLoopIndex < files.length; loadingLoopIndex++) {
  var filename = files[loadingLoopIndex];

  if ( Array.isArray(filename) ) {
    if ( filename[1]() ) filename = filename[0];
    else continue;
  }

  if ( filename.lastIndexOf('.js') != filename.length - 3 ) {
    filename = filename + '.js';
  }

  if ( path.isAbsolute(filename) ) {
    var filedata = fs.readFileSync(filename);
  } else {
    filedata = fs.readFileSync(path.join(FOAM_BOOT_DIR, filename));
  }
  vm.runInThisContext(filedata, filename);
}
<commit_msg>Replce path.isAbsolute usage with poor substitute that works on older nodejs versions<commit_after>/**
 * @license
 * Copyright 2013 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var fs = require('fs');
var vm = require('vm');
var path = require('path');

// Initializing FOAM_BOOT_DIR.
var FOAM_BOOT_DIR = global.FOAM_BOOT_DIR || '';

global.window = global;
global.document = global;

// Loading all FOAM models.
var modelsfiles =
    fs.readFileSync(path.join(FOAM_BOOT_DIR, 'FOAMmodels.js'));
vm.runInThisContext(modelsfiles);

for (var loadingLoopIndex = 0; loadingLoopIndex < files.length; loadingLoopIndex++) {
  var filename = files[loadingLoopIndex];

  if ( Array.isArray(filename) ) {
    if ( filename[1]() ) filename = filename[0];
    else continue;
  }

  if ( filename.lastIndexOf('.js') != filename.length - 3 ) {
    filename = filename + '.js';
  }

  // Poor mans workaround for path.isAbsolute on older nodejs versions.
  if ( filename[0] === '/' ) {
    var filedata = fs.readFileSync(filename);
  } else {
    filedata = fs.readFileSync(path.join(FOAM_BOOT_DIR, filename));
  }
  vm.runInThisContext(filedata, filename);
}
<|endoftext|>