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

var UUFClient = {};

(function (UUFClient) {

    var UUF_ZONE_COMMENT_PREFIX = "[UUF-ZONE]";

    var ON_SUCCESS = "onSuccess";
    var ON_FAILURE = "onFailure";

    var APPEND = "APPEND";
    var PREPEND = "PREPEND";
    var OVERWRITE = "OVERWRITE";

    /**
     * Zones in the current DOM.
     * @type {{string: {start: Object, end: Object}}}
     */

    var zonesMap;

    // Check whether the JQuery is available.
    if (!window.jQuery) {
        throw new UUFClientException("JQuery is required for UUFClient.");
    }
    // Check whether the Handlebars is available.
    if (!window.Handlebars) {
        throw new UUFClientException("Handlebars JS is required for UUFClient.");
    }

    /**
     * Indicates an error in UUFClient.
     *
     * @param {string} message message of this error
     * @param {Object} [cause] cause of this error
     * @param {number} [statusCode] status code of this error
     * @constructor
     */
    function UUFClientException(message, cause, statusCode) {
        this.message = message;
        this.cause = cause;
        this.statusCode = statusCode;
    }

    /**
     * Populates a zones map by scanning HTML comments in the DOM.
     */
    function populateZonesMap() {
        zonesMap = {};
        $("*").contents().filter(function () {
            // For HTML comments, node type will be 8.
            return this.nodeType === 8;
        }).each(function (i, node) {
            var commentText = node.nodeValue;
            if (!commentText.startsWith(UUF_ZONE_COMMENT_PREFIX)) {
                return;
            }

            var zone;
            try {
                zone = JSON.parse(commentText.substring(UUF_ZONE_COMMENT_PREFIX.length));
            } catch (e) {
                throw new UUFClientException("Cannot parse UUFClient zone comment '" + commentText
                                             + "' as a JSON.");
            }
            if (!zone.name) {
                throw new UUFClientException("Cannot find field 'name' in the UUFClient zone comment '"
                                             + commentText + "'.");
            }
            if (!zone.position) {
                throw new UUFClientException("Cannot find field 'position' in the UUFClient zone comment '"
                                             + commentText + "'.");
            }

            if (!zonesMap[zone.name]) {
                zonesMap[zone.name] = {};
            }
            zonesMap[zone.name][zone.position] = node;
        });
    }

    /**
     * Pushes the content to the specified zone according to the given mode.
     *
     * @param {string} content content to push
     * @param {string} zone name of the zone to push
     * @param {string} mode mode to use. Mode can be either PREPEND, APPEND or OVERWRITE. PREPEND will
     *     add the fragment to the beginning of the existing content of that zone. Mode can be "PREPEND" (put the
     *     pushing content before the existing content), "APPEND" (put the pushing content after the existing content)
     *     or "OVERWRITE" (replace the existing content with the pushing content)
     */
    function pushContent(content, zone, mode) {
        if (!content) {
            console.warn("Content is empty.");
            return;
        }

        switch (mode) {
            case OVERWRITE:
                var innerContents = $(zone.start).parent().contents();
                innerContents.slice(innerContents.index($(zone.start)) + 1, innerContents.index($(zone.end))).remove();
                $(zone.start).after(content);
                break;
            case APPEND:
                $(zone.end).before(content);
                break;
            case PREPEND:
                $(zone.start).after(content);
                break;
        }
    }

    /**
     * Check the zoneName and mode variables for null or empty and check for the callback functions.
     *
     * @param {string} zoneName
     * @param {string} mode
     * @param {?Object} callbacks
     */
    function validateParams(zoneName, mode, callbacks) {
        if (!zoneName) {
            throw new UUFClientException("Zone name cannot be null or empty.");
        }
        if (!mode) {
            throw new UUFClientException("Mode cannot be null or empty.");
        }
        if (mode == APPEND || mode == PREPEND || mode == OVERWRITE) {
            throw new UUFClientException("Mode '" + mode + "' is not supported.");
        }
        if (!callbacks[ON_SUCCESS]) {
            throw new UUFClientException("'" + ON_SUCCESS + "' callback function not found.");
        }
        if (!callbacks[ON_FAILURE]) {
            throw new UUFClientException("'" + ON_FAILURE + "' callback function not found.");
        }
    }

    /**
     * Renders the specified fragment and pushes to the given zone according to the given mode.
     *
     * @param {string} fragmentFullyQualifiedName fully qualified name of the fragment
     * @param {?Object} templateFillingObject data for the template
     * @param {string} zoneName name of the zone to push
     * @param {string} mode mode to use
     * @param {Function} callbacks callback function
     */
    UUFClient.renderFragment = function (fragmentFullyQualifiedName, templateFillingObject, zoneName, mode, callbacks) {
        if (!fragmentFullyQualifiedName) {
            throw new UUFClientException("Fragment name cannot be null or empty.");
        }
        validateParams(zoneName, mode, callbacks);

        // This check is not done on renderTemplate* functions because this check will be done in pushContent function.
        if (!zonesMap) {
            populateZonesMap();
        }
        var zone = zonesMap[zoneName];
        if (!zone) {
            throw new UUFClientException("Zone '" + zoneName + "' does not exists in current DOM.");
        }

        var url = contextPath + "/fragments/" + fragmentFullyQualifiedName;
        $.ajax({
                   url: url,
                   type: "POST",
                   contentType: 'application/json',
                   data: JSON.stringify(templateFillingObject),
                   success: function (data, textStatus, jqXHR) {
                       try {
                           pushContent(data, zone, mode);
                           callbacks[ON_SUCCESS](data);
                       } catch (e) {
                           callbacks[ON_FAILURE]("Error occurred while pushing the content.", e);
                       }
                   },
                   error: function (jqXHR, textStatus, errorThrown) {
                       var msg = "Error occurred while retrieving fragment '" + fragmentFullyQualifiedName
                                 + "' from '" + url + "'.";
                       callbacks[ON_FAILURE](msg, errorThrown);
                   }
               });
    };

    /**
     * Renders the specified embedded Handlebars template and pushes to the given zone according to the given mode.
     *
     * @param {string} templateId id of the handlebars template
     * @param {?Object} templateFillingObject data for the template
     * @param {string} zoneName name of the zone to push
     * @param {string} mode mode to use
     * @param {Function} callbacks callback function
     */
    UUFClient.renderTemplate = function (templateId, templateFillingObject, zoneName, mode, callbacks) {
        if (!templateId) {
            throw new UUFClientException("Template name cannot be null or empty.");
        }
        validateParams(zoneName, mode, callbacks);

        var source = $("#" + templateId).html();
        if (source) {
            UUFClient.renderTemplateString(source, templateFillingObject, zoneName, mode, callbacks);
        } else {
            throw new UUFClientException("Template '" + templateId + "' not found");
        }
    };

    /**
     * Retrieves the Handlebars template from the specified URL and renders and pushes it to the given zone according
     * to the given mode.
     *
     * @param {string} templateUrl url of the template
     * @param {?Object} templateFillingObject data for the template
     * @param {string} zoneName name of the zone to push
     * @param {string} mode mode to use
     * @param {Function} callbacks callback function
     */
    UUFClient.renderTemplateUrl = function (templateUrl, templateFillingObject, zoneName, mode, callbacks) {
        if (!templateUrl) {
            throw new UUFClientException("Template url cannot be null or empty.");
        }
        validateParams(zoneName, mode, callbacks);

        $.ajax({
                   url: templateUrl,
                   type: "GET",
                   success: function (data, textStatus, jqXHR) {
                       var contentType = jqXHR.getResponseHeader("content-type") || "";
                       if (contentType.indexOf('text/x-handlebars-template') <= -1) {
                           throw new UUFClientException(
                               "Response content type is incorrect. Found '" + jqXHR.getResponseHeader("content-type")
                               + "' instead of 'text/x-handlebars-template'.");
                       }
                       UUFClient.renderTemplateString(data, templateFillingObject, zoneName, mode);
                       callbacks[ON_SUCCESS](data);
                   },
                   error: function (jqXHR, textStatus, errorThrown) {
                       callbacks[ON_FAILURE]("Error occurred while retrieving template from " + templateUrl + ".",
                                             errorThrown);
                   }
               });
    };

    /**
     * Renders the Handlebars template and pushes to the given zone according to the given mode.
     *
     * @param {string} templateString Handlebars template
     * @param {?Object} templateFillingObject data for the template
     * @param {string} zoneName name of the zone to push
     * @param {string} mode mode to use
     * @param {Function} callbacks callback function
     */
    UUFClient.renderTemplateString = function (templateString, templateFillingObject, zoneName, mode, callbacks) {
        if (!templateString) {
            throw new UUFClientException("Template string cannot be null or empty.");
        }
        validateParams(zoneName, mode, callbacks);

        if (!zonesMap) {
            populateZonesMap();
        }

        var zone = zonesMap[zoneName];
        if (!zone) {
            throw new UUFClientException("Zone '" + zoneName + "' does not exists in current DOM.");
        }

        try {
            var template = Handlebars.compile(templateString);
            var html = template(templateFillingObject);
            pushContent(html, zone, mode);
            callbacks[ON_SUCCESS](html);
        } catch (e) {
            callbacks[ON_FAILURE]("Error occurred while compiling the handlebar template.", e);
        }
    };

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

var UUFClient = {};

(function (UUFClient) {

    var UUF_ZONE_COMMENT_PREFIX = "[UUF-ZONE]";

    var CALLBACK_ON_SUCCESS = "onSuccess";
    var CALLBACK_ON_FAILURE = "onFailure";

    var MODE_APPEND = "APPEND";
    var MODE_PREPEND = "PREPEND";
    var MODE_OVERWRITE = "OVERWRITE";

    /**
     * Zones in the current DOM.
     * @type {{string: {start: Object, end: Object}}}
     */

    var zonesMap;

    // Check whether the JQuery is available.
    if (!window.jQuery) {
        throw new UUFClientException("JQuery is required for UUFClient.");
    }
    // Check whether the Handlebars is available.
    if (!window.Handlebars) {
        throw new UUFClientException("Handlebars JS is required for UUFClient.");
    }

    /**
     * Indicates an error in UUFClient.
     *
     * @param {string} message message of this error
     * @param {Object} [cause] cause of this error
     * @param {number} [statusCode] status code of this error
     * @constructor
     */
    function UUFClientException(message, cause, statusCode) {
        this.message = message;
        this.cause = cause;
        this.statusCode = statusCode;
    }

    /**
     * Populates a zones map by scanning HTML comments in the DOM.
     */
    function populateZonesMap() {
        zonesMap = {};
        $("*").contents().filter(function () {
            // For HTML comments, node type will be 8.
            return this.nodeType === 8;
        }).each(function (i, node) {
            var commentText = node.nodeValue;
            if (!commentText.startsWith(UUF_ZONE_COMMENT_PREFIX)) {
                return;
            }

            var zone;
            try {
                zone = JSON.parse(commentText.substring(UUF_ZONE_COMMENT_PREFIX.length));
            } catch (e) {
                throw new UUFClientException("Cannot parse UUFClient zone comment '" + commentText
                                             + "' as a JSON.");
            }
            if (!zone.name) {
                throw new UUFClientException("Cannot find field 'name' in the UUFClient zone comment '"
                                             + commentText + "'.");
            }
            if (!zone.position) {
                throw new UUFClientException("Cannot find field 'position' in the UUFClient zone comment '"
                                             + commentText + "'.");
            }

            if (!zonesMap[zone.name]) {
                zonesMap[zone.name] = {};
            }
            zonesMap[zone.name][zone.position] = node;
        });
    }

    /**
     * Pushes the content to the specified zone according to the given mode.
     *
     * @param {string} content content to push
     * @param {string} zone name of the zone to push
     * @param {string} mode mode to use. Mode can be either PREPEND, APPEND or OVERWRITE. PREPEND will
     *     add the fragment to the beginning of the existing content of that zone. Mode can be "PREPEND" (put the
     *     pushing content before the existing content), "APPEND" (put the pushing content after the existing content)
     *     or "OVERWRITE" (replace the existing content with the pushing content)
     */
    function pushContent(content, zone, mode) {
        if (!content) {
            console.warn("Content is empty.");
            return;
        }

        switch (mode) {
            case MODE_OVERWRITE:
                var innerContents = $(zone.start).parent().contents();
                innerContents.slice(innerContents.index($(zone.start)) + 1, innerContents.index($(zone.end))).remove();
                $(zone.start).after(content);
                break;
            case MODE_APPEND:
                $(zone.end).before(content);
                break;
            case MODE_PREPEND:
                $(zone.start).after(content);
                break;
        }
    }

    /**
     * Check the zoneName and mode variables for null or empty and check for the callback functions.
     *
     * @param {string} zoneName
     * @param {string} mode
     * @param {?Object} callbacks
     */
    function validateParams(zoneName, mode, callbacks) {
        if (!zoneName) {
            throw new UUFClientException("Zone name cannot be null or empty.");
        }
        if (!mode) {
            throw new UUFClientException("Mode cannot be null or empty.");
        }
        if (mode != MODE_APPEND || mode != MODE_PREPEND || mode != MODE_OVERWRITE) {
            throw new UUFClientException("Mode should be one of '" + MODE_APPEND + "," + MODE_PREPEND + ","
                                         + MODE_OVERWRITE + "'.");
        }
        if (!callbacks[CALLBACK_ON_SUCCESS]) {
            throw new UUFClientException("Function '" + CALLBACK_ON_SUCCESS + "' not found in callbacks.");
        }
        if (!callbacks[CALLBACK_ON_FAILURE]) {
            throw new UUFClientException("Function '" + CALLBACK_ON_FAILURE + "' not found in callbacks.");
        }
    }

    /**
     * Renders the specified fragment and pushes to the given zone according to the given mode.
     *
     * @param {string} fragmentFullyQualifiedName fully qualified name of the fragment
     * @param {?Object} templateFillingObject data for the template
     * @param {string} zoneName name of the zone to push
     * @param {string} mode mode to use
     * @param {Function} callbacks callback function
     */
    UUFClient.renderFragment = function (fragmentFullyQualifiedName, templateFillingObject, zoneName, mode, callbacks) {
        if (!fragmentFullyQualifiedName) {
            throw new UUFClientException("Fragment name cannot be null or empty.");
        }
        validateParams(zoneName, mode, callbacks);

        // This check is not done on renderTemplate* functions because this check will be done in pushContent function.
        if (!zonesMap) {
            populateZonesMap();
        }
        var zone = zonesMap[zoneName];
        if (!zone) {
            throw new UUFClientException("Zone '" + zoneName + "' does not exists in current DOM.");
        }

        var url = contextPath + "/fragments/" + fragmentFullyQualifiedName;
        $.ajax({
                   url: url,
                   type: "POST",
                   contentType: 'application/json',
                   data: JSON.stringify(templateFillingObject),
                   success: function (data, textStatus, jqXHR) {
                       try {
                           pushContent(data, zone, mode);
                           callbacks[CALLBACK_ON_SUCCESS](data);
                       } catch (e) {
                           callbacks[CALLBACK_ON_FAILURE]("Error occurred while pushing the content.", e);
                       }
                   },
                   error: function (jqXHR, textStatus, errorThrown) {
                       var msg = "Error occurred while retrieving fragment '" + fragmentFullyQualifiedName
                                 + "' from '" + url + "'.";
                       callbacks[CALLBACK_ON_FAILURE](msg, errorThrown);
                   }
               });
    };

    /**
     * Renders the specified embedded Handlebars template and pushes to the given zone according to the given mode.
     *
     * @param {string} templateId id of the handlebars template
     * @param {?Object} templateFillingObject data for the template
     * @param {string} zoneName name of the zone to push
     * @param {string} mode mode to use
     * @param {Function} callbacks callback function
     */
    UUFClient.renderTemplate = function (templateId, templateFillingObject, zoneName, mode, callbacks) {
        if (!templateId) {
            throw new UUFClientException("Template name cannot be null or empty.");
        }
        validateParams(zoneName, mode, callbacks);

        var source = $("#" + templateId).html();
        if (source) {
            UUFClient.renderTemplateString(source, templateFillingObject, zoneName, mode, callbacks);
        } else {
            throw new UUFClientException("Template '" + templateId + "' not found");
        }
    };

    /**
     * Retrieves the Handlebars template from the specified URL and renders and pushes it to the given zone according
     * to the given mode.
     *
     * @param {string} templateUrl url of the template
     * @param {?Object} templateFillingObject data for the template
     * @param {string} zoneName name of the zone to push
     * @param {string} mode mode to use
     * @param {Function} callbacks callback function
     */
    UUFClient.renderTemplateUrl = function (templateUrl, templateFillingObject, zoneName, mode, callbacks) {
        if (!templateUrl) {
            throw new UUFClientException("Template url cannot be null or empty.");
        }
        validateParams(zoneName, mode, callbacks);

        $.ajax({
                   url: templateUrl,
                   type: "GET",
                   success: function (data, textStatus, jqXHR) {
                       var contentType = jqXHR.getResponseHeader("content-type") || "";
                       if (contentType.indexOf('text/x-handlebars-template') <= -1) {
                           throw new UUFClientException(
                               "Response content type is incorrect. Found '" + jqXHR.getResponseHeader("content-type")
                               + "' instead of 'text/x-handlebars-template'.");
                       }
                       UUFClient.renderTemplateString(data, templateFillingObject, zoneName, mode);
                       callbacks[CALLBACK_ON_SUCCESS](data);
                   },
                   error: function (jqXHR, textStatus, errorThrown) {
                       callbacks[CALLBACK_ON_FAILURE](
                           "Error occurred while retrieving template from " + templateUrl + ".",
                           errorThrown);
                   }
               });
    };

    /**
     * Renders the Handlebars template and pushes to the given zone according to the given mode.
     *
     * @param {string} templateString Handlebars template
     * @param {?Object} templateFillingObject data for the template
     * @param {string} zoneName name of the zone to push
     * @param {string} mode mode to use
     * @param {Function} callbacks callback function
     */
    UUFClient.renderTemplateString = function (templateString, templateFillingObject, zoneName, mode, callbacks) {
        if (!templateString) {
            throw new UUFClientException("Template string cannot be null or empty.");
        }
        validateParams(zoneName, mode, callbacks);

        if (!zonesMap) {
            populateZonesMap();
        }

        var zone = zonesMap[zoneName];
        if (!zone) {
            throw new UUFClientException("Zone '" + zoneName + "' does not exists in current DOM.");
        }

        try {
            var template = Handlebars.compile(templateString);
            var html = template(templateFillingObject);
            pushContent(html, zone, mode);
            callbacks[CALLBACK_ON_SUCCESS](html);
        } catch (e) {
            callbacks[CALLBACK_ON_FAILURE]("Error occurred while compiling the handlebar template.", e);
        }
    };

})(UUFClient);
<|endoftext|>


<commit_before>'use strict';

define({
  patch: patch,
});

// Patches the provided dictionary of instances of googlemap.Marker.
function patch(markers) {
  ignoreErrors('bernsteinsee');
  setPlaceId('betahaus', 'ChIJqQFHjS1OqEcR8d99mafShxY');
  setPlaceId('brlo', 'ChIJoWMZoR1OqEcR_ZCD-qZZGkA');
  setComment('ilritrovo', 'Italian');
  setPlaceId('nymphensee', 'ChIJGS3gbYD7qEcRePUdNIcYvYE');
  setPlaceId('ploetzensee', 'ChIJY57G5GZRqEcRnKNEpnBZIK8');
  setPlaceId('ponterosa', 'ChIJqTH0OztQqEcRLgWCiboku0M');
  ignoreErrors('rahmersee');

  function setComment(id, comment) {
    try {
      markers[id].setComment(comment);
    } catch(e) {
      console.error('Error patching ' + id + "'s comment: " + e);
    }
  }

  function setPlaceId(id, placeId) {
    try {
      markers[id].setPlaceId(placeId);
    } catch(e) {
      console.error('Error patching ' + id + "'s place ID: " + e);
    }
  }

  function ignoreErrors(id) {
    try {
      markers[id].ignoreErrors();
    } catch(e) {
      console.error('Error patching ' + id + "'s ignore_errors.");
    }
  }
}
<commit_msg>Lipopette's place ID.<commit_after>'use strict';

define({
  patch: patch,
});

// Patches the provided dictionary of instances of googlemap.Marker.
function patch(markers) {
  ignoreErrors('bernsteinsee');
  setPlaceId('betahaus', 'ChIJqQFHjS1OqEcR8d99mafShxY');
  setPlaceId('brlo', 'ChIJoWMZoR1OqEcR_ZCD-qZZGkA');
  setComment('ilritrovo', 'Italian');
  setPlaceId('lipopette', 'ChIJ54YiTpdPqEcR_3MWglIIzLc');
  setPlaceId('nymphensee', 'ChIJGS3gbYD7qEcRePUdNIcYvYE');
  setPlaceId('ploetzensee', 'ChIJY57G5GZRqEcRnKNEpnBZIK8');
  setPlaceId('ponterosa', 'ChIJqTH0OztQqEcRLgWCiboku0M');
  ignoreErrors('rahmersee');

  function setComment(id, comment) {
    try {
      markers[id].setComment(comment);
    } catch(e) {
      console.error('Error patching ' + id + "'s comment: " + e);
    }
  }

  function setPlaceId(id, placeId) {
    try {
      markers[id].setPlaceId(placeId);
    } catch(e) {
      console.error('Error patching ' + id + "'s place ID: " + e);
    }
  }

  function ignoreErrors(id) {
    try {
      markers[id].ignoreErrors();
    } catch(e) {
      console.error('Error patching ' + id + "'s ignore_errors.");
    }
  }
}
<|endoftext|>


<commit_before>const yeoman = require('yeoman-generator');
const yosay = require('yosay');
const _merge = require('lodash/merge');
const _includes = require('lodash/includes');

module.exports = yeoman.Base.extend({
  prompting: {
    mocha() {
      const self = this;

      this.log(yosay(
        'Installing Testing frameworks'
      ));
      return this.prompt([{
        type: 'checkbox',
        name: 'selectedTestFramework',
        message: 'Which Framework do you use?',
        choices: ['Mocha'],
        default: ['Mocha'],
        when: () => !self.config.get('selectedTestFramework'),
      }, {
        type: 'confirm',
        name: 'selectedCoverage',
        message: 'Would you like to enable coverage feature?',
      }])
      .then(answers => {
        self.selectedTestFramework = self.config.get('selectedTestFramework') ||
        answers.selectedTestFramework;
        self.selectedCoverage = self.config.get('selectedCoverage') || answers.selectedCoverage;
      });
    },
  },
  writing() {
    // Read a package.json if it exists or create it
    const packageJSON = this.fs.readJSON(this.destinationPath('package.json'), {});
    // Read a aliases.js if it exists or create it
    let aliasesJS = require(this.destinationPath('./grunt/aliases.js'));
    let cover = require(this.destinationPath('./grunt/aliases.js'));
    // Mocha
    if (_includes(this.selectedTestFramework, 'Mocha')) {
      this.log('Configuring default options for mocha');
      // Convert JSON to an indented JS module.
      aliasesJS = 'module.exports=' + JSON.stringify(_merge(aliasesJS, {
        default: [],
        test: [
          'mochaTest',
        ],
      }), null, 2);
      _merge(packageJSON, {
        devDependencies: {
          'grunt-mocha-test': '^0.13.2',
          mocha: '^3.1.2',
        },
      });
      this.fs.write(this.destinationPath('grunt/aliases.js'), aliasesJS);
      this.fs.copyTpl(
         this.templatePath('mocha.opts'),
         this.destinationPath('./test/mocha.opts'), {}
       );
      this.fs.copyTpl(
         this.templatePath('.eslintrc'),
         this.destinationPath('./test/.eslintrc'), {}
       );
    }
    if (this.selectedCoverage) {
      this.log('Configuring options for coverage');
      // Convert JSON to an indented JS module.
      cover = 'module.exports=' + JSON.stringify(_merge(cover, {
        default: [],
        cover: [
          'mocha_istanbul',
        ],
      }), null, 2);
      _merge(packageJSON, {
        devDependencies: {
          'grunt-mocha-istanbul': '^5.0.2',
        },
      });
      this.fs.write(this.destinationPath('grunt/aliases.js'), cover);
    }
    this.log('Writing to package.json');
    this.fs.writeJSON(this.destinationPath('package.json'), packageJSON);
    this.installDependencies();
  },
});
<commit_msg>update grunt task<commit_after>const yeoman = require('yeoman-generator');
const yosay = require('yosay');
const _merge = require('lodash/merge');
const _includes = require('lodash/includes');

module.exports = yeoman.Base.extend({
  prompting: {
    mocha() {
      const self = this;

      this.log(yosay(
        'Installing Testing frameworks'
      ));
      return this.prompt([{
        type: 'checkbox',
        name: 'selectedTestFramework',
        message: 'Which Framework do you use?',
        choices: ['Mocha'],
        default: ['Mocha'],
        when: () => !self.config.get('selectedTestFramework'),
      }, {
        type: 'confirm',
        name: 'selectedCoverage',
        message: 'Would you like to enable coverage feature?',
      }])
      .then(answers => {
        self.selectedTestFramework = self.config.get('selectedTestFramework') ||
        answers.selectedTestFramework;
        self.selectedCoverage = self.config.get('selectedCoverage') || answers.selectedCoverage;
      });
    },
  },
  writing() {
    // Read a package.json if it exists or create it
    const packageJSON = this.fs.readJSON(this.destinationPath('package.json'), {});
    // Read a aliases.js if it exists or create it
    let aliasesJS = require(this.destinationPath('./grunt/aliases.js'));
    let cover = require(this.destinationPath('./grunt/aliases.js'));
    // Mocha
    if (_includes(this.selectedTestFramework, 'Mocha')) {
      this.log('Configuring default options for mocha');
      // Convert JSON to an indented JS module.
      aliasesJS = 'module.exports=' + JSON.stringify(_merge(aliasesJS, {
        default: [],
        test: [
          'mochaTest',
        ],
      }), null, 2);
      _merge(packageJSON, {
        devDependencies: {
          'grunt-mocha-test': '^0.13.2',
          mocha: '^3.1.2',
        },
      });
      this.fs.write(this.destinationPath('grunt/aliases.js'), aliasesJS);
      this.fs.copyTpl(
         this.templatePath('mocha.opts'),
         this.destinationPath('./test/mocha.opts'), {}
       );
      this.fs.copyTpl(
          this.templatePath('grunt/mochaTest.js'),
          this.destinationPath('./grunt/mochaTest.js'), {}
        );
      this.fs.copyTpl(
         this.templatePath('.eslintrc'),
         this.destinationPath('./test/.eslintrc'), {}
       );
    }
    if (this.selectedCoverage) {
      this.log('Configuring options for coverage');
      // Convert JSON to an indented JS module.
      cover = 'module.exports=' + JSON.stringify(_merge(cover, {
        default: [],
        cover: [
          'mocha_istanbul',
        ],
      }), null, 2);
      _merge(packageJSON, {
        devDependencies: {
          'grunt-mocha-istanbul': '^5.0.2',
        },
      });
      this.fs.copyTpl(
          this.templatePath('grunt/mocha_istanbul.js'),
          this.destinationPath('./grunt/mocha_istanbul.js'), {}
        );
      this.fs.write(this.destinationPath('grunt/aliases.js'), cover);
    }
    this.log('Writing to package.json');
    this.fs.writeJSON(this.destinationPath('package.json'), packageJSON);
    this.installDependencies();
  },
});
<|endoftext|>


<commit_before>

QUnit.test("Token generator test - 1", function(assert) {

    const expected = JSON.stringify([
        { type: "keyword", value:"(" },
        { type: "keyword", value:"&" },
            { type: "keyword", value:"(" },
                { type: "identifier", value: "abc" },
                { type: "keyword", value: "="},
                { type: "identifier", value: "def" },
            { type: "keyword", value: ")" },
            { type: "keyword", value: "(" },
                { type: "identifier", value:"zxy" },
                { type: "keyword", value: "=" },
                { type: "identifier", value: "oph" },
            { type: "keyword", value:")" },
        { type: "keyword", value:")"}
    ]);

    const tkn = Oxy.ldapTokenizer("(&(abc=def)(zxy=oph))");
    const result = JSON.stringify(Array.from(tkn));
    assert.ok(result === expected, result);
});

QUnit.test("Token generator test - 2", function(assert) {

    assert.ok(function () {

        var expected = JSON.stringify([
            { type: "keyword", value: "(" },
            { type: "identifier", value: "abc" },
            { type: "keyword", value: "~=" },
            { type: "identifier", value: "def" },
            { type: "keyword", value: ")" }
        ]);

        const tkn = Oxy.ldapTokenizer("(abc~=def)");
        return JSON.stringify(Array.from(tkn)) === expected;
    }(), "parse ~= condition");

    assert.ok(function () {

        var expected = JSON.stringify([
            { type: "keyword", value: "(" },
            { type: "identifier", value: "abc" },
            { type: "keyword", value: ">=" },
            { type: "identifier", value: "def" },
            { type: "keyword", value: ")" }
        ]);

        const tkn = Oxy.ldapTokenizer("(abc>=def)");
        return JSON.stringify(Array.from(tkn)) === expected;

    }(), "parse >= condition");

    assert.ok(function () {

        var expected = JSON.stringify([
            { type: "keyword", value: "(" },
            { type: "identifier", value: "abc" },
            { type: "keyword", value: "<=" },
            { type: "identifier", value: "def" },
            { type: "keyword", value: ")" }
        ]);

        const tkn = Oxy.ldapTokenizer("(abc<=def)");
        return JSON.stringify(Array.from(tkn)) === expected;

    }(), "parse <= condition");

    assert.ok(function () {

        var expected = JSON.stringify([
            { type: "keyword", value: "(" },
            { type: "identifier", value: "abc" },
            { type: "keyword", value: "<=" },
            { type: "identifier", value: "def" },
            { type: "keyword", value: ")" }
        ]);

        const tkn = Oxy.ldapTokenizer("( abc <= def )");
        return JSON.stringify(Array.from(tkn)) === expected;

    }(), "parse <= condition with whitespaces in identifiers");
});

QUnit.test("LdapParser::parse the simplest filter", function(assert) {

    assert.ok(
        function() {
            const strQuery = "(objectName=someObjectName)";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value instanceof LdapItem && result.value.toString() === strQuery;
        },
        "Test filter by '='"
    );

    assert.ok(
        function() {
            const strQuery = "(objectName~=someObjectName)";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value instanceof LdapItem && result.value.toString() === strQuery;
        },
        "Test filter by '~='"
    );

    assert.ok(
        function() {
            const strQuery = "(objectName>=someObjectName)";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value instanceof LdapItem && result.value.toString() === strQuery;
        },
        "Test filter by '>='"
    );

    assert.ok(
        function() {
            const strQuery = "(objectName<=someObjectName)";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value instanceof LdapItem && result.value.toString() === strQuery;
        },
        "Test filter by '<='"
    );
});

QUnit.test("LdapParser::parse two combined items", function(assert) {

    assert.ok(
        function() {

            const strQuery = "(&(objectName=someObjectName)(objectType=someObjectType))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "Two items connected through &"
    );

    assert.ok(
        function() {

            const strQuery = "(|(objectName=someObjectName)(objectType=someObjectType))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "Two items connected through |"
    );
});

QUnit.test("LdapParser::parse filter list of one element", function(assert) {

    assert.ok(
        function() {
            const strQuery = "(&(objectName=someObjectName))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "Single item connected through &"
    );

    assert.ok(
        function() {
            const strQuery = "(|(objectName=someObjectName))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "Single item connected through |"
    );
});

QUnit.test("LdapParse::parse filter list with nested filter list", function(assert) {

    assert.ok(
        function() {
            const strQuery = "(|(objectName=someObjectName)(&(otherObject=someOtherObject)))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "One nested filter list"
    );

    assert.ok(
        function() {
            const strQuery = "(|(objectName=someObjectName)(&(otherObject=someOtherObject)(|(objectName=someObjectName))))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "One nested filter with one nested filter"
    );
});

// TODO: Put some tests here<commit_msg>Fixed comment :)<commit_after>

QUnit.test("Token generator test - 1", function(assert) {

    const expected = JSON.stringify([
        { type: "keyword", value:"(" },
        { type: "keyword", value:"&" },
            { type: "keyword", value:"(" },
                { type: "identifier", value: "abc" },
                { type: "keyword", value: "="},
                { type: "identifier", value: "def" },
            { type: "keyword", value: ")" },
            { type: "keyword", value: "(" },
                { type: "identifier", value:"zxy" },
                { type: "keyword", value: "=" },
                { type: "identifier", value: "oph" },
            { type: "keyword", value:")" },
        { type: "keyword", value:")"}
    ]);

    const tkn = Oxy.ldapTokenizer("(&(abc=def)(zxy=oph))");
    const result = JSON.stringify(Array.from(tkn));
    assert.ok(result === expected, result);
});

QUnit.test("Token generator test - 2", function(assert) {

    assert.ok(function () {

        var expected = JSON.stringify([
            { type: "keyword", value: "(" },
            { type: "identifier", value: "abc" },
            { type: "keyword", value: "~=" },
            { type: "identifier", value: "def" },
            { type: "keyword", value: ")" }
        ]);

        const tkn = Oxy.ldapTokenizer("(abc~=def)");
        return JSON.stringify(Array.from(tkn)) === expected;
    }(), "parse ~= condition");

    assert.ok(function () {

        var expected = JSON.stringify([
            { type: "keyword", value: "(" },
            { type: "identifier", value: "abc" },
            { type: "keyword", value: ">=" },
            { type: "identifier", value: "def" },
            { type: "keyword", value: ")" }
        ]);

        const tkn = Oxy.ldapTokenizer("(abc>=def)");
        return JSON.stringify(Array.from(tkn)) === expected;

    }(), "parse >= condition");

    assert.ok(function () {

        var expected = JSON.stringify([
            { type: "keyword", value: "(" },
            { type: "identifier", value: "abc" },
            { type: "keyword", value: "<=" },
            { type: "identifier", value: "def" },
            { type: "keyword", value: ")" }
        ]);

        const tkn = Oxy.ldapTokenizer("(abc<=def)");
        return JSON.stringify(Array.from(tkn)) === expected;

    }(), "parse <= condition");

    assert.ok(function () {

        var expected = JSON.stringify([
            { type: "keyword", value: "(" },
            { type: "identifier", value: "abc" },
            { type: "keyword", value: "<=" },
            { type: "identifier", value: "def" },
            { type: "keyword", value: ")" }
        ]);

        const tkn = Oxy.ldapTokenizer("( abc <= def )");
        return JSON.stringify(Array.from(tkn)) === expected;

    }(), "parse <= condition with whitespaces in identifiers");
});

QUnit.test("LdapParser::parse the simplest filter", function(assert) {

    assert.ok(
        function() {
            const strQuery = "(objectName=someObjectName)";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value instanceof LdapItem && result.value.toString() === strQuery;
        },
        "Test filter by '='"
    );

    assert.ok(
        function() {
            const strQuery = "(objectName~=someObjectName)";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value instanceof LdapItem && result.value.toString() === strQuery;
        },
        "Test filter by '~='"
    );

    assert.ok(
        function() {
            const strQuery = "(objectName>=someObjectName)";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value instanceof LdapItem && result.value.toString() === strQuery;
        },
        "Test filter by '>='"
    );

    assert.ok(
        function() {
            const strQuery = "(objectName<=someObjectName)";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value instanceof LdapItem && result.value.toString() === strQuery;
        },
        "Test filter by '<='"
    );
});

QUnit.test("LdapParser::parse two combined items", function(assert) {

    assert.ok(
        function() {

            const strQuery = "(&(objectName=someObjectName)(objectType=someObjectType))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "Two items connected through &"
    );

    assert.ok(
        function() {

            const strQuery = "(|(objectName=someObjectName)(objectType=someObjectType))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "Two items connected through |"
    );
});

QUnit.test("LdapParser::parse filter list of one element", function(assert) {

    assert.ok(
        function() {
            const strQuery = "(&(objectName=someObjectName))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "Single item connected through &"
    );

    assert.ok(
        function() {
            const strQuery = "(|(objectName=someObjectName))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "Single item connected through |"
    );
});

QUnit.test("LdapParse::parse filter list with nested filter list", function(assert) {

    assert.ok(
        function() {
            const strQuery = "(|(objectName=someObjectName)(&(otherObject=someOtherObject)))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "One nested filter list"
    );

    assert.ok(
        function() {
            const strQuery = "(|(objectName=someObjectName)(&(otherObject=someOtherObject)(|(objectName=someObjectName))))";
            const result = Oxy.LdapParser.parse(strQuery);
            return result.success && result.value.toString() === strQuery;
        }(), "One nested filter with one nested filter"
    );
});

// TODO: Put more tests here<|endoftext|>


<commit_before>/* eslint-disable no-console */
import { types, onAction } from 'mobx-state-tree';

const dev = process.env.NODE_ENV !== 'production';

const Build = types
  .model('Build')
  .props({
    siteId: types.string,
    channel: types.enumeration(['amp', 'pwa']),
    device: types.enumeration(['mobile', 'tablet, desktop']),
    rendering: types.enumeration(['ssr', 'csr']),
    packages: types.frozen,
    isDev: types.optional(types.boolean, false),
    initialUrl: types.string,
    perPage: types.optional(types.number, 10),
  })
  .views(self => ({
    get isAmp() {
      return self.channel === 'amp';
    },
    get isPwa() {
      return self.channel === 'pwa';
    },
    isChannel: channel => self.channel === channel,
    get isMobile() {
      return self.device === 'mobile';
    },
    get isTablet() {
      return self.device === 'tablet';
    },
    get isDesktop() {
      return self.device === 'tablet';
    },
    isDevice: device => self.device === device,
    get machine() {
      return typeof window !== 'undefined' ? 'client' : 'server';
    },
    get isServer() {
      return self.machine === 'server';
    },
    get isClient() {
      return self.machine === 'client';
    },
    isMachine: machine => self.machine === machine,
    get isSsr() {
      return self.rendering === 'ssr';
    },
    get isCsr() {
      return self.rendering === 'csr';
    },
    isRendering: rendering => self.rendering === rendering,
  }))
  .actions(self => ({
    switchToCsr: () => { self.rendering = 'csr'; },
  }));

const Store = types
  .model('Store')
  .props({
    settings: types.frozen,
    build: Build,
  })
  .actions(self => ({
    updateSettings: ({ settings }) => {
      self.settings = settings;
    },
    serverStarted: () => {},
    serverFinished: () => {},
    serverFlowsInitialized: () => {},
    clientStarted: () => {},
    clientRendered: () => { self.build.rendering = 'csr'; },
    afterCreate: () => {
      if (dev) onAction(self, action => console.log(action));
    },
  }));

export default Store;
<commit_msg>Fixes build store <commit_after>/* eslint-disable no-console */
import { types, onAction } from 'mobx-state-tree';

const dev = process.env.NODE_ENV !== 'production';

const Build = types
  .model('Build')
  .props({
    siteId: types.string,
    channel: types.enumeration(['amp', 'pwa']),
    device: types.enumeration(['mobile', 'tablet, desktop']),
    rendering: types.enumeration(['ssr', 'csr']),
    packages: types.frozen,
    isDev: types.optional(types.boolean, false),
    initialUrl: types.maybe(types.string),
    perPage: types.optional(types.number, 10),
  })
  .views(self => ({
    get isAmp() {
      return self.channel === 'amp';
    },
    get isPwa() {
      return self.channel === 'pwa';
    },
    isChannel: channel => self.channel === channel,
    get isMobile() {
      return self.device === 'mobile';
    },
    get isTablet() {
      return self.device === 'tablet';
    },
    get isDesktop() {
      return self.device === 'tablet';
    },
    isDevice: device => self.device === device,
    get machine() {
      return typeof window !== 'undefined' ? 'client' : 'server';
    },
    get isServer() {
      return self.machine === 'server';
    },
    get isClient() {
      return self.machine === 'client';
    },
    isMachine: machine => self.machine === machine,
    get isSsr() {
      return self.rendering === 'ssr';
    },
    get isCsr() {
      return self.rendering === 'csr';
    },
    isRendering: rendering => self.rendering === rendering,
  }))
  .actions(self => ({
    switchToCsr: () => {
      self.rendering = 'csr';
    },
  }));

const Store = types
  .model('Store')
  .props({
    settings: types.frozen,
    build: Build,
  })
  .actions(self => ({
    updateSettings: ({ settings }) => {
      self.settings = settings;
    },
    serverStarted: () => {},
    serverFinished: () => {},
    serverFlowsInitialized: () => {},
    clientStarted: () => {},
    clientRendered: () => {
      self.build.rendering = 'csr';
    },
    afterCreate: () => {
      if (dev) onAction(self, action => console.log(action));
    },
  }));

export default Store;
<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var NavigationBar = require('../Components/NavigationBar');

var {
  StyleSheet,
  Text,
  ScrollView,
  View,
  StatusBarIOS,
  LinkingIOS,
  TouchableOpacity,
} = React;

var Help = React.createClass({
  _sendEmail() {
    LinkingIOS.openURL('mailto:info@rnplay.org');
  },

  render() {
    StatusBarIOS.setStyle(StatusBarIOS.Style.lightContent);
    return (
      <View style={{flex: 1}}>
        <NavigationBar title={'About'} />
        <ScrollView style={styles.contentContainer}>
            <Text style={styles.aboutTitle}>What is this app for?</Text>
            <Text style={styles.aboutText}>Running React Native apps from rnplay.org directly on your device.</Text>
            <View style={styles.separator} />
            <Text style={styles.aboutTitle}>How do I exit a loaded app?</Text>
            <Text style={styles.aboutText}>Tap and hold the screen with two fingers simultaneously for 1.5 seconds.</Text>
            <View style={styles.separator} />
            <Text style={styles.aboutTitle}>What does target mean?</Text>
            <Text style={styles.aboutText}>Target refers to the React Native build version that a given play is intended for.</Text>
            <View style={styles.separator} />
            <Text style={styles.aboutTitle} numberOfLines={2}>
              What React Native version is this app built with?
            </Text>
            <Text style={styles.aboutText} numberOfLines={2}>
              This app is currently built against React Native
              <Text style={styles.buildVersionText}> 0.5.0</Text>, released Friday, June 5th, 2015.
            </Text>
            <View style={styles.separator} />
            <View style={styles.otherQuestions}>
              <Text style={styles.otherQuestionsText}>
                More questions? Pleaes get in touch with us by email.
              </Text>
              <View style={{paddingTop: 5}}>
                <TouchableOpacity onPress={this._sendEmail}>
                  <Text style={styles.sendEmailText}>info@rnplay.org</Text>
                </TouchableOpacity>
              </View>
            </View>
        </ScrollView>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  contentContainer: {
    marginTop: -10,
    paddingBottom: 20,
    flex: 1,
  },
  sendEmailText: {
    color: '#712FA9',
    fontSize: 13,
    marginTop: -2,
  },
  aboutTitle: {
    fontSize: 18,
    marginBottom: 10,
    lineHeight: 20,
    fontFamily: 'Avenir Next',
    paddingLeft: 15,
    paddingRight: 15,
  },
  aboutText: {
    paddingRight: 15,
    paddingLeft: 15,
    marginBottom: 12,
    fontSize: 13,
    textAlign: 'left',
    color: '#3a3638',
    opacity: 0.5,
  },
  separator: {
    flex: 1,
    height: 1,
    backgroundColor: "rgba(0,0,0,0.07)",
    marginBottom: 14,
  },
  buildVersionText: {
    fontWeight: 'bold',
  },
  otherQuestionsText: {
    opacity: 0.4,
    fontSize: 13,
  },
  otherQuestions: {
    paddingTop: 0,
    paddingLeft: 15,
    paddingRight: 15,
    paddingBottom: 23,
  }
});

module.exports = Help;
<commit_msg>Adjust styles on about page<commit_after>'use strict';

var React = require('react-native');
var NavigationBar = require('../Components/NavigationBar');

var {
  StyleSheet,
  Text,
  ScrollView,
  View,
  StatusBarIOS,
  LinkingIOS,
  TouchableOpacity,
} = React;

var Help = React.createClass({
  _sendEmail() {
    LinkingIOS.openURL('mailto:info@rnplay.org');
  },

  render() {
    StatusBarIOS.setStyle(StatusBarIOS.Style.lightContent);
    return (
      <View style={{flex: 1}}>
        <NavigationBar title={'About'} />
        <ScrollView style={styles.contentContainer}>
            <Text style={styles.aboutTitle}>What is this app for?</Text>
            <Text style={styles.aboutText}>Running React Native apps from rnplay.org directly on your device.</Text>
            <View style={styles.separator} />
            <Text style={styles.aboutTitle}>How do I exit a loaded app?</Text>
            <Text style={styles.aboutText}>Tap and hold the screen with two fingers simultaneously for 1.5 seconds.</Text>
            <View style={styles.separator} />
            <Text style={styles.aboutTitle}>What does target mean?</Text>
            <Text style={styles.aboutText}>Target refers to the React Native build version that a given play is intended for.</Text>
            <View style={styles.separator} />
            <Text style={styles.aboutTitle} numberOfLines={2}>
              What React Native version is this app built with?
            </Text>
            <Text style={styles.aboutText} numberOfLines={2}>
              This app is currently built against React Native
              <Text style={styles.buildVersionText}> 0.5.0</Text>, released Friday, June 5th, 2015.
            </Text>
            <View style={styles.separator} />
            <View style={styles.otherQuestions}>
              <Text style={styles.otherQuestionsText}>
                More questions? Pleaes get in touch with us by email.
              </Text>
              <View style={{paddingTop: 5}}>
                <TouchableOpacity onPress={this._sendEmail}>
                  <Text style={styles.sendEmailText}>info@rnplay.org</Text>
                </TouchableOpacity>
              </View>
            </View>
        </ScrollView>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  contentContainer: {
    marginTop: -10,
    paddingBottom: 20,
    flex: 1,
  },
  sendEmailText: {
    color: '#712FA9',
    fontSize: 13,
    marginTop: -2,
  },
  aboutTitle: {
    fontSize: 18,
    marginBottom: 4,
    lineHeight: 20,
    fontFamily: 'Avenir Next',
    paddingLeft: 15,
    paddingRight: 20,
  },
  aboutText: {
    paddingRight: 15,
    paddingLeft: 15,
    marginBottom: 12,
    fontSize: 13,
    textAlign: 'left',
    color: '#3a3638',
    opacity: 0.5,
  },
  separator: {
    flex: 1,
    height: 1,
    backgroundColor: "rgba(0,0,0,0.07)",
    marginBottom: 14,
  },
  buildVersionText: {
    fontWeight: 'bold',
  },
  otherQuestionsText: {
    opacity: 0.4,
    fontSize: 13,
  },
  otherQuestions: {
    paddingTop: 0,
    paddingLeft: 15,
    paddingRight: 15,
    paddingBottom: 23,
  }
});

module.exports = Help;
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { Settings, Zap } from 'react-feather';

import Header, { HeaderType } from 'primitives/text/header';
import ContentContainer from 'primitives/containers/content-container';
import SubContainer from 'primitives/containers/sub-container';
import LinkIcon from 'primitives/other/link-icon';
import Link from 'primitives/other/link';

import './style.css';

export default function Home({ seed }) {
  return (
    <ContentContainer direction="column" align="center" justify="center">
      Sectors Without Number
      <SubContainer fullWidth justify="center" align="center">

        Sector Generator & Notepad

      </SubContainer>
      <SubContainer wrap justify="center" align="center">
        <Link padded to="/configure">
          <LinkIcon icon={Settings} size="20" />
          Configure
        </Link>
        <Link
          padded
          to={{
            pathname: '/sector',
            query: { s: seed, c: 8, r: 10 },
          }}
        >
          <LinkIcon icon={Zap} size="20" />
          Generate
        </Link>
      </SubContainer>
    </ContentContainer>
  );
}

Home.propTypes = {
  seed: PropTypes.string.isRequired,
};
<commit_msg>Just a sector generator for now<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { Settings, Zap } from 'react-feather';

import Header, { HeaderType } from 'primitives/text/header';
import ContentContainer from 'primitives/containers/content-container';
import SubContainer from 'primitives/containers/sub-container';
import LinkIcon from 'primitives/other/link-icon';
import Link from 'primitives/other/link';

import './style.css';

export default function Home({ seed }) {
  return (
    <ContentContainer direction="column" align="center" justify="center">
      Sectors Without Number
      <SubContainer fullWidth justify="center" align="center">

        Sector Generator

      </SubContainer>
      <SubContainer wrap justify="center" align="center">
        <Link padded to="/configure">
          <LinkIcon icon={Settings} size="20" />
          Configure
        </Link>
        <Link
          padded
          to={{
            pathname: '/sector',
            query: { s: seed, c: 8, r: 10 },
          }}
        >
          <LinkIcon icon={Zap} size="20" />
          Generate
        </Link>
      </SubContainer>
    </ContentContainer>
  );
}

Home.propTypes = {
  seed: PropTypes.string.isRequired,
};
<|endoftext|>


<commit_before>const fs = require('fs');
const mkdirpSync = require('mkdirp').sync;
const path = require('path');

const DEFAULT_READ_BUFFER_SIZE = 4 * 1024;
const DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;

// node-event-store partition V01
const HEADER_MAGIC = "nesprt01";

class CorruptFileError extends Error {}
class InvalidDataSizeError extends Error {}

/**
 * @param {string} str
 * @param {number} len
 * @param {string} [char]
 * @returns {string}
 */
function pad(str, len, char = ' ') {
    return len > str.length ? char.repeat(len - str.length) + str : str;
}

/**
 * Method for hashing a string (partition name) to a 32-bit unsigned integer.
 *
 * @param {string} str
 * @returns {number}
 */
function hash(str) {
    if (str.length === 0) return 0;
    let hash = 5381,
        i    = str.length;

    while(i) {
        hash = ((hash << 5) + hash) ^ str.charCodeAt(--i);
    }

    /* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
     * integers. Since we want the results to be always positive, convert the
     * signed int to an unsigned by doing an unsigned bitshift. */
    return hash >>> 0;
}

/**
 * A partition is a single file where the storage will write documents to depending on some partitioning rules.
 * In the case of an event store, this is most likely the (write) streams.
 */
class Partition {

    /**
     * Get the id for a specific partition name.
     *
     * @param {string} name
     * @returns {number}
     */
    static id(name) {
        return hash(name);
    }

    /**
     * @param {string} name The name of the partition.
     * @param {Object} [config] An object with storage parameters.
     * @param {string} [config.dataDirectory] The path where the storage data should reside. Default '.'.
     * @param {number} [config.readBufferSize] Size of the read buffer in bytes. Default 4096.
     * @param {number} [config.writeBufferSize] Size of the write buffer in bytes. Default 16384.
     * @param {number} [config.maxWriteBufferDocuments] How many documents to have in the write buffer at max. 0 means as much as possible. Default 0.
     * @param {boolean} [config.syncOnFlush] If fsync should be called on write buffer flush. Set this if you need strict durability. Defaults to false.
     * @param {boolean} [config.dirtyReads] If dirty reads should be allowed. This means that writes that are in write buffer but not yet flushed can be read. Defaults to true.
     */
    constructor(name, config = {}) {
        if (!name) {
            throw new Error('Must specify a partition name.');
        }

        let defaults = {
            dataDirectory: '.',
            readBufferSize: DEFAULT_READ_BUFFER_SIZE,
            writeBufferSize: DEFAULT_WRITE_BUFFER_SIZE,
            maxWriteBufferDocuments: 0,
            syncOnFlush: false,
            dirtyReads: true
        };
        config = Object.assign(defaults, config);
        this.dataDirectory = path.resolve(config.dataDirectory);
        if (!fs.existsSync(this.dataDirectory)) {
            mkdirpSync(this.dataDirectory);
        }

        this.name = name;
        this.id = hash(name);
        this.fileName = path.resolve(this.dataDirectory, this.name);

        this.readBufferSize = config.readBufferSize >>> 0;
        this.writeBufferSize = config.writeBufferSize >>> 0;
        this.maxWriteBufferDocuments = config.maxWriteBufferDocuments >>> 0;
        this.syncOnFlush = !!config.syncOnFlush;
        this.dirtyReads = !!config.dirtyReads;
    }

    /**
     * Check if the partition file is opened.
     *
     * @returns {boolean}
     */
    isOpen() {
        return !!this.fd;
    }

    /**
     * Open the partition storage and create read and write buffers.
     *
     * @api
     * @returns {boolean}
     */
    open() {
        if (this.fd) {
            return true;
        }

        this.fd = fs.openSync(this.fileName, 'a+');

        // allocUnsafeSlow because we don't need buffer pooling for these relatively long-lived buffers
        this.readBuffer = Buffer.allocUnsafeSlow(10 + this.readBufferSize);
        // Where inside the file the read buffer starts
        this.readBufferPos = -1;
        this.readBufferLength = 0;

        this.writeBuffer = Buffer.allocUnsafeSlow(this.writeBufferSize);
        // Where inside the write buffer the next write is added
        this.writeBufferCursor = 0;
        // How many documents are currently in the write buffer
        this.writeBufferDocuments = 0;
        this.flushCallbacks = [];

        let stat = fs.statSync(this.fileName);
        this.headerSize = HEADER_MAGIC.length + 1;
        if (stat.size === 0) {
            fs.writeSync(this.fd, HEADER_MAGIC + "\n");
            this.size = 0;
            return true;
        }

        let headerBuffer = Buffer.allocUnsafe(HEADER_MAGIC.length);
        fs.readSync(this.fd, headerBuffer, 0, HEADER_MAGIC.length, 0);
        if (headerBuffer.toString() !== HEADER_MAGIC) {
            this.close();
            if (headerBuffer.toString().substr(0, -2) === HEADER_MAGIC.substr(0, -2)) {
                throw new Error(`Invalid file version. The partition ${this.name} was created with a different library version.`);
            }
            throw new Error(`Invalid file header in partition ${this.name}.`);
        }
        this.size = stat.size - this.headerSize;

        return true;
    }

    /**
     * Close the partition and frees up all resources.
     *
     * @api
     * @returns void
     */
    close() {
        if (this.fd) {
            this.flush();
            fs.closeSync(this.fd);
            this.fd = undefined;
        }
        if (this.readBuffer) {
            this.readBuffer = undefined;
            this.readBufferPos = -1;
            this.readBufferLength = 0;
        }
        if (this.writeBuffer) {
            this.writeBuffer = undefined;
            this.writeBufferCursor = 0;
            this.writeBufferDocuments = 0;
        }
    }

    /**
     * Flush the write buffer to disk.
     * This is a sync method and will invoke all previously registered flush callbacks.
     *
     * @returns {boolean}
     */
    flush() {
        if (!this.fd) {
            return false;
        }
        if (this.writeBufferCursor === 0) {
            return false;
        }

        fs.writeSync(this.fd, this.writeBuffer, 0, this.writeBufferCursor);
        if (this.syncOnFlush) {
            fs.fsyncSync(this.fd);
        }

        this.writeBufferCursor = 0;
        this.writeBufferDocuments = 0;
        this.flushCallbacks.forEach(callback => callback());
        this.flushCallbacks = [];

        return true;
    }

    /**
     * @private
     * @param {number} dataSize The size of the data that needs to go into the write buffer next.
     */
    flushIfWriteBufferTooSmall(dataSize) {
        if (this.writeBufferCursor > 0 && dataSize + this.writeBufferCursor > this.writeBuffer.byteLength) {
            this.flush();
        }
        if (this.writeBufferCursor === 0) {
            process.nextTick(() => this.flush());
        }
    }

    /**
     * @api
     * @param {string} data The data to write to storage.
     * @param {function} [callback] A function that will be called when the document is written to disk.
     * @returns {number|boolean} The file position at which the data was written or false on error.
     */
    write(data, callback) {
        if (!this.fd) {
            return false;
        }
        let dataSize = Buffer.byteLength(data, 'utf8');
        let dataToWrite = pad(dataSize.toString(), 10) + data.toString() + "\n";
        dataSize += 11;

        this.flushIfWriteBufferTooSmall(dataSize);
        if (dataSize > this.writeBuffer.byteLength) {
            //console.log('unbuffered write!');
            fs.writeSync(this.fd, dataToWrite);
            if (typeof callback === 'function') process.nextTick(callback);
        } else {
            this.writeBufferCursor += this.writeBuffer.write(dataToWrite, this.writeBufferCursor, dataSize, 'utf8');
            this.writeBufferDocuments++;
            if (typeof callback === 'function') this.flushCallbacks.push(callback);
            if (this.maxWriteBufferDocuments > 0 && this.writeBufferDocuments >= this.maxWriteBufferDocuments) {
                this.flush();
            }
        }
        let dataPosition = this.size;
        this.size += dataSize;
        return dataPosition;
    }

    /**
     * Fill the internal read buffer starting from the given position.
     *
     * @private
     * @param {number} [from] The file position to start filling the read buffer from. Default 0.
     */
    fillBuffer(from = 0) {
        if (!this.fd) {
            return;
        }
        this.readBufferLength = fs.readSync(this.fd, this.readBuffer, 0, this.readBuffer.byteLength, this.headerSize + from);
        this.readBufferPos = from;
    }

    /**
     * @private
     * @param {Buffer} buffer The buffer to read the data length from.
     * @param {number} offset The position inside the buffer to start reading from.
     * @param {number} position The file position to start reading from.
     * @param {number} [size] The expected byte size of the document at the given position.
     * @returns {number} The length of the document at the given position.
     * @throws {Error} if the storage entry at the given position is corrupted.
     * @throws {InvalidDataSizeError} if the document size at the given position does not match the provided size.
     * @throws {CorruptFileError} if the document at the given position can not be read completely.
     */
    readDataLength(buffer, offset, position, size) {
        let dataLengthStr = buffer.toString('utf8', offset, offset + 10);
        let dataLength = parseInt(dataLengthStr, 10);
        if (!dataLength || isNaN(dataLength) || !/^\s+[0-9]+$/.test(dataLengthStr)) {
            throw new Error(`Error reading document size from ${position}, got ${dataLength}.`);
        }
        if (size && dataLength !== size) {
            throw new InvalidDataSizeError(`Invalid document size ${dataLength} at position ${position}, expected ${size}.`);
        }

        if (position + dataLength + 11 > this.size) {
            throw new CorruptFileError(`Invalid document at position ${position}. This may be caused by an unfinished write.`);
        }

        return dataLength;
    }

    /**
     * Prepare the read buffer for reading from the specified position.
     *
     * @private
     * @param {number} position The position in the file to prepare the read buffer for reading from.
     * @returns {Object} A reader object with properties `buffer`, `cursor` and `length`.
     */
    prepareReadBuffer(position) {
        let buffer = this.readBuffer;
        let bufferPos = this.readBufferPos;
        let bufferLength = this.readBufferLength;

        // Handle the case when data that is still in write buffer is supposed to be read
        if (this.dirtyReads && this.writeBufferCursor > 0 && position >= this.size - this.writeBufferCursor) {
            buffer = this.writeBuffer;
            bufferPos = this.size - this.writeBufferCursor;
            bufferLength = this.writeBufferCursor;
        }

        let bufferCursor = position - bufferPos;
        if (bufferPos < 0 || bufferCursor < 0 || bufferCursor + 10 > bufferLength) {
            this.fillBuffer(position);
            bufferCursor = 0;
            buffer = this.readBuffer;
            bufferLength = this.readBufferLength;
        }
        return { buffer, cursor: bufferCursor, length: bufferLength };
    }

    /**
     * Read the data from the given position.
     *
     * @api
     * @param {number} position The file position to read from.
     * @param {number} [size] The expected byte size of the document at the given position.
     * @returns {string|boolean} The data stored at the given position or false if no data could be read.
     * @throws {Error} if the storage entry at the given position is corrupted.
     * @throws {InvalidDataSizeError} if the document size at the given position does not match the provided size.
     * @throws {CorruptFileError} if the document at the given position can not be read completely.
     */
    readFrom(position, size) {
        if (!this.fd) {
            return false;
        }
        if (position + 10 >= this.size) {
            return false;
        }
        let reader = this.prepareReadBuffer(position);

        if (reader.length < (size || 1) + 10) {
            return false;
        }

        let dataPosition = reader.cursor + 10;
        let dataLength = this.readDataLength(reader.buffer, reader.cursor, position, size);

        if (dataLength + 10 > reader.buffer.byteLength) {
            //console.log('sync read for large document size', dataLength, 'at position', position);
            let tempReadBuffer = Buffer.allocUnsafe(dataLength);
            fs.readSync(this.fd, tempReadBuffer, 0, dataLength, this.headerSize + position + 10);
            return tempReadBuffer.toString('utf8');
        }

        if (reader.cursor > 0 && dataPosition + dataLength > reader.length) {
            this.fillBuffer(position);
            dataPosition = 10;
        }

        return reader.buffer.toString('utf8', dataPosition, dataPosition + dataLength);
    }

    /**
     * @api
     * @return {Generator} A generator that returns all documents in this partition.
     */
    *readAll() {
        let position = 0;
        let data;
        while ((data = this.readFrom(position)) !== false) {
            yield data;
            position += Buffer.byteLength(data, 'utf8') + 11;
        }
    }

    /**
     * Truncate the partition storage at the given position.
     *
     * @param {number} after The file position after which to truncate the partition.
     */
    truncate(after) {
        if (after > this.size) {
            return;
        }
        if (after < 0) {
            after = 0;
        }
        this.flush();

        let position = after, data;
        try {
            data = this.readFrom(position);
        } catch (e) {
            throw new Error('Can only truncate on valid document boundaries.');
        }
        // copy all truncated documents to some delete log
        let deletedBranch = new Partition(this.name + '-' + after + '.branch', { dataDirectory: this.dataDirectory });
        deletedBranch.open();
        while (data) {
            deletedBranch.write(data);
            position += Buffer.byteLength(data, 'utf8') + 11;
            data = this.readFrom(position);
        }
        deletedBranch.close();

        fs.truncateSync(this.fileName, this.headerSize + after);
        this.size = after;
    }
}

module.exports = Partition;
module.exports.CorruptFileError = CorruptFileError;
module.exports.InvalidDataSizeError = InvalidDataSizeError;<commit_msg>Simplify read size check<commit_after>const fs = require('fs');
const mkdirpSync = require('mkdirp').sync;
const path = require('path');

const DEFAULT_READ_BUFFER_SIZE = 4 * 1024;
const DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;

// node-event-store partition V01
const HEADER_MAGIC = "nesprt01";

class CorruptFileError extends Error {}
class InvalidDataSizeError extends Error {}

/**
 * @param {string} str
 * @param {number} len
 * @param {string} [char]
 * @returns {string}
 */
function pad(str, len, char = ' ') {
    return len > str.length ? char.repeat(len - str.length) + str : str;
}

/**
 * Method for hashing a string (partition name) to a 32-bit unsigned integer.
 *
 * @param {string} str
 * @returns {number}
 */
function hash(str) {
    if (str.length === 0) return 0;
    let hash = 5381,
        i    = str.length;

    while(i) {
        hash = ((hash << 5) + hash) ^ str.charCodeAt(--i);
    }

    /* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
     * integers. Since we want the results to be always positive, convert the
     * signed int to an unsigned by doing an unsigned bitshift. */
    return hash >>> 0;
}

/**
 * A partition is a single file where the storage will write documents to depending on some partitioning rules.
 * In the case of an event store, this is most likely the (write) streams.
 */
class Partition {

    /**
     * Get the id for a specific partition name.
     *
     * @param {string} name
     * @returns {number}
     */
    static id(name) {
        return hash(name);
    }

    /**
     * @param {string} name The name of the partition.
     * @param {Object} [config] An object with storage parameters.
     * @param {string} [config.dataDirectory] The path where the storage data should reside. Default '.'.
     * @param {number} [config.readBufferSize] Size of the read buffer in bytes. Default 4096.
     * @param {number} [config.writeBufferSize] Size of the write buffer in bytes. Default 16384.
     * @param {number} [config.maxWriteBufferDocuments] How many documents to have in the write buffer at max. 0 means as much as possible. Default 0.
     * @param {boolean} [config.syncOnFlush] If fsync should be called on write buffer flush. Set this if you need strict durability. Defaults to false.
     * @param {boolean} [config.dirtyReads] If dirty reads should be allowed. This means that writes that are in write buffer but not yet flushed can be read. Defaults to true.
     */
    constructor(name, config = {}) {
        if (!name) {
            throw new Error('Must specify a partition name.');
        }

        let defaults = {
            dataDirectory: '.',
            readBufferSize: DEFAULT_READ_BUFFER_SIZE,
            writeBufferSize: DEFAULT_WRITE_BUFFER_SIZE,
            maxWriteBufferDocuments: 0,
            syncOnFlush: false,
            dirtyReads: true
        };
        config = Object.assign(defaults, config);
        this.dataDirectory = path.resolve(config.dataDirectory);
        if (!fs.existsSync(this.dataDirectory)) {
            mkdirpSync(this.dataDirectory);
        }

        this.name = name;
        this.id = hash(name);
        this.fileName = path.resolve(this.dataDirectory, this.name);

        this.readBufferSize = config.readBufferSize >>> 0;
        this.writeBufferSize = config.writeBufferSize >>> 0;
        this.maxWriteBufferDocuments = config.maxWriteBufferDocuments >>> 0;
        this.syncOnFlush = !!config.syncOnFlush;
        this.dirtyReads = !!config.dirtyReads;
    }

    /**
     * Check if the partition file is opened.
     *
     * @returns {boolean}
     */
    isOpen() {
        return !!this.fd;
    }

    /**
     * Open the partition storage and create read and write buffers.
     *
     * @api
     * @returns {boolean}
     */
    open() {
        if (this.fd) {
            return true;
        }

        this.fd = fs.openSync(this.fileName, 'a+');

        // allocUnsafeSlow because we don't need buffer pooling for these relatively long-lived buffers
        this.readBuffer = Buffer.allocUnsafeSlow(10 + this.readBufferSize);
        // Where inside the file the read buffer starts
        this.readBufferPos = -1;
        this.readBufferLength = 0;

        this.writeBuffer = Buffer.allocUnsafeSlow(this.writeBufferSize);
        // Where inside the write buffer the next write is added
        this.writeBufferCursor = 0;
        // How many documents are currently in the write buffer
        this.writeBufferDocuments = 0;
        this.flushCallbacks = [];

        let stat = fs.statSync(this.fileName);
        this.headerSize = HEADER_MAGIC.length + 1;
        if (stat.size === 0) {
            fs.writeSync(this.fd, HEADER_MAGIC + "\n");
            this.size = 0;
            return true;
        }

        let headerBuffer = Buffer.allocUnsafe(HEADER_MAGIC.length);
        fs.readSync(this.fd, headerBuffer, 0, HEADER_MAGIC.length, 0);
        if (headerBuffer.toString() !== HEADER_MAGIC) {
            this.close();
            if (headerBuffer.toString().substr(0, -2) === HEADER_MAGIC.substr(0, -2)) {
                throw new Error(`Invalid file version. The partition ${this.name} was created with a different library version.`);
            }
            throw new Error(`Invalid file header in partition ${this.name}.`);
        }
        this.size = stat.size - this.headerSize;

        return true;
    }

    /**
     * Close the partition and frees up all resources.
     *
     * @api
     * @returns void
     */
    close() {
        if (this.fd) {
            this.flush();
            fs.closeSync(this.fd);
            this.fd = undefined;
        }
        if (this.readBuffer) {
            this.readBuffer = undefined;
            this.readBufferPos = -1;
            this.readBufferLength = 0;
        }
        if (this.writeBuffer) {
            this.writeBuffer = undefined;
            this.writeBufferCursor = 0;
            this.writeBufferDocuments = 0;
        }
    }

    /**
     * Flush the write buffer to disk.
     * This is a sync method and will invoke all previously registered flush callbacks.
     *
     * @returns {boolean}
     */
    flush() {
        if (!this.fd) {
            return false;
        }
        if (this.writeBufferCursor === 0) {
            return false;
        }

        fs.writeSync(this.fd, this.writeBuffer, 0, this.writeBufferCursor);
        if (this.syncOnFlush) {
            fs.fsyncSync(this.fd);
        }

        this.writeBufferCursor = 0;
        this.writeBufferDocuments = 0;
        this.flushCallbacks.forEach(callback => callback());
        this.flushCallbacks = [];

        return true;
    }

    /**
     * @private
     * @param {number} dataSize The size of the data that needs to go into the write buffer next.
     */
    flushIfWriteBufferTooSmall(dataSize) {
        if (this.writeBufferCursor > 0 && dataSize + this.writeBufferCursor > this.writeBuffer.byteLength) {
            this.flush();
        }
        if (this.writeBufferCursor === 0) {
            process.nextTick(() => this.flush());
        }
    }

    /**
     * @api
     * @param {string} data The data to write to storage.
     * @param {function} [callback] A function that will be called when the document is written to disk.
     * @returns {number|boolean} The file position at which the data was written or false on error.
     */
    write(data, callback) {
        if (!this.fd) {
            return false;
        }
        let dataSize = Buffer.byteLength(data, 'utf8');
        let dataToWrite = pad(dataSize.toString(), 10) + data.toString() + "\n";
        dataSize += 11;

        this.flushIfWriteBufferTooSmall(dataSize);
        if (dataSize > this.writeBuffer.byteLength) {
            //console.log('unbuffered write!');
            fs.writeSync(this.fd, dataToWrite);
            if (typeof callback === 'function') process.nextTick(callback);
        } else {
            this.writeBufferCursor += this.writeBuffer.write(dataToWrite, this.writeBufferCursor, dataSize, 'utf8');
            this.writeBufferDocuments++;
            if (typeof callback === 'function') this.flushCallbacks.push(callback);
            if (this.maxWriteBufferDocuments > 0 && this.writeBufferDocuments >= this.maxWriteBufferDocuments) {
                this.flush();
            }
        }
        let dataPosition = this.size;
        this.size += dataSize;
        return dataPosition;
    }

    /**
     * Fill the internal read buffer starting from the given position.
     *
     * @private
     * @param {number} [from] The file position to start filling the read buffer from. Default 0.
     */
    fillBuffer(from = 0) {
        if (!this.fd) {
            return;
        }
        this.readBufferLength = fs.readSync(this.fd, this.readBuffer, 0, this.readBuffer.byteLength, this.headerSize + from);
        this.readBufferPos = from;
    }

    /**
     * @private
     * @param {Buffer} buffer The buffer to read the data length from.
     * @param {number} offset The position inside the buffer to start reading from.
     * @param {number} position The file position to start reading from.
     * @param {number} [size] The expected byte size of the document at the given position.
     * @returns {number} The length of the document at the given position.
     * @throws {Error} if the storage entry at the given position is corrupted.
     * @throws {InvalidDataSizeError} if the document size at the given position does not match the provided size.
     * @throws {CorruptFileError} if the document at the given position can not be read completely.
     */
    readDataLength(buffer, offset, position, size) {
        let dataLengthStr = buffer.toString('utf8', offset, offset + 10);
        let dataLength = parseInt(dataLengthStr, 10);
        if (!dataLength || isNaN(dataLength) || !/^\s+[0-9]+$/.test(dataLengthStr)) {
            throw new Error(`Error reading document size from ${position}, got ${dataLength}.`);
        }
        if (size && dataLength !== size) {
            throw new InvalidDataSizeError(`Invalid document size ${dataLength} at position ${position}, expected ${size}.`);
        }

        if (position + dataLength + 11 > this.size) {
            throw new CorruptFileError(`Invalid document at position ${position}. This may be caused by an unfinished write.`);
        }

        return dataLength;
    }

    /**
     * Prepare the read buffer for reading from the specified position.
     *
     * @private
     * @param {number} position The position in the file to prepare the read buffer for reading from.
     * @returns {Object} A reader object with properties `buffer`, `cursor` and `length`.
     */
    prepareReadBuffer(position) {
        let buffer = this.readBuffer;
        let bufferPos = this.readBufferPos;
        let bufferLength = this.readBufferLength;

        // Handle the case when data that is still in write buffer is supposed to be read
        if (this.dirtyReads && this.writeBufferCursor > 0 && position >= this.size - this.writeBufferCursor) {
            buffer = this.writeBuffer;
            bufferPos = this.size - this.writeBufferCursor;
            bufferLength = this.writeBufferCursor;
        }

        let bufferCursor = position - bufferPos;
        if (bufferPos < 0 || bufferCursor < 0 || bufferCursor + 10 > bufferLength) {
            this.fillBuffer(position);
            bufferCursor = 0;
            buffer = this.readBuffer;
            bufferLength = this.readBufferLength;
        }
        return { buffer, cursor: bufferCursor, length: bufferLength };
    }

    /**
     * Read the data from the given position.
     *
     * @api
     * @param {number} position The file position to read from.
     * @param {number} [size] The expected byte size of the document at the given position.
     * @returns {string|boolean} The data stored at the given position or false if no data could be read.
     * @throws {Error} if the storage entry at the given position is corrupted.
     * @throws {InvalidDataSizeError} if the document size at the given position does not match the provided size.
     * @throws {CorruptFileError} if the document at the given position can not be read completely.
     */
    readFrom(position, size = 0) {
        if (!this.fd) {
            return false;
        }
        if (position + 10 >= this.size) {
            return false;
        }
        let reader = this.prepareReadBuffer(position);

        if (reader.length < size + 10) {
            return false;
        }

        let dataPosition = reader.cursor + 10;
        let dataLength = this.readDataLength(reader.buffer, reader.cursor, position, size);

        if (dataLength + 10 > reader.buffer.byteLength) {
            //console.log('sync read for large document size', dataLength, 'at position', position);
            let tempReadBuffer = Buffer.allocUnsafe(dataLength);
            fs.readSync(this.fd, tempReadBuffer, 0, dataLength, this.headerSize + position + 10);
            return tempReadBuffer.toString('utf8');
        }

        if (reader.cursor > 0 && dataPosition + dataLength > reader.length) {
            this.fillBuffer(position);
            dataPosition = 10;
        }

        return reader.buffer.toString('utf8', dataPosition, dataPosition + dataLength);
    }

    /**
     * @api
     * @return {Generator} A generator that returns all documents in this partition.
     */
    *readAll() {
        let position = 0;
        let data;
        while ((data = this.readFrom(position)) !== false) {
            yield data;
            position += Buffer.byteLength(data, 'utf8') + 11;
        }
    }

    /**
     * Truncate the partition storage at the given position.
     *
     * @param {number} after The file position after which to truncate the partition.
     */
    truncate(after) {
        if (after > this.size) {
            return;
        }
        if (after < 0) {
            after = 0;
        }
        this.flush();

        let position = after, data;
        try {
            data = this.readFrom(position);
        } catch (e) {
            throw new Error('Can only truncate on valid document boundaries.');
        }
        // copy all truncated documents to some delete log
        let deletedBranch = new Partition(this.name + '-' + after + '.branch', { dataDirectory: this.dataDirectory });
        deletedBranch.open();
        while (data) {
            deletedBranch.write(data);
            position += Buffer.byteLength(data, 'utf8') + 11;
            data = this.readFrom(position);
        }
        deletedBranch.close();

        fs.truncateSync(this.fileName, this.headerSize + after);
        this.size = after;
    }
}

module.exports = Partition;
module.exports.CorruptFileError = CorruptFileError;
module.exports.InvalidDataSizeError = InvalidDataSizeError;<|endoftext|>


<commit_before>/* global graphql */

import React from 'react';
import PropTypes from 'prop-types';
import Img from 'gatsby-image';

import Separator from './../components/Separator';
import Menu from './../components/Menu';
import MetaTags from './../components/MetaTags';

export default function About({ data }) {
  return (

      <MetaTags
        siteUrl={data.site.siteMetadata.siteUrl}
        title={`About`}
        path={`/about`}
        description={'Hey, I am Kostas. Nice having you here.'}
        noIndex={false}
        tags=""
      />
      <Menu />

Hey, I am Kostas. Nice having you here.

          <Separator />

INTRO

                  I design software architectures, APIs and databases to serve the rest of an
                  application. I am a full stack engineer but I love taking a specific field in my
                  hands and getting the juice out of it. I am always interested in being a part of a
                  team that builds great software and getting things done.

                  I like things like Node.js, Express.js, React.js, Webpack, Gulp, MySQL, MongoDB,
                  Mocha, Jest, AWS, Ansible, Git and a whole lot more.

                  I like speaking to meetups and
                  conferences about things that tried and also talking with others on my{' '}
                  podcast. I created{' '}
                  Janitr and{' '}
                  GitYeller You can find more code samples and my
                  contributions on Github. Along with
                  some folks, we are organizing the local{' '}
                  Nodejs meetup and{' '}

                    DEVit Conf
                  , the biggest web development conference in northern Greece. We are also known
                  as{' '}

                    SKGtech
                  .

                  This site is being generated using Gatsby.js and you can find the source on{' '}
                   GitHub.

                  I am currently living in Thessaloniki, Greece. Have you ever been? Take a look, I
                  am sure you will fall in love with the amazing beaches of Chalkidiki.

BIO

2018

                    Started working with Geekbot, a fully remote
                    company with a mission to change the way we do standup meetings.

2017

                    Started working with Quotelier. A amazing
                    product on the hospitality industry.

2017

                    Released Janitr.net

2016

                    Started the first ever{' '}
                    Podcast for greek developers

2015

                    Started working with Goodvidio

2014

                    Won the first place at{' '}

                      Thessaloniki Startup Live
                    {' '}
                    with the Tunedeck Team

2014

                    Stargento is on the air

2014

                    Started working with a local web design agency. Lots of E-Commerce, Magento
                    based, projects

2013

This blog is born

2013

                    Started working with DTek. A lot of nice projects
                    born from there like Carfinder.gr and{' '}
                    Viral Contest App

2013

                    Fulfilled my military service as defined by the Greek Constitution (nine months)

2012

                    Graduated from{' '}

                      A.T.E.I. Thessalonikis with the BsC of Computer Science

2005

                    Started Web Development using raw HTML, CSS, JS

2002

                    Started Web Development using Flash, Dreamweaver and MS Web Publisher

2001

                    Wrote my first app (Lucky Seven) using Visual Basic

2000

                    Bought my first computer. Since then I have formatted every hard disk of my
                    close friends

1988

                    Bing Bang happens somewhere in Thessaloniki, Greece.

                      Generation Y got upgraded

PROJECTS

                      Janitr

                    A Slack bot that welcomes news members on your team

                      GitYeller

                    Subscribe to your favorite GitHub repository and get notified by email for new
                    issues with specific labels.

                      Stargento

                    PHP sandbox powered up with the latest Magento installation to test your Magento
                    skills

TALKS

                      JavaScript 101

A JavaScript journey for beginners

                      Micro Services Architecture

How do I scale my codebase

  );
}

About.propTypes = {
  data: PropTypes.object,
};

export const aboutPageQuery = graphql`
  query AboutPageSiteMetadata {
    site {
      siteMetadata {
        siteUrl
      }
    }
    file(relativePath: { eq: "avatar.jpg" }) {
      childImageSharp {
        sizes {
          ...GatsbyImageSharpSizes_withWebp
        }
      }
    }
  }
`;
<commit_msg>change a few things on about<commit_after>/* global graphql */

import React from 'react';
import PropTypes from 'prop-types';
import Img from 'gatsby-image';

import Separator from './../components/Separator';
import Menu from './../components/Menu';
import MetaTags from './../components/MetaTags';

export default function About({ data }) {
  return (

      <MetaTags
        siteUrl={data.site.siteMetadata.siteUrl}
        title={`About`}
        path={`/about`}
        description={'Hey, I am Kostas. Nice having you here.'}
        noIndex={false}
        tags=""
      />
      <Menu />

Hey, I am Kostas. Nice having you here.

          <Separator />

INTRO

                  I design software architectures, APIs and databases to serve the rest of an
                  application. I am a full stack engineer but I love taking a specific field in my
                  hands and getting the juice out of it. I am always interested in being a part of a
                  team that builds great software and getting things done.

                  I like things like Node.js, Express.js, React.js, Webpack, Gulp, MySQL, MongoDB,
                  Mocha, Jest, AWS, Ansible, Git and a whole lot more.

                  I like speaking to meetups and
                  conferences about things that tried and also talking with others on my{' '}
                  podcast. I created{' '}
                  Janitr and{' '}
                  GitYeller You can find more code samples and my
                  contributions on Github. Along with
                  some folks, we are organizing the local{' '}
                  Nodejs meetup and{' '}

                    DEVit Conf
                  , the biggest web development conference in northern Greece. We are also known
                  as{' '}

                    SKGtech
                  .

                  This site is being generated using Gatsby.js and you can find the source on{' '}
                   GitHub.

                  I am currently living in Thessaloniki, Greece. Have you ever been? Take a look, I
                  am sure you will fall in love with the amazing beaches of Chalkidiki.

BIO

2018

                    Started working with Geekbot, a fully remote
                    company with a mission to change the way we do standup meetings.

2017

                    Started working with Quotelier. A amazing
                    product on the hospitality industry.

2017

                    Released Janitr.net

2016

                    Started the first ever{' '}
                    Podcast for greek developers

2015

                    Started working with Goodvidio

2014

                    Won the first place at{' '}

                      Thessaloniki Startup Live
                    {' '}
                    with the Tunedeck Team

2014

                    Stargento is on the air

2014

                    Started working with a local web design agency. Lots of E-Commerce, Magento
                    based, projects

2013

This blog is born

2013

                    Started working with DTek. A lot of nice projects
                    born from there like Carfinder.gr and{' '}
                    Viral Contest App

2013

                    Fulfilled my military service as defined by the Greek Constitution (nine months)

2012

                    Graduated from{' '}

                      A.T.E.I. Thessalonikis with the BsC of Computer Science

2005

                    Started Web Development using raw HTML, CSS, JS

2002

                    Started Web Development using Flash, Dreamweaver and MS Web Publisher

2001

                    Wrote my first app (Lucky Seven) using Visual Basic

2000

                    Bought my first computer. Since then I have formatted every hard disk of my
                    close friends

1988

                    Bing Bang happens somewhere in Thessaloniki, Greece.

                      Generation Y got upgraded

PROJECTS

                      Janitr

                    A Slack bot that welcomes news members on your team

                      GitYeller (Dead)

                    Subscribe to your favorite GitHub repository and get notified by email for new
                    issues with specific labels.

                      Stargento (Dead)

                    PHP sandbox powered up with the latest Magento installation to test your Magento
                    skills

TALKS

                      JavaScript 101

A JavaScript journey for beginners

                      Micro Services Architecture

How do I scale my codebase

Find all my presentation slides at Slides.com

  );
}

About.propTypes = {
  data: PropTypes.object,
};

export const aboutPageQuery = graphql`
  query AboutPageSiteMetadata {
    site {
      siteMetadata {
        siteUrl
      }
    }
    file(relativePath: { eq: "avatar.jpg" }) {
      childImageSharp {
        sizes {
          ...GatsbyImageSharpSizes_withWebp
        }
      }
    }
  }
`;
<|endoftext|>