<commit_before>jQuery(document).ready(function($) {

  // Email (mailto:) link click
  var anaylticsMailto = function(email) {
    ga('send', {
      hitType: 'event',
      eventCategory: 'Score',
      eventLabel: 'Email',
      eventAction: email,
      eventValue: 5
    });
  }
  $('a[href^="mailto:"]').bind('click', function(e){
    anaylticsMailto($(this).attr('href').replace('mailto:', ''));
  });

  // Phone number (tel:) link click
  var anaylticsPhone = function(phone) {
    ga('send', {
      hitType: 'event',
      eventCategory: 'Score',
      eventLabel: 'Phone',
      eventAction: phone,
      eventValue: 10
    });
  }
  $('a[href^="tel:"]').bind('click', function(e){
    anaylticsPhone($(this).attr('href').replace('tel:', ''));
  });

  // Widget click
  var anaylticsWidgetClick = function(e) {
    var activeClass = 'btn-primary';
    e.preventDefault();
    var title = $(this).attr('data-title') ? $(this).attr('data-title') : $('h1.entry-title').length ? $('h1.entry-title').text() : document.title;
    ga('send', {
      hitType: 'event',
      eventCategory: 'Score',
      eventLabel: 'Heart',
      eventAction: window.location.href,
      eventValue: jQuery(this).hasClass(activeClass) ? -5 : +5
    });

    if (!$(this).hasClass(activeClass)) {
      ga('send', {
        hitType: 'event',
        eventCategory: 'Heart',
        eventLabel: title,
        eventAction: window.location.href,
        eventValue: 1
      });
    }

    $(this).toggleClass(activeClass);
  }
  $('.proudscore-widget').bind('click', anaylticsWidgetClick);

  // Gravity form submission
  var submittedBy;
  var anaylticsSubmission = function(title, action) {

      ga('send', {
        hitType: 'event',
        eventCategory: 'Submission',
        eventLabel: title,
        eventAction: action,
        eventValue: 1
      });
      ga('send', {
        hitType: 'event',
        eventCategory: 'Score',
        eventLabel: 'Submission',
        eventAction: action,
        eventValue: 5
      });
  }
  $('.gform_wrapper form').once('proud-analytics', function() {
    var $self = $(this);
    // Process buttons to deal with multistep forms
    $.each($self.find('input[type="button"]'), function(key, button) {
      $(button).bind('click', function(e) {
        submittedBy = this.value;
      });
    });
    $self.bind('submit', function(e){
      // Allow bound click to complete
      setTimeout(function() {
        if(submittedBy !== 'Next' && submittedBy !== 'Previous') {
          anaylticsSubmission($(this).attr('id'), $(this).attr('action'));
        }
      }, 0);
    });
  });
  // Emitted by Gravity Forms
  // Documentation: https://www.gravityhelp.com/documentation/article/gform_confirmation_loaded/#source-code
  $(document).bind('gform_confirmation_loaded', function(event, formId){
    anaylticsSubmission('gform_' + formId);
  });

  // Social clicks
  var analyticsSocialClick = function(e) {
    if(e.target.href) {
      var label;
      if(e.target.href.match(/facebook\.com/i)) {
        label = 'Facebook';
      }
      else if(e.target.href.match(/twitter\.com/i)) {
        label = 'Twitter';
      }
      else if(e.target.href.match(/mailto\:/i)) {
        label = 'Email';
      }
      if(label) {
        ga('send', {
          hitType: 'event',
          eventCategory: 'Share',
          eventLabel: label,
          eventAction: window.location.protocol + '//' + window.location.hostname + window.location.pathname,
        });
      }
      ga('send', {
        hitType: 'event',
        eventCategory: 'Score',
        eventLabel: 'Share',
        eventAction: window.location.protocol + '//' + window.location.hostname + window.location.pathname,
        eventValue: 5
      });
    }
  }
  $('.share-dropdown ~ ul.dropdown-menu a').once('social-ga', function() {
    $(this).bind('click', analyticsSocialClick);
  });

  // AddToCalendar click
  var anaylticsCalendarShare = function(title, slug) {
    ga('send', {
      hitType: 'event',
      eventCategory: 'AddEvent',
      eventLabel: title,
      eventAction: slug,
      eventValue: 1
    });
    ga('send', {
      hitType: 'event',
      eventCategory: 'Score',
      eventLabel: 'AddEvent',
      eventAction: slug,
      eventValue: 5
    });
  }
  if ($('.addtocalendar').length) {
    setTimeout(function(){
      $('.atcb-item-link').bind('click', function(e){
        var $parent = $(this).parents('.addtocalendar');
        anaylticsCalendarShare($parent.attr('data-title'), $parent.attr('data-slug'));
      });
    }, 1000);
  }

}); //ready

<commit_msg>Capture form submission form name https://github.com/proudcity/wp-proudcity/issues/1019<commit_after>jQuery(document).ready(function($) {

  // Email (mailto:) link click
  var anaylticsMailto = function(email) {
    ga('send', {
      hitType: 'event',
      eventCategory: 'Score',
      eventLabel: 'Email',
      eventAction: email,
      eventValue: 5
    });
  }
  $('a[href^="mailto:"]').bind('click', function(e){
    anaylticsMailto($(this).attr('href').replace('mailto:', ''));
  });

  // Phone number (tel:) link click
  var anaylticsPhone = function(phone) {
    ga('send', {
      hitType: 'event',
      eventCategory: 'Score',
      eventLabel: 'Phone',
      eventAction: phone,
      eventValue: 10
    });
  }
  $('a[href^="tel:"]').bind('click', function(e){
    anaylticsPhone($(this).attr('href').replace('tel:', ''));
  });

  // Widget click
  var anaylticsWidgetClick = function(e) {
    var activeClass = 'btn-primary';
    e.preventDefault();
    var title = $(this).attr('data-title') ? $(this).attr('data-title') : $('h1.entry-title').length ? $('h1.entry-title').text() : document.title;
    ga('send', {
      hitType: 'event',
      eventCategory: 'Score',
      eventLabel: 'Heart',
      eventAction: window.location.href,
      eventValue: jQuery(this).hasClass(activeClass) ? -5 : +5
    });

    if (!$(this).hasClass(activeClass)) {
      ga('send', {
        hitType: 'event',
        eventCategory: 'Heart',
        eventLabel: title,
        eventAction: window.location.href,
        eventValue: 1
      });
    }

    $(this).toggleClass(activeClass);
  }
  $('.proudscore-widget').bind('click', anaylticsWidgetClick);

  // Gravity form submission
  var submittedBy;
  var anaylticsSubmission = function(title, action) {
    action = window.location.protocol + '//' + window.location.host + action;
    ga('send', {
      hitType: 'event',
      eventCategory: 'Submission',
      eventLabel: title,
      eventAction: action,
      eventValue: 1
    });
    ga('send', {
      hitType: 'event',
      eventCategory: 'Score',
      eventLabel: 'Submission',
      eventAction: action,
      eventValue: 5
    });
  }
  $('.gform_wrapper form').once('proud-analytics', function() {
    var $self = $(this);
    // Process buttons to deal with multistep forms
    $.each($self.find('input[type="button"]'), function(key, button) {
      $(button).bind('click', function(e) {
        submittedBy = this.value;
      });
    });
    $self.bind('submit', function(e){
      // Allow bound click to complete
      setTimeout(function() {
        if(submittedBy !== 'Next' && submittedBy !== 'Previous') {
          anaylticsSubmission($self.attr('id'), $self.attr('action'));
        }
      }, 0);
    });
  });
  // Emitted by Gravity Forms
  // Documentation: https://www.gravityhelp.com/documentation/article/gform_confirmation_loaded/#source-code
  $(document).bind('gform_confirmation_loaded', function(event, formId){
    anaylticsSubmission('gform_' + formId);
  });

  // Social clicks
  var analyticsSocialClick = function(e) {
    if(e.target.href) {
      var label;
      if(e.target.href.match(/facebook\.com/i)) {
        label = 'Facebook';
      }
      else if(e.target.href.match(/twitter\.com/i)) {
        label = 'Twitter';
      }
      else if(e.target.href.match(/mailto\:/i)) {
        label = 'Email';
      }
      if(label) {
        ga('send', {
          hitType: 'event',
          eventCategory: 'Share',
          eventLabel: label,
          eventAction: window.location.protocol + '//' + window.location.hostname + window.location.pathname,
        });
      }
      ga('send', {
        hitType: 'event',
        eventCategory: 'Score',
        eventLabel: 'Share',
        eventAction: window.location.protocol + '//' + window.location.hostname + window.location.pathname,
        eventValue: 5
      });
    }
  }
  $('.share-dropdown ~ ul.dropdown-menu a').once('social-ga', function() {
    $(this).bind('click', analyticsSocialClick);
  });

  // AddToCalendar click
  var anaylticsCalendarShare = function(title, slug) {
    ga('send', {
      hitType: 'event',
      eventCategory: 'AddEvent',
      eventLabel: title,
      eventAction: slug,
      eventValue: 1
    });
    ga('send', {
      hitType: 'event',
      eventCategory: 'Score',
      eventLabel: 'AddEvent',
      eventAction: slug,
      eventValue: 5
    });
  }
  if ($('.addtocalendar').length) {
    setTimeout(function(){
      $('.atcb-item-link').bind('click', function(e){
        var $parent = $(this).parents('.addtocalendar');
        anaylticsCalendarShare($parent.attr('data-title'), $parent.attr('data-slug'));
      });
    }, 1000);
  }

}); //ready

<|endoftext|>


<commit_before>'use strict';

// Basic template description.
exports.description = 'Create a complete Chaplin.js application.';

// Template-specific notes to be displayed before question prompts.
exports.notes = '';

// Any existing file or directory matching this wildcard will cause a warning.
exports.warnOn = '*';

// The initialize template.
exports.template = function(grunt, init, done) {
  var _ = grunt.util._;

  init.process({}, [
    // Prompt for the following values.
    // Built-In
    init.prompt('name'),
    init.prompt('description'),
    init.prompt('version'),
    init.prompt('repository'),
    init.prompt('homepage'),
    init.prompt('bugs'),
    init.prompt('licenses'),
    init.prompt('author_name'),
    init.prompt('author_email'),
    init.prompt('author_url'),
    // Custom
    {
      name: 'language',
      message: 'Language',
      default: 'coffee',
      validator: /coffee|js/,
      warning: 'Must be either "coffee" for coffee-script or "js" ' +
        'for javascript'
    }, {
      name: 'templateLanguage',
      message: 'Micro-templating language',
      default: 'handlebars',
      validator: /handlebars|haml|underscore/,
      warning: 'Must be one of the following template languages: ' +
        'handlebars, haml, or underscore.'
    }, {
      name: 'preprocessor',
      message: 'Stylesheet preprocessor',
      default: 'stylus',
      validator: /sass|scss|less|stylus|none/,
      warning: 'Must be one of the following preprocessors: ' +
        'sass, scss, less, stylus, or none (to indicate no preprocessor).'
    }, {
      name: 'bootstrap',
      message: 'Include Twitter Bootstrap?',
      default: 'Y/n',
      warning: 'Yes: Twitter bootstrap is included; no: it\'s not.',
    }
  ], function(err, props) {
    // Files to copy (and process).
    var files = init.filesToCopy(props);

    // Normalize options.
    props.bootstrap = /y/i.test(props.bootstrap);
    props.preprocessor = props.preprocessor ? props.preprocessor : 'none';

    // Remove files that aren't of the language requested.
    var lang = props.language === 'coffee' ? 'js' : 'coffee';
    files = _.omit(files, function(value, key) {
      if (/^src\/scripts\/vendor/.test(key)) return false;
      return _.endsWith(key, lang);
    });

    // Remove files that aren't of the template language requested.
    var templateLanguages = {
      haml: '.haml',
      handlebars: '.hbs'
    };

    delete templateLanguages[props.templateLanguage];
    files = _.omit(files, function(value, key) {
      return _.any(templateLanguages, function(lang) {
        return _.endsWith(key, lang);
      });
    });

    if (props.templateLanguage === 'haml') {
      // Haml can provide the index file.
      // TODO: Should we generalize this check so other template languages
      //  that can be rendered as well as pre-compiled could be used?
      delete files['src/index.html'];
    }

    // Remove stylesheets that aren't part of the preprocessor requested.
    var preprocessors = {
      none: '.css',
      scss: '.scss',
      sass: '.sass',
      less: '.less',
      stylus: '.styl'
    };

    delete preprocessors[props.preprocessor];
    files = _.omit(files, function(value, key) {
      return _.any(preprocessors, function(lang) {
        return _.endsWith(key, lang);
      });
    });

    // Gather standard and additional dependencies.
    var devDependencies = {
      'grunt': '0.4.x',
      'grunt-contrib-clean': '0.4.0rc6',
      'grunt-contrib-copy': '0.4.0rc7',
      'grunt-contrib-connect': '0.1.1rc6',
      'grunt-contrib-watch': '0.2.0rc7',
      'grunt-requirejs': '0.3.x',
      'grunt-contrib-mincss': '0.4.0rc7',
      'grunt-contrib-htmlmin': '0.1.1rc7',
      'grunt-bower-task': '0.1.x',
      'grunt-urequire': 'git://github.com/aearly/grunt-urequire.git',
      // grunt-urequire requires lodash incorrectly,
      // see: https://github.com/aearly/grunt-urequire/pull/3
      'lodash': '0.10.x',
      'connect-url-rewrite': '0.1.x'
    };

    // Language libraries
    switch (props.language) {
    case 'js':
      devDependencies['grunt-contrib-jshint'] = '0.1.1rc6';
      break;

    case 'coffee':
      devDependencies['grunt-contrib-coffee'] = '0.4.0rc7';
      devDependencies['grunt-coffeelint'] =
        // NPM seems to be out-dated; master works with grunt 0.4.x
        'git://github.com/vojtajina/grunt-coffeelint.git';
      break;
    }

    // Micro-templating library
    switch (props.templateLanguage) {
    case 'haml':
      devDependencies['grunt-haml'] = '0.3.x';

    case 'handlebars':
      // Waiting on a pull request to add modular AMD
      // See: https://github.com/gruntjs/grunt-contrib-handlebars/pull/24
      devDependencies['grunt-contrib-handlebars'] =
        'git://github.com/concordusapps/grunt-contrib-handlebars.git';
      break;
    }

    if (props.templateLanguage !== 'haml') {
      // Remove the HAML runtime.
      delete files['src/scripts/lib/haml.coffee'];
      delete files['src/scripts/lib/haml.js'];
    }

    // Stylesheet preprocessor
    switch (props.preprocessor) {
    case 'sass':
    case 'scss':
      devDependencies['grunt-contrib-compass'] = '0.1.x';
      break;

    case 'stylus':
      devDependencies['grunt-contrib-stylus'] = '0.4.0rc7';
      break;

    case 'less':
      devDependencies['grunt-contrib-less'] = '0.5.x';
      break;
    }

    // Add properly-named license files.
    init.addLicenseFiles(files, props.licenses);

    // Actually copy (and process) files.
    init.copyAndProcess(files, props);

    // Generate package.json file.
    init.writePackageJSON('package.json', _.extend(props, {
      keywords: [],
      node_version: '0.8.x',
      devDependencies: devDependencies
    }));

    // Gather client-side, browser dependencies
    // Collect the standard ones.
    var dependencies = {
      'jquery': '1.8.x',
      'underscore': '1.4.x',
      'backbone': '0.9.x',
      'requirejs': '2.1.x',
      'almond': '0.2.x',
      'chaplin': '0.6.x'
    };

    if (props.templateLanguage === 'handlebars') {
      // Handlebars requires a run-time library.
      dependencies['handlebars'] = '1.0.x'
    }

    // Gatrher the export overrides (these are consumed by grunt-bower-task
    // to replace the main declaration in the component.json).
    // Collect the standard ones
    var exportsOverride = {
      'jquery': {'scripts': 'jquery.js' },
      'almond': {'scripts': 'almond.js' },
      'backbone': {'scripts': 'backbone.js'},
      'requirejs': {'scripts': 'require.js'},
      'underscore': {'scripts': 'underscore.js'},
      'chaplin': {'scripts': 'amd/chaplin.js'},
    };

    if (props.templateLanguage === 'handlebars') {
      // Handlebars requires a run-time library.
      exportsOverride['handlebars'] = {'scripts': 'handlebars.runtime.js'};
    }

    if (props.bootstrap) {
      // Include the bootstrap libraries.
      switch (props.preprocessor) {
      case 'sass':
      case 'scss':
        dependencies['bootstrap-sass'] = '2.2.x';
        exportsOverride['bootstrap-sass'] = {
          'scripts': 'js/**/*.js',
          'styles': 'lib/**/*.scss',
          'images': 'img/glyphicons-*.png',
        };
        break;

      case 'less':
        dependencies['bootstrap'] = '2.2.x';
        exportsOverride['bootstrap'] = {
          'styles': 'less/*.less',
          'scripts': 'js/*.js',
          'images': 'img/glyphicons-*.png'
        };
        break;

      case 'stylus':
      default:
        dependencies['bootstrap'] = '2.2.x';
        exportsOverride['bootstrap'] = {
          'styles': 'docs/assets/css/bootstrap*.css',
          'scripts': 'js/*.js',
          'images': 'img/glyphicons-*.png'
        };
      }
    }

    // Generate a component.json file.
    init.writePackageJSON('component.json', {
      name: props.name,
      version: props.version,
      dependencies: dependencies
    }, function(pkg, props) {
      pkg.exportsOverride = exportsOverride;
      return pkg;
    });

    // All done!
    done();
  });

};
<commit_msg>just make this working again, had problems on startup with the newest 0.6.x chaplin version<commit_after>'use strict';

// Basic template description.
exports.description = 'Create a complete Chaplin.js application.';

// Template-specific notes to be displayed before question prompts.
exports.notes = '';

// Any existing file or directory matching this wildcard will cause a warning.
exports.warnOn = '*';

// The initialize template.
exports.template = function(grunt, init, done) {
  var _ = grunt.util._;

  init.process({}, [
    // Prompt for the following values.
    // Built-In
    init.prompt('name'),
    init.prompt('description'),
    init.prompt('version'),
    init.prompt('repository'),
    init.prompt('homepage'),
    init.prompt('bugs'),
    init.prompt('licenses'),
    init.prompt('author_name'),
    init.prompt('author_email'),
    init.prompt('author_url'),
    // Custom
    {
      name: 'language',
      message: 'Language',
      default: 'coffee',
      validator: /coffee|js/,
      warning: 'Must be either "coffee" for coffee-script or "js" ' +
        'for javascript'
    }, {
      name: 'templateLanguage',
      message: 'Micro-templating language',
      default: 'handlebars',
      validator: /handlebars|haml|underscore/,
      warning: 'Must be one of the following template languages: ' +
        'handlebars, haml, or underscore.'
    }, {
      name: 'preprocessor',
      message: 'Stylesheet preprocessor',
      default: 'stylus',
      validator: /sass|scss|less|stylus|none/,
      warning: 'Must be one of the following preprocessors: ' +
        'sass, scss, less, stylus, or none (to indicate no preprocessor).'
    }, {
      name: 'bootstrap',
      message: 'Include Twitter Bootstrap?',
      default: 'Y/n',
      warning: 'Yes: Twitter bootstrap is included; no: it\'s not.',
    }
  ], function(err, props) {
    // Files to copy (and process).
    var files = init.filesToCopy(props);

    // Normalize options.
    props.bootstrap = /y/i.test(props.bootstrap);
    props.preprocessor = props.preprocessor ? props.preprocessor : 'none';

    // Remove files that aren't of the language requested.
    var lang = props.language === 'coffee' ? 'js' : 'coffee';
    files = _.omit(files, function(value, key) {
      if (/^src\/scripts\/vendor/.test(key)) return false;
      return _.endsWith(key, lang);
    });

    // Remove files that aren't of the template language requested.
    var templateLanguages = {
      haml: '.haml',
      handlebars: '.hbs'
    };

    delete templateLanguages[props.templateLanguage];
    files = _.omit(files, function(value, key) {
      return _.any(templateLanguages, function(lang) {
        return _.endsWith(key, lang);
      });
    });

    if (props.templateLanguage === 'haml') {
      // Haml can provide the index file.
      // TODO: Should we generalize this check so other template languages
      //  that can be rendered as well as pre-compiled could be used?
      delete files['src/index.html'];
    }

    // Remove stylesheets that aren't part of the preprocessor requested.
    var preprocessors = {
      none: '.css',
      scss: '.scss',
      sass: '.sass',
      less: '.less',
      stylus: '.styl'
    };

    delete preprocessors[props.preprocessor];
    files = _.omit(files, function(value, key) {
      return _.any(preprocessors, function(lang) {
        return _.endsWith(key, lang);
      });
    });

    // Gather standard and additional dependencies.
    var devDependencies = {
      'grunt': '0.4.x',
      'grunt-contrib-clean': '0.4.0rc6',
      'grunt-contrib-copy': '0.4.0rc7',
      'grunt-contrib-connect': '0.1.1rc6',
      'grunt-contrib-watch': '0.2.0rc7',
      'grunt-requirejs': '0.3.x',
      'grunt-contrib-mincss': '0.4.0rc7',
      'grunt-contrib-htmlmin': '0.1.1rc7',
      'grunt-bower-task': '0.1.x',
      'grunt-urequire': 'git://github.com/aearly/grunt-urequire.git',
      // grunt-urequire requires lodash incorrectly,
      // see: https://github.com/aearly/grunt-urequire/pull/3
      'lodash': '0.10.x',
      'connect-url-rewrite': '0.1.x'
    };

    // Language libraries
    switch (props.language) {
    case 'js':
      devDependencies['grunt-contrib-jshint'] = '0.1.1rc6';
      break;

    case 'coffee':
      devDependencies['grunt-contrib-coffee'] = '0.4.0rc7';
      devDependencies['grunt-coffeelint'] =
        // NPM seems to be out-dated; master works with grunt 0.4.x
        'git://github.com/vojtajina/grunt-coffeelint.git';
      break;
    }

    // Micro-templating library
    switch (props.templateLanguage) {
    case 'haml':
      devDependencies['grunt-haml'] = '0.3.x';

    case 'handlebars':
      // Waiting on a pull request to add modular AMD
      // See: https://github.com/gruntjs/grunt-contrib-handlebars/pull/24
      devDependencies['grunt-contrib-handlebars'] =
        'git://github.com/concordusapps/grunt-contrib-handlebars.git';
      break;
    }

    if (props.templateLanguage !== 'haml') {
      // Remove the HAML runtime.
      delete files['src/scripts/lib/haml.coffee'];
      delete files['src/scripts/lib/haml.js'];
    }

    // Stylesheet preprocessor
    switch (props.preprocessor) {
    case 'sass':
    case 'scss':
      devDependencies['grunt-contrib-compass'] = '0.1.x';
      break;

    case 'stylus':
      devDependencies['grunt-contrib-stylus'] = '0.4.0rc7';
      break;

    case 'less':
      devDependencies['grunt-contrib-less'] = '0.5.x';
      break;
    }

    // Add properly-named license files.
    init.addLicenseFiles(files, props.licenses);

    // Actually copy (and process) files.
    init.copyAndProcess(files, props);

    // Generate package.json file.
    init.writePackageJSON('package.json', _.extend(props, {
      keywords: [],
      node_version: '0.8.x',
      devDependencies: devDependencies
    }));

    // Gather client-side, browser dependencies
    // Collect the standard ones.
    var dependencies = {
      'jquery': '1.8.x',
      'underscore': '1.4.x',
      'backbone': '0.9.x',
      'requirejs': '2.1.x',
      'almond': '0.2.x',
      'chaplin': '0.7.x'
    };

    if (props.templateLanguage === 'handlebars') {
      // Handlebars requires a run-time library.
      dependencies['handlebars'] = '1.0.x'
    }

    // Gatrher the export overrides (these are consumed by grunt-bower-task
    // to replace the main declaration in the component.json).
    // Collect the standard ones
    var exportsOverride = {
      'jquery': {'scripts': 'jquery.js' },
      'almond': {'scripts': 'almond.js' },
      'backbone': {'scripts': 'backbone.js'},
      'requirejs': {'scripts': 'require.js'},
      'underscore': {'scripts': 'underscore.js'},
      'chaplin': {'scripts': 'amd/chaplin.js'},
    };

    if (props.templateLanguage === 'handlebars') {
      // Handlebars requires a run-time library.
      exportsOverride['handlebars'] = {'scripts': 'handlebars.runtime.js'};
    }

    if (props.bootstrap) {
      // Include the bootstrap libraries.
      switch (props.preprocessor) {
      case 'sass':
      case 'scss':
        dependencies['bootstrap-sass'] = '2.2.x';
        exportsOverride['bootstrap-sass'] = {
          'scripts': 'js/**/*.js',
          'styles': 'lib/**/*.scss',
          'images': 'img/glyphicons-*.png',
        };
        break;

      case 'less':
        dependencies['bootstrap'] = '2.2.x';
        exportsOverride['bootstrap'] = {
          'styles': 'less/*.less',
          'scripts': 'js/*.js',
          'images': 'img/glyphicons-*.png'
        };
        break;

      case 'stylus':
      default:
        dependencies['bootstrap'] = '2.2.x';
        exportsOverride['bootstrap'] = {
          'styles': 'docs/assets/css/bootstrap*.css',
          'scripts': 'js/*.js',
          'images': 'img/glyphicons-*.png'
        };
      }
    }

    // Generate a component.json file.
    init.writePackageJSON('component.json', {
      name: props.name,
      version: props.version,
      dependencies: dependencies
    }, function(pkg, props) {
      pkg.exportsOverride = exportsOverride;
      return pkg;
    });

    // All done!
    done();
  });

};
<|endoftext|>


<commit_before>
var unprocessed_events = {};
unprocessed_events.waiting_for = 0;

// Handle unprocessed events
function handle_unprocessed_events() {

  if (slam.local_event_number == slam.event_number) {
    // Everything is up to date.
    return;
  }

  if (unprocessed_events[slam.local_event_number + 1] !== undefined) {
    // Handle next event.

    var i = slam.local_event_number + 1;

    do_event(unprocessed_events[i]);
    delete (unprocessed_events[i]);
  }
}

function process_metrics(metric) {

  var e = document.getElementById("number_of_connections");
  if (e != null)
    e.innerHTML = "Number of Connections: " + metric.total_connections;

  if (login_info.is_logged_in)
    document.title = metric.total_connections;
}

function process_event(event) {

  try {

    if (event.type == "metrics") {
      var metric = event;

      process_metrics(metric);
      return;
    }

    if (event.type == "heads_up") {
      do_heads_up();
      return;
    }

    if (event.type == "reload") {
      location.reload(true);
      return;
    }

  }
  catch(e) {}

  if (event.competition_id != slam.id)
    return;

  slam.event_number = event.event_number;

  if (event.event_number == slam.local_event_number + 1) {
    do_event(event);
  }
  else {

    unprocessed_events[event.event_number] = event;
    event_catch_up(event.event_number - 1);
  }
}

function last_updated(event) {

  var div = document.getElementById("last_updated");

  var date_pat = /(.*)T/;
  var date =  _.last(date_pat.exec(event.datetime));

  var time_pat = /T(\d*):(\d*):(\d*)/;
  var times = time_pat.exec(event.datetime);

  var time = " " + times[1] + ":" + times[2] + ":" + times[3];

  var datetime = date + time;

  div.innerHTML = "
 Last updated: " + datetime + "
";
}

function do_event(event) {

  if (slam.local_event_number + 1 != event.event_number)
    return;

  slam.local_event_number = event.event_number;

  if (event.event != 'signup_poet')
    last_updated(event);

  // I'm making 'new_round' an exceoption to help keep in sync with the server
  if (event.web_sock_id == web_sock_id && event.event != 'new_round') {
    return;
  }

  switch (event.event) {

    case 'new_performance':
      event_new_performance(event);
      break;
    case 'judge':
      event_judge(event);
      break;
    case 'set_time':
      event_set_time(event);
      break;
    case 'set_penalty':
      event_set_penalty(event);
      break;
    case 'signup_poet':
      signup_poet(event.name);
      break;
    case 'remove_performance':
      event_remove_performance(event);
      break;
    case 'new_round':
      event_new_round(event);
      break;
  }

}

function do_heads_up(event) {

}

// Send requests to the server up to and including 'event_number'
function event_catch_up(event_number) {

  var event_number_i = Math.max(unprocessed_events.waiting_for, slam.local_number_event_number + 1);
  var event_number_j = event_number;

  unprocessed_events.waiting_for = event_number_j;
  get_event_range_request(event_number_i, event_number_j);
}

function event_new_performance(event) {

  var round = rounds[event.round_number -1];

  var prev_performance_2 = null;

  if (event.previous_performance_id != null) {
    prev_performance_2 = comms_2[event.previous_performance_id].p_div.performance;
  }

  var performance_2 = performance_new(event.poet_name, prev_performance_2, round.time_limit, round.grace_period, slam.num_judges);
  var p_div = p_div_new(performance_2);

  performance_2.performance_id = event.performance_id;

  round.round_js.add_performance(performance_2);

  performance_2.calculate(); // So that it doesn't say Rank is 'Infinity'

  $("#performances_" + round.round_number).append(p_div);
  round.names_already_performing.push(performance_2.name);
  invisible_round.notify_rank();

  p_div.comm.performance_id = event.performance_id;

  window.comms_2[event.performance_id] = p_div.comm;

  // Trigger contenders.get_winners() so that the button to add the performer will be removed
  if (round.are_poets_from_previous) {

    var previous_round_index = round.previous_round_number == null ? event.round_number - 2 : round.previous_round_number -1;
    rounds[previous_round_index].round_js.rank();
  }

}

function event_judge(event) {
  var comm_2 = window.comms_2[event.performance_id];

  p_div_set_score(comm_2.p_div, parseInt(event.judge_name), event.value);
}

function event_set_time(event) {

  var p_div = window.comms_2[event.performance_id].p_div;
  p_div_set_time(p_div, event.minutes, event.seconds);
}

function event_set_penalty(event) {
  var p_div = window.comms_2[event.performance_id].p_div;
  p_div_set_penalty(p_div, event.penalty);

}

function event_remove_performance(event) {

  var comm_2 = window.comms_2[event.performance_id];

  remove_performance(comm_2.p_div);
}

function event_new_round(event) {

  if (rounds.length >= parseInt(event.round.round_number))
    return; // ignore

  var round = event.round;
  create_round_div(round);
}
<commit_msg>processing heads_up events<commit_after>
var unprocessed_events = {};
unprocessed_events.waiting_for = 0;

// Handle unprocessed events
function handle_unprocessed_events() {

  if (slam.local_event_number == slam.event_number) {
    // Everything is up to date.
    return;
  }

  if (unprocessed_events[slam.local_event_number + 1] !== undefined) {
    // Handle next event.

    var i = slam.local_event_number + 1;

    do_event(unprocessed_events[i]);
    delete (unprocessed_events[i]);
  }
}

function process_metrics(metric) {

  var e = document.getElementById("number_of_connections");
  if (e != null)
    e.innerHTML = "Number of Connections: " + metric.total_connections;

  if (login_info.is_logged_in)
    document.title = metric.total_connections;
}

function process_event(event) {

  try {

    if (event.type == "metrics") {
      var metric = event;

      process_metrics(metric);
      return;
    }

    if (event.type == "heads_up") {
      do_heads_up();
      return;
    }

    if (event.type == "reload") {
      location.reload(true);
      return;
    }

  }
  catch(e) {}

  if (event.competition_id != slam.id)
    return;

  slam.event_number = event.event_number;

  if (event.event_number == slam.local_event_number + 1) {
    do_event(event);
  }
  else {

    unprocessed_events[event.event_number] = event;
    event_catch_up(event.event_number - 1);
  }
}

function last_updated(event) {

  var div = document.getElementById("last_updated");

  var date_pat = /(.*)T/;
  var date =  _.last(date_pat.exec(event.datetime));

  var time_pat = /T(\d*):(\d*):(\d*)/;
  var times = time_pat.exec(event.datetime);

  var time = " " + times[1] + ":" + times[2] + ":" + times[3];

  var datetime = date + time;

  div.innerHTML = "
 Last updated: " + datetime + "
";
}

function do_event(event) {

  if (slam.local_event_number + 1 != event.event_number)
    return;

  slam.local_event_number = event.event_number;

  if (event.event != 'signup_poet')
    last_updated(event);

  // I'm making 'new_round' an exceoption to help keep in sync with the server
  if (event.web_sock_id == web_sock_id && event.event != 'new_round') {
    return;
  }

  switch (event.event) {

    case 'new_performance':
      event_new_performance(event);
      break;
    case 'judge':
      event_judge(event);
      break;
    case 'set_time':
      event_set_time(event);
      break;
    case 'set_penalty':
      event_set_penalty(event);
      break;
    case 'signup_poet':
      signup_poet(event.name);
      break;
    case 'remove_performance':
      event_remove_performance(event);
      break;
    case 'new_round':
      event_new_round(event);
      break;
  }

}

function do_heads_up(event) {

 if (event.web_sock_id == web_sock_id && event.competition_id != slam.id && comm_2[event.performance_id] != undefined)
  return;

 switch (event.event) {

   case 'judge':
     event_judge(event);
     break;
   case 'set_time':
     event_set_time(event);
     break;
   case 'set_penalty':
     event_set_penalty(event);
     break;
 }
}

// Send requests to the server up to and including 'event_number'
function event_catch_up(event_number) {

  var event_number_i = Math.max(unprocessed_events.waiting_for, slam.local_number_event_number + 1);
  var event_number_j = event_number;

  unprocessed_events.waiting_for = event_number_j;
  get_event_range_request(event_number_i, event_number_j);
}

function event_new_performance(event) {

  var round = rounds[event.round_number -1];

  var prev_performance_2 = null;

  if (event.previous_performance_id != null) {
    prev_performance_2 = comms_2[event.previous_performance_id].p_div.performance;
  }

  var performance_2 = performance_new(event.poet_name, prev_performance_2, round.time_limit, round.grace_period, slam.num_judges);
  var p_div = p_div_new(performance_2);

  performance_2.performance_id = event.performance_id;

  round.round_js.add_performance(performance_2);

  performance_2.calculate(); // So that it doesn't say Rank is 'Infinity'

  $("#performances_" + round.round_number).append(p_div);
  round.names_already_performing.push(performance_2.name);
  invisible_round.notify_rank();

  p_div.comm.performance_id = event.performance_id;

  window.comms_2[event.performance_id] = p_div.comm;

  // Trigger contenders.get_winners() so that the button to add the performer will be removed
  if (round.are_poets_from_previous) {

    var previous_round_index = round.previous_round_number == null ? event.round_number - 2 : round.previous_round_number -1;
    rounds[previous_round_index].round_js.rank();
  }

}

function event_judge(event) {
  var comm_2 = window.comms_2[event.performance_id];

  p_div_set_score(comm_2.p_div, parseInt(event.judge_name), event.value);
}

function event_set_time(event) {

  var p_div = window.comms_2[event.performance_id].p_div;
  p_div_set_time(p_div, event.minutes, event.seconds);
}

function event_set_penalty(event) {
  var p_div = window.comms_2[event.performance_id].p_div;
  p_div_set_penalty(p_div, event.penalty);

}

function event_remove_performance(event) {

  var comm_2 = window.comms_2[event.performance_id];

  remove_performance(comm_2.p_div);
}

function event_new_round(event) {

  if (rounds.length >= parseInt(event.round.round_number))
    return; // ignore

  var round = event.round;
  create_round_div(round);
}
<|endoftext|>


<commit_before>/**
 * Poetry.route
 * Create a new endpoint
 * @param {object} options Options passed to HAPI server
 * @param {function} handler Request handler passed to HAPI server
 * @returns {void} void
 */
const log = require( './log' ),
    events = require( './events' ),
    devRoute = require('./devRoute');

let registry = [];

module.exports = function route(
    options,
    handler
) {

    let options = devRoute(options, handler);

    events.emit( 'web:route', options );
    registry.push( options );

};

events.on( 'web:init', ( message ) => {
    registry.forEach( ( options ) => {
        events.emit( 'web:route', options );
    } );
} );
<commit_msg>debug<commit_after>/**
 * Poetry.route
 * Create a new endpoint
 * @param {object} options Options passed to HAPI server
 * @param {function} handler Request handler passed to HAPI server
 * @returns {void} void
 */
const log = require( './log' ),
    events = require( './events' ),
    devRoute = require('./devRoute');

let registry = [];

module.exports = function route(
    opt,
    handler
) {

    let options = devRoute(opt, handler);

    events.emit( 'web:route', options );
    registry.push( options );

};

events.on( 'web:init', ( message ) => {
    registry.forEach( ( options ) => {
        events.emit( 'web:route', options );
    } );
} );
<|endoftext|>


<commit_before>"use strict";

const fs = require('fs');
const crypto = require('crypto');
const gm = require('gm');
const stream2buffer = require('stream-to-buffer');
const streamifier = require('streamifier');
const XRegExp = require('xregexp').XRegExp;
const co = require('co');

const IMAGE_REGEX = XRegExp('^\/ai\/(?<width>\\d+)x(?<height>\\d+)(?<x2>@2x)?\/(?<path>.+\\.(?<ext>jpe?g|png|gif))(?:\\?(?:.+)?)?$', 'i');
const MIME_TYPES = {
  'jpg': 'image/jpeg',
  'jpeg': 'image/jpeg',
  'png': 'image/png',
  'gif': 'image/gif'
};

module.exports = function(http) {
  let log = http.log.as('http:ai');
  let config = http.config.ai || {};

  let imagesDir = mkpath(sand.appPath, config.imagesDir);

  let put = config.put;
  let get = config.get;

  if (config.useMemcache && sand.memcache) {
    put = function(key, buf, callback) {
      sand.memcache.set(key, buf, config.cacheLife, callback);
    };
    get = function(key, callback) {
      sand.memcache.get(key, callback);
    };
  }

  return function(req, res, next) {

    // ignore if we're not GETing
    if ('GET' !== req.method) {
      return next();
    }

    // check if route matches
    let matches = IMAGE_REGEX.xexec(req.originalUrl);

    if (!matches) {
      return next();
    }

    // Ensure the file exists
    try {
      fs.statSync(mkpath(imagesDir, matches.path));
    } catch (e) {
      return next();
    }

    // collect the adapted dimensions
    let width = parseInt(matches.width);
    let height = parseInt(matches.height);
    let crop = !!('undefined' !== typeof req.query.crop && req.query.crop == 1);
    let bg = req.query.bg ? '#' + req.query.bg : 'white';
    let is2x = matches.x2 || req.query.x2;

    // for 2x images
    if (is2x) {
      width *= 2;
      height *= 2;
    }

    let path = matches.path;
    let mimetype = MIME_TYPES[matches.ext.toLowerCase()];

    // we don't know how to return this one
    if (!mimetype) {
      return next();
    }

    if (!config.useCache) {
      return adapt(function(err, stdout) {

        if (err) {
          log(err.message || err);
          return next(err);
        }

        send(stdout);

      });
    }

    co(function *() {

      try {

        // check if we have cache
        try {
          var buffer = yield getCache();
        } catch(e) {
          sand.warn('Could not get cache');
        }

        if (buffer) {
          // if we do, then return it right away
          let stream = streamifier.createReadStream(buffer);
          return send(stream);
        }

        // otherwise, make a buffer and cache it
        buffer = yield putCache();

        if (!buffer) {
          // we should never get here!!! buffer should always be returned
          return next(new Error('AI: Unable to retrieve image! (' + getKey() + ')'));
        }

        // change buffer to stream and return
        let stream = streamifier.createReadStream(buffer);
        return send(stream);

      } catch(e) {
        http.log(e.message || e);
        return next(e);
      }

    });

    // Helper functions

    function send(stream) {
      res.setHeader('content-type', mimetype);
      stream.pipe(res);
    }

    /**
     * Adapts the image to the proper dimensions with cropping
     *
     * @returns {Promise}
     */
    function adapt(callback) {
      /*
       * For Graphics Magick docs: http://www.graphicsmagick.org/GraphicsMagick.html#details-geometry
       * Inspiration: http://stackoverflow.com/questions/14705152/thumbnails-from-graphics-magick-without-upscaling
       */

      let w = width == 0 ? null : (crop ? `${width}^` : width);
      let h = height == 0 ? null : (crop ? `${height}^` : height);

      gm(config.stream(path) || mkpath(imagesDir, path))
        .out('-background', bg)
        .resize(w, h)
        .gravity('Center')
        .extent(width, height)
        .quality(90)
        .strip()
        .stream(function(err, stdout, stderr) {
          if (err) {
            return callback(err);
          }
          callback(null, stdout);
        });
    }

    /**
     * Fetches an image buffer from the cache
     *
     * @returns {Promise}
     */
    function getCache() {
      return new Promise(function(resolve, reject) {
        // create and fetch the cache key
        get(getKey(), function(err, data) {
          if (err) {
            return reject(err);
          }
          resolve(data);
        });
      });
    }

    /**
     * Creates an adapted image buffer | puts it in the cache | returns the buffer
     *
     * @returns {Promise}
     */
    function putCache() {
      return new Promise(function(resolve, reject) {
        // make the cache key
        let key = getKey();

        // adapt the image
        adapt(function(err, stdout, stderr) {
          if (err) {
            return reject(err);
          }

          // convert the new image stream to buffer
          stream2buffer(stdout, function(err, buffer) {
            if (err) {
              return reject(err);
            }

            if (!buffer || !buffer.length) {
              return resolve(buffer);
            }

            // put the buffer in the cache
            put(key, buffer, function(err, data) {
              if (err) {
                return reject(err);
              }

              // return the buffer
              resolve(buffer);
            });
          });
        });
      });
    }

    /**
     * Builds a cache key for the adapted image
     *
     * @returns {string}
     */
    function getKey() {
      let paramString = width + 'x' + height + '-' + path + (is2x ? '-@2x' : '');
      return paramString + '-' + crypto.createHash('sha1').update(paramString).digest('hex');
    }

  };

};

function mkpath(dir, rel) {
  return dir.replace(/\/$/, '') + '/' + rel.replace(/^\//, '');
}<commit_msg>include bg color in cache key<commit_after>"use strict";

const fs = require('fs');
const crypto = require('crypto');
const gm = require('gm');
const stream2buffer = require('stream-to-buffer');
const streamifier = require('streamifier');
const XRegExp = require('xregexp').XRegExp;
const co = require('co');

const IMAGE_REGEX = XRegExp('^\/ai\/(?<width>\\d+)x(?<height>\\d+)(?<x2>@2x)?\/(?<path>.+\\.(?<ext>jpe?g|png|gif))(?:\\?(?:.+)?)?$', 'i');
const MIME_TYPES = {
  'jpg': 'image/jpeg',
  'jpeg': 'image/jpeg',
  'png': 'image/png',
  'gif': 'image/gif'
};

module.exports = function(http) {
  let log = http.log.as('http:ai');
  let config = http.config.ai || {};

  let imagesDir = mkpath(sand.appPath, config.imagesDir);

  let put = config.put;
  let get = config.get;

  if (config.useMemcache && sand.memcache) {
    put = function(key, buf, callback) {
      sand.memcache.set(key, buf, config.cacheLife, callback);
    };
    get = function(key, callback) {
      sand.memcache.get(key, callback);
    };
  }

  return function(req, res, next) {

    // ignore if we're not GETing
    if ('GET' !== req.method) {
      return next();
    }

    // check if route matches
    let matches = IMAGE_REGEX.xexec(req.originalUrl);

    if (!matches) {
      return next();
    }

    // Ensure the file exists
    try {
      fs.statSync(mkpath(imagesDir, matches.path));
    } catch (e) {
      return next();
    }

    // collect the adapted dimensions
    let width = parseInt(matches.width);
    let height = parseInt(matches.height);
    let crop = !!('undefined' !== typeof req.query.crop && req.query.crop == 1);
    let bg = req.query.bg ? '#' + req.query.bg : undefined;
    let is2x = matches.x2 || req.query.x2;

    // for 2x images
    if (is2x) {
      width *= 2;
      height *= 2;
    }

    let path = matches.path;
    let mimetype = MIME_TYPES[matches.ext.toLowerCase()];

    // we don't know how to return this one
    if (!mimetype) {
      return next();
    }

    if (!config.useCache) {
      return adapt(function(err, stdout) {

        if (err) {
          log(err.message || err);
          return next(err);
        }

        send(stdout);

      });
    }

    co(function *() {

      try {

        // check if we have cache
        try {
          var buffer = yield getCache();
        } catch(e) {
          sand.warn('Could not get cache');
        }

        if (buffer) {
          // if we do, then return it right away
          let stream = streamifier.createReadStream(buffer);
          return send(stream);
        }

        // otherwise, make a buffer and cache it
        buffer = yield putCache();

        if (!buffer) {
          // we should never get here!!! buffer should always be returned
          return next(new Error('AI: Unable to retrieve image! (' + getKey() + ')'));
        }

        // change buffer to stream and return
        let stream = streamifier.createReadStream(buffer);
        return send(stream);

      } catch(e) {
        http.log(e.message || e);
        return next(e);
      }

    });

    // Helper functions

    function send(stream) {
      res.setHeader('content-type', mimetype);
      stream.pipe(res);
    }

    /**
     * Adapts the image to the proper dimensions with cropping
     *
     * @returns {Promise}
     */
    function adapt(callback) {
      /*
       * For Graphics Magick docs: http://www.graphicsmagick.org/GraphicsMagick.html#details-geometry
       * Inspiration: http://stackoverflow.com/questions/14705152/thumbnails-from-graphics-magick-without-upscaling
       */

      let w = width == 0 ? null : (crop ? `${width}^` : width);
      let h = height == 0 ? null : (crop ? `${height}^` : height);

      gm(config.stream(path) || mkpath(imagesDir, path))
        .out('-background', bg || 'white')
        .resize(w, h)
        .gravity('Center')
        .extent(width, height)
        .quality(90)
        .strip()
        .stream(function(err, stdout, stderr) {
          if (err) {
            return callback(err);
          }
          callback(null, stdout);
        });
    }

    /**
     * Fetches an image buffer from the cache
     *
     * @returns {Promise}
     */
    function getCache() {
      return new Promise(function(resolve, reject) {
        // create and fetch the cache key
        get(getKey(), function(err, data) {
          if (err) {
            return reject(err);
          }
          resolve(data);
        });
      });
    }

    /**
     * Creates an adapted image buffer | puts it in the cache | returns the buffer
     *
     * @returns {Promise}
     */
    function putCache() {
      return new Promise(function(resolve, reject) {
        // make the cache key
        let key = getKey();

        // adapt the image
        adapt(function(err, stdout, stderr) {
          if (err) {
            return reject(err);
          }

          // convert the new image stream to buffer
          stream2buffer(stdout, function(err, buffer) {
            if (err) {
              return reject(err);
            }

            if (!buffer || !buffer.length) {
              return resolve(buffer);
            }

            // put the buffer in the cache
            put(key, buffer, function(err, data) {
              if (err) {
                return reject(err);
              }

              // return the buffer
              resolve(buffer);
            });
          });
        });
      });
    }

    /**
     * Builds a cache key for the adapted image
     *
     * @returns {string}
     */
    function getKey() {
      let paramString = width + 'x' + height + '-' + path + (is2x ? '-@2x' : '') + (bg ? '_' + bg : '');
      return paramString + '-' + crypto.createHash('sha1').update(paramString).digest('hex');
    }

  };

};

function mkpath(dir, rel) {
  return dir.replace(/\/$/, '') + '/' + rel.replace(/^\//, '');
}<|endoftext|>


<commit_before>import GameStateManager from "./GameStates/GameStateManager";
// import CommandParser from "./Commands/CommandParser";
import GenerateName from "./Generators/NameGenerator";

export default {
  install: (Vue) => {
    Vue.prototype.$game = {
      start() {
        GameStateManager.StartGame();
      },
      receiveInput(input) {
        console.log(input);
        GameStateManager.receiveInput(input);
      },
      generateName() {
        return GenerateName();
      },
      parseCommand(command) {
        // return CommandParser.ParseCommand(command);
        console.log("Parsing " + command);
      },
      getCurrentState() {
        return GameStateManager.currentState;
      }
    }
  }
}
<commit_msg>Add display to game plugin, add redraw method on gsman<commit_after>import GameStateManager from "./GameStates/GameStateManager";
// import CommandParser from "./Commands/CommandParser";
import GenerateName from "./Generators/NameGenerator";
import display from "./overview/Display.js";

export default {
  install: (Vue) => {
    Vue.prototype.$game = {
      start() {
        GameStateManager.StartGame();
      },
      receiveInput(input) {
        console.log(input);
        GameStateManager.receiveInput(input);
      },
      generateName() {
        return GenerateName();
      },
      parseCommand(command) {
        // return CommandParser.ParseCommand(command);
        console.log("Parsing " + command);
      },
      getCurrentState() {
        return GameStateManager.currentState;
      },
      redraw() {
        return GameStateManager.redraw();
      },
      display: display,
    }
  }
}
<|endoftext|>


<commit_before>import _ from 'lodash';
import ReplConsoleHook from '../common/ReplConsoleHook';
import ReplConstants from '../constants/ReplConstants';
import vm from 'vm';
import fs from 'fs';
import {dirname, resolve} from 'path';
import timers from 'timers';
import module from 'module';
import util from 'util';

let execSync = require('child_process').execSync;
let cxt = null;
let systemVariables = [];
let npmExe = resolve(__dirname, 'node_modules', '.bin', 'npm');

let getPreferences = () => global.Mancy.preferences;
let noop = () => {};
let linkFun = noop;
let link = (context) => { (linkFun || noop)(context); };

let hookContext = (fun) => {
  linkFun = fun;
}

let createContext = () => {
  if(cxt) { return cxt; }
  // sandbox
  let context = vm.createContext();
  let defaults = [
    'process',
    'Buffer',
    'console',
    'module',
    'require',
    '__filename',
    '__dirname'
  ];

  let circulars = [ '_', 'global', 'GLOBAL', 'root'];

  _.each(defaults, (g) => {
    context[g] = global[g];
  });

  _.each(circulars, (g) => {
    context[g] = context;
  });

  context.console = require('console');
  _.each(['error', 'warn', 'info', 'log', 'debug'], (fun) => {
    context.console[fun] = ReplConsoleHook[fun];
  });

  let timerFuns = [ 'clearImmediate', 'clearInterval', 'clearTimeout',
    'setImmediate', 'setInterval', 'setTimeout' ];

  _.each(timerFuns, (fun) => {
    context[fun] = timers[fun];
  });

  context.os = require('os');

  context.process.on('uncaughtException', function (err) {
    console.error(err);
  });

  let {createScript} = vm;
  vm.createScript = (code, options) => {
    try {
      let {timeout} = getPreferences();
      let cxt = createScript(code, options);
      let runInContext = cxt.runInContext.bind(cxt);
      cxt.runInContext = (contextifiedSandbox, options) => {
        return runInContext(contextifiedSandbox, {
          displayErrors: false,
          timeout: timeout
        });
      };
      global.Mancy.REPLError = null;
      return cxt;
    } catch(e) {
      if(e instanceof SyntaxError) {
        global.Mancy.REPLError = e;
      }
      throw e;
    }
  };

  let _load = module._load;
  module._load = (request, parent, isMain) => {
    try {
      return _load(request, parent, isMain);
    } catch(e) {
      let path = dirname(parent.paths[parent.paths.length - 1]);
      try {
        let child = execSync(`npm install ${request}`,
          { cwd: `${path}`, stdio:[], timeout: global.Mancy.preferences.timeout });
        return _load(request, parent, isMain);
      } catch(ex) {
        throw e;
      }
    }
  };

  let debuglog = util.debuglog;
  util.debuglog = (name) => {
    if(name === 'repl') {
      return (fun, e, ret) => {
        if(fun === 'finish' && !e) {
          // unlink context
          link({});
        }
        else if(fun === 'line %j') {
          // link context
          link(context);
        }
      };
    }
    return debuglog(name);
  };

  systemVariables = _.keys(context);

  if(process.platform !== 'win32' && context.process.env.PATH.indexOf() == -1) {
    context.process.env.PATH += ':/usr/local/bin';
  }

  return (cxt = context);
};

let getContext = () => {
  return cxt ? cxt : createContext();
};

let builtIns = () => {
  return systemVariables;
};

createContext();
export default { createContext, getContext, builtIns, hookContext };
<commit_msg>Add repl builtins in context<commit_after>import _ from 'lodash';
import ReplConsoleHook from '../common/ReplConsoleHook';
import ReplConstants from '../constants/ReplConstants';
import vm from 'vm';
import fs from 'fs';
import {dirname, resolve} from 'path';
import timers from 'timers';
import module from 'module';
import util from 'util';

let execSync = require('child_process').execSync;
let cxt = null;
let systemVariables = [];
let npmExe = resolve(__dirname, 'node_modules', '.bin', 'npm');

let getPreferences = () => global.Mancy.preferences;
let noop = () => {};
let linkFun = noop;
let link = (context) => { (linkFun || noop)(context); };

let hookContext = (fun) => {
  linkFun = fun;
}

let createContext = () => {
  if(cxt) { return cxt; }
  // sandbox
  let context = vm.createContext();
  let defaults = [
    'process',
    'Buffer',
    'console',
    'module',
    'require',
    '__filename',
    '__dirname'
  ];

  let circulars = [ '_', 'global', 'GLOBAL', 'root'];

  _.each(defaults, (g) => {
    context[g] = global[g];
  });

  _.each(circulars, (g) => {
    context[g] = context;
  });

  context.console = require('console');
  _.each(['error', 'warn', 'info', 'log', 'debug'], (fun) => {
    context.console[fun] = ReplConsoleHook[fun];
  });

  let timerFuns = [ 'clearImmediate', 'clearInterval', 'clearTimeout',
    'setImmediate', 'setInterval', 'setTimeout' ];

  _.each(timerFuns, (fun) => {
    context[fun] = timers[fun];
  });

  context.os = require('os');

  context.process.on('uncaughtException', function (err) {
    console.error(err);
  });

  let {createScript} = vm;
  vm.createScript = (code, options) => {
    try {
      let {timeout} = getPreferences();
      let cxt = createScript(code, options);
      let runInContext = cxt.runInContext.bind(cxt);
      cxt.runInContext = (contextifiedSandbox, options) => {
        return runInContext(contextifiedSandbox, {
          displayErrors: false,
          timeout: timeout
        });
      };
      global.Mancy.REPLError = null;
      return cxt;
    } catch(e) {
      if(e instanceof SyntaxError) {
        global.Mancy.REPLError = e;
      }
      throw e;
    }
  };

  let _load = module._load;
  module._load = (request, parent, isMain) => {
    try {
      return _load(request, parent, isMain);
    } catch(e) {
      let path = dirname(parent.paths[parent.paths.length - 1]);
      try {
        let child = execSync(`npm install ${request}`,
          { cwd: `${path}`, stdio:[], timeout: global.Mancy.preferences.timeout });
        return _load(request, parent, isMain);
      } catch(ex) {
        throw e;
      }
    }
  };

  let debuglog = util.debuglog;
  util.debuglog = (name) => {
    if(name === 'repl') {
      return (fun, e, ret) => {
        if(fun === 'finish' && !e) {
          // unlink context
          link({});
        }
        else if(fun === 'line %j') {
          // link context
          link(context);
        }
      };
    }
    return debuglog(name);
  };

  systemVariables = _.keys(context);

  if(process.platform !== 'win32' && context.process.env.PATH.indexOf() == -1) {
    context.process.env.PATH += ':/usr/local/bin';
  }

  // load builtIns
  let builtins = require('repl')._builtinLibs;
  _.each(builtins, (name) => {
    Object.defineProperty(context, name, {
      get: () => (context[name] = require(name)),
      set: (val) => {
        delete context[name];
        context[name] = val;
      },
      configurable: true
    });
  });

  return (cxt = context);
};

let getContext = () => {
  return cxt ? cxt : createContext();
};

let builtIns = () => {
  return systemVariables;
};

createContext();
export default { createContext, getContext, builtIns, hookContext };
<|endoftext|>


<commit_before>// # Ghost Server
// Handles the creation of an HTTP Server for Ghost
const debug = require('@tryghost/debug')('server');

const Promise = require('bluebird');
const fs = require('fs-extra');
const path = require('path');
const _ = require('lodash');
const config = require('../shared/config');
const errors = require('@tryghost/errors');
const tpl = require('@tryghost/tpl');
const logging = require('@tryghost/logging');
const notify = require('./notify');
const moment = require('moment');
const stoppable = require('stoppable');

const messages = {
    cantTouchThis: 'Can\'t touch this',
    ghostIsRunning: 'Ghost is running...',
    yourBlogIsAvailableOn: 'Your site is now available on {url}',
    ctrlCToShutDown: 'Ctrl+C to shut down',
    ghostIsRunningIn: 'Ghost is running in {env}...',
    listeningOn: 'Listening on: {host}:{port}',
    urlConfiguredAs: 'Url configured as: {url}',
    ghostIsShuttingDown: 'Ghost is shutting down',
    ghostHasShutdown: 'Ghost has shut down',
    yourBlogIsNowOffline: 'Your site is now offline',
    ghostWasRunningFor: 'Ghost was running for',
    addressInUse: {
        error: '(EADDRINUSE) Cannot start Ghost.',
        context: 'Port {port} is already in use by another program.',
        help: 'Is another Ghost instance already running?'
    },
    otherError: {
        error: '(Code: {errorNumber})',
        context: 'There was an error starting your server.',
        help: 'Please use the error code above to search for a solution.'
    }
};

/**
 * ## GhostServer
 */
class GhostServer {
    constructor({url}) {
        this.url = url;
        this.rootApp = null;
        this.httpServer = null;

        // Expose config module for use externally.
        this.config = config;

        // Tasks that should be run before the server exits
        this.cleanupTasks = [];
    }

    /**
     * ## Public API methods
     *
     * ### Start
     * Starts the ghost server listening on the configured port.
     * Requires an express app to be passed in
     *
     * @param  {Object} rootApp - Required express app instance.
     * @return {Promise} Resolves once Ghost has started
     */
    start(rootApp) {
        debug('Starting...');
        const self = this;
        self.rootApp = rootApp;
        let socketConfig;

        const socketValues = {
            path: path.join(config.get('paths').contentPath, config.get('env') + '.socket'),
            permissions: '660'
        };

        return new Promise(function (resolve, reject) {
            if (_.has(config.get('server'), 'socket')) {
                socketConfig = config.get('server').socket;

                if (_.isString(socketConfig)) {
                    socketValues.path = socketConfig;
                } else if (_.isObject(socketConfig)) {
                    socketValues.path = socketConfig.path || socketValues.path;
                    socketValues.permissions = socketConfig.permissions || socketValues.permissions;
                }

                // Make sure the socket is gone before trying to create another
                try {
                    fs.unlinkSync(socketValues.path);
                } catch (e) {
                    // We can ignore this.
                }

                self.httpServer = rootApp.listen(socketValues.path);
                fs.chmod(socketValues.path, socketValues.permissions);
                config.set('server:socket', socketValues);
            } else {
                self.httpServer = rootApp.listen(
                    config.get('server').port,
                    config.get('server').host
                );
            }

            self.httpServer.on('error', function (error) {
                let ghostError;

                if (error.code === 'EADDRINUSE') {
                    ghostError = new errors.InternalServerError({
                        message: tpl(messages.addressInUse.error),
                        context: tpl(messages.addressInUse.context, {port: config.get('server').port}),
                        help: tpl(messages.addressInUse.help)
                    });
                } else {
                    ghostError = new errors.InternalServerError({
                        message: tpl(messages.otherError.error, {errorNumber: error.errno}),
                        context: tpl(messages.otherError.context),
                        help: tpl(messages.otherError.help)
                    });
                }

                debug('Notifying server started (error)');
                return notify.notifyServerStarted()
                    .finally(() => {
                        reject(ghostError);
                    });
            });

            self.httpServer.on('listening', function () {
                debug('...Started');
                self._logStartMessages();

                // Debug logs output in testmode only
                if (config.get('server:testmode')) {
                    self._startTestMode();
                }

                debug('Notifying server ready (success)');
                return notify.notifyServerStarted()
                    .finally(() => {
                        resolve(self);
                    });
            });

            stoppable(self.httpServer, config.get('server:shutdownTimeout'));

            // ensure that Ghost exits correctly on Ctrl+C and SIGTERM
            process
                .removeAllListeners('SIGINT').on('SIGINT', self.shutdown.bind(self))
                .removeAllListeners('SIGTERM').on('SIGTERM', self.shutdown.bind(self));
        });
    }

    /**
     * ### Shutdown
     * Stops the server, handles cleanup and exits the process = a full shutdown
     * Called on SIGINT or SIGTERM
     */
    async shutdown(code = 0) {
        try {
            logging.warn(tpl(messages.ghostIsShuttingDown));
            await this.stop();
            setTimeout(() => {
                process.exit(code);
            }, 100);
        } catch (error) {
            logging.error(error);
            setTimeout(() => {
                process.exit(1);
            }, 100);
        }
    }

    /**
     * ### Stop
     * Stops the server & handles cleanup, but does not exit the process
     * Used in tests for quick start/stop actions
     * Called by shutdown to handle server stop and cleanup before exiting
     * @returns {Promise} Resolves once Ghost has stopped
     */
    async stop() {
        try {
            // If we never fully started, there's nothing to stop
            if (this.httpServer && this.httpServer.listening) {
                // We stop the server first so that no new long running requests or processes can be started
                await this._stopServer();
            }
            // Do all of the cleanup tasks
            await this._cleanup();
        } finally {
            // Wrap up
            this.httpServer = null;
            this._logStopMessages();
        }
    }

    /**
     * ### Hammertime
     * To be called after `stop`
     */
    async hammertime() {
        logging.info(tpl(messages.cantTouchThis));
    }

    /**
     * Add a task that should be called on shutdown
     */
    registerCleanupTask(task) {
        this.cleanupTasks.push(task);
    }

    /**
     * ### Stop Server
     * Does the work of stopping the server using stoppable
     * This handles closing connections:
     * - New connections are rejected
     * - Idle connections are closed immediately
     * - Active connections are allowed to complete in-flight requests before being closed
     *
     * If server.shutdownTimeout is reached, requests are terminated in-flight
     */
    async _stopServer() {
        return new Promise((resolve, reject) => {
            this.httpServer
                .stop((error, status) => {
                    if (error) {
                        return reject(error);
                    }

                    return resolve(status);
                });
        });
    }

    async _cleanup() {
        // Wait for all cleanup tasks to finish
        await Promise
            .all(this.cleanupTasks.map(task => task()));
    }

    /**
     * Internal Method for TestMode.
     */
    _startTestMode() {
        // This is horrible and very temporary
        const jobService = require('./services/jobs');

        // Output how many connections are open every 5 seconds
        const connectionInterval = setInterval(() => this.httpServer.getConnections(
            (err, connections) => logging.warn(`${connections} connections currently open`)
        ), 5000);

        // Output a notice when the server closes
        this.httpServer.on('close', function () {
            clearInterval(connectionInterval);
            logging.warn('Server has fully closed');
        });

        // Output job queue length every 5 seconds
        setInterval(() => {
            logging.warn(`${jobService.queue.length()} jobs in the queue. Idle: ${jobService.queue.idle()}`);

            const runningScheduledjobs = Object.keys(jobService.bree.workers);
            if (Object.keys(jobService.bree.workers).length) {
                logging.warn(`${Object.keys(jobService.bree.workers).length} jobs running: ${runningScheduledjobs}`);
            }

            const scheduledJobs = Object.keys(jobService.bree.intervals);
            if (Object.keys(jobService.bree.intervals).length) {
                logging.warn(`${Object.keys(jobService.bree.intervals).length} scheduled jobs: ${scheduledJobs}`);
            }

            if (runningScheduledjobs.length === 0 && scheduledJobs.length === 0) {
                logging.warn('No scheduled or running jobs');
            }
        }, 5000);
    }

    /**
     * Log Start Messages
     */
    _logStartMessages() {
        logging.info(tpl(messages.ghostIsRunningIn, {env: config.get('env')}));

        if (config.get('env') === 'production') {
            logging.info(tpl(messages.yourBlogIsAvailableOn, {url: this.url}));
        } else {
            logging.info(tpl(messages.listeningOn, {
                host: config.get('server').socket || config.get('server').host,
                port: config.get('server').port
            }));
            logging.info(tpl(messages.urlConfiguredAs, {url: this.url}));
        }

        logging.info(tpl(messages.ctrlCToShutDown));
    }

    /**
     * Log Stop Messages
     */
    _logStopMessages() {
        logging.warn(tpl(messages.ghostHasShutdown));

        // Extra clear message for production mode
        if (config.get('env') === 'production') {
            logging.warn(tpl(messages.yourBlogIsNowOffline));
        }

        // Always output uptime
        logging.warn(
            tpl(messages.ghostWasRunningFor),
            moment.duration(process.uptime(), 'seconds').humanize()
        );
    }
}

module.exports = GhostServer;
<commit_msg>Removed socket option from ghost-server<commit_after>// # Ghost Server
// Handles the creation of an HTTP Server for Ghost
const debug = require('@tryghost/debug')('server');

const Promise = require('bluebird');
const config = require('../shared/config');
const errors = require('@tryghost/errors');
const tpl = require('@tryghost/tpl');
const logging = require('@tryghost/logging');
const notify = require('./notify');
const moment = require('moment');
const stoppable = require('stoppable');

const messages = {
    cantTouchThis: 'Can\'t touch this',
    ghostIsRunning: 'Ghost is running...',
    yourBlogIsAvailableOn: 'Your site is now available on {url}',
    ctrlCToShutDown: 'Ctrl+C to shut down',
    ghostIsRunningIn: 'Ghost is running in {env}...',
    listeningOn: 'Listening on: {host}:{port}',
    urlConfiguredAs: 'Url configured as: {url}',
    ghostIsShuttingDown: 'Ghost is shutting down',
    ghostHasShutdown: 'Ghost has shut down',
    yourBlogIsNowOffline: 'Your site is now offline',
    ghostWasRunningFor: 'Ghost was running for',
    addressInUse: {
        error: '(EADDRINUSE) Cannot start Ghost.',
        context: 'Port {port} is already in use by another program.',
        help: 'Is another Ghost instance already running?'
    },
    otherError: {
        error: '(Code: {errorNumber})',
        context: 'There was an error starting your server.',
        help: 'Please use the error code above to search for a solution.'
    }
};

/**
 * ## GhostServer
 */
class GhostServer {
    constructor({url}) {
        this.url = url;
        this.rootApp = null;
        this.httpServer = null;

        // Expose config module for use externally.
        this.config = config;

        // Tasks that should be run before the server exits
        this.cleanupTasks = [];
    }

    /**
     * ## Public API methods
     *
     * ### Start
     * Starts the ghost server listening on the configured port.
     * Requires an express app to be passed in
     *
     * @param  {Object} rootApp - Required express app instance.
     * @return {Promise} Resolves once Ghost has started
     */
    start(rootApp) {
        debug('Starting...');
        const self = this;
        self.rootApp = rootApp;

        return new Promise(function (resolve, reject) {
            self.httpServer = rootApp.listen(
                config.get('server').port,
                config.get('server').host
            );

            self.httpServer.on('error', function (error) {
                let ghostError;

                if (error.code === 'EADDRINUSE') {
                    ghostError = new errors.InternalServerError({
                        message: tpl(messages.addressInUse.error),
                        context: tpl(messages.addressInUse.context, {port: config.get('server').port}),
                        help: tpl(messages.addressInUse.help)
                    });
                } else {
                    ghostError = new errors.InternalServerError({
                        message: tpl(messages.otherError.error, {errorNumber: error.errno}),
                        context: tpl(messages.otherError.context),
                        help: tpl(messages.otherError.help)
                    });
                }

                debug('Notifying server started (error)');
                return notify.notifyServerStarted()
                    .finally(() => {
                        reject(ghostError);
                    });
            });

            self.httpServer.on('listening', function () {
                debug('...Started');
                self._logStartMessages();

                // Debug logs output in testmode only
                if (config.get('server:testmode')) {
                    self._startTestMode();
                }

                debug('Notifying server ready (success)');
                return notify.notifyServerStarted()
                    .finally(() => {
                        resolve(self);
                    });
            });

            stoppable(self.httpServer, config.get('server:shutdownTimeout'));

            // ensure that Ghost exits correctly on Ctrl+C and SIGTERM
            process
                .removeAllListeners('SIGINT').on('SIGINT', self.shutdown.bind(self))
                .removeAllListeners('SIGTERM').on('SIGTERM', self.shutdown.bind(self));
        });
    }

    /**
     * ### Shutdown
     * Stops the server, handles cleanup and exits the process = a full shutdown
     * Called on SIGINT or SIGTERM
     */
    async shutdown(code = 0) {
        try {
            logging.warn(tpl(messages.ghostIsShuttingDown));
            await this.stop();
            setTimeout(() => {
                process.exit(code);
            }, 100);
        } catch (error) {
            logging.error(error);
            setTimeout(() => {
                process.exit(1);
            }, 100);
        }
    }

    /**
     * ### Stop
     * Stops the server & handles cleanup, but does not exit the process
     * Used in tests for quick start/stop actions
     * Called by shutdown to handle server stop and cleanup before exiting
     * @returns {Promise} Resolves once Ghost has stopped
     */
    async stop() {
        try {
            // If we never fully started, there's nothing to stop
            if (this.httpServer && this.httpServer.listening) {
                // We stop the server first so that no new long running requests or processes can be started
                await this._stopServer();
            }
            // Do all of the cleanup tasks
            await this._cleanup();
        } finally {
            // Wrap up
            this.httpServer = null;
            this._logStopMessages();
        }
    }

    /**
     * ### Hammertime
     * To be called after `stop`
     */
    async hammertime() {
        logging.info(tpl(messages.cantTouchThis));
    }

    /**
     * Add a task that should be called on shutdown
     */
    registerCleanupTask(task) {
        this.cleanupTasks.push(task);
    }

    /**
     * ### Stop Server
     * Does the work of stopping the server using stoppable
     * This handles closing connections:
     * - New connections are rejected
     * - Idle connections are closed immediately
     * - Active connections are allowed to complete in-flight requests before being closed
     *
     * If server.shutdownTimeout is reached, requests are terminated in-flight
     */
    async _stopServer() {
        return new Promise((resolve, reject) => {
            this.httpServer
                .stop((error, status) => {
                    if (error) {
                        return reject(error);
                    }

                    return resolve(status);
                });
        });
    }

    async _cleanup() {
        // Wait for all cleanup tasks to finish
        await Promise
            .all(this.cleanupTasks.map(task => task()));
    }

    /**
     * Internal Method for TestMode.
     */
    _startTestMode() {
        // This is horrible and very temporary
        const jobService = require('./services/jobs');

        // Output how many connections are open every 5 seconds
        const connectionInterval = setInterval(() => this.httpServer.getConnections(
            (err, connections) => logging.warn(`${connections} connections currently open`)
        ), 5000);

        // Output a notice when the server closes
        this.httpServer.on('close', function () {
            clearInterval(connectionInterval);
            logging.warn('Server has fully closed');
        });

        // Output job queue length every 5 seconds
        setInterval(() => {
            logging.warn(`${jobService.queue.length()} jobs in the queue. Idle: ${jobService.queue.idle()}`);

            const runningScheduledjobs = Object.keys(jobService.bree.workers);
            if (Object.keys(jobService.bree.workers).length) {
                logging.warn(`${Object.keys(jobService.bree.workers).length} jobs running: ${runningScheduledjobs}`);
            }

            const scheduledJobs = Object.keys(jobService.bree.intervals);
            if (Object.keys(jobService.bree.intervals).length) {
                logging.warn(`${Object.keys(jobService.bree.intervals).length} scheduled jobs: ${scheduledJobs}`);
            }

            if (runningScheduledjobs.length === 0 && scheduledJobs.length === 0) {
                logging.warn('No scheduled or running jobs');
            }
        }, 5000);
    }

    /**
     * Log Start Messages
     */
    _logStartMessages() {
        logging.info(tpl(messages.ghostIsRunningIn, {env: config.get('env')}));

        if (config.get('env') === 'production') {
            logging.info(tpl(messages.yourBlogIsAvailableOn, {url: this.url}));
        } else {
            logging.info(tpl(messages.listeningOn, {
                host: config.get('server').host,
                port: config.get('server').port
            }));
            logging.info(tpl(messages.urlConfiguredAs, {url: this.url}));
        }

        logging.info(tpl(messages.ctrlCToShutDown));
    }

    /**
     * Log Stop Messages
     */
    _logStopMessages() {
        logging.warn(tpl(messages.ghostHasShutdown));

        // Extra clear message for production mode
        if (config.get('env') === 'production') {
            logging.warn(tpl(messages.yourBlogIsNowOffline));
        }

        // Always output uptime
        logging.warn(
            tpl(messages.ghostWasRunningFor),
            moment.duration(process.uptime(), 'seconds').humanize()
        );
    }
}

module.exports = GhostServer;
<|endoftext|>


<commit_before>module('users.timfelgentreff.babelsberg.deltablue_ext').requires('users.timfelgentreff.deltablue.deltablue').toRun(function() {

Function.addMethods({
    shouldBeSatisfiedWith: function(priority, methods, ctx) {
        // method for deltablue constraint (for now)
        if (!ctx) {
            ctx = methods;
            methods = priority;
            priority = DBStrength.required;
        }
        return DBPlanner.getInstance().always({
            priority: priority,
            methods: methods,
            ctx: ctx
        }, this);
    }
});

DBPlanner.addMethods({
    isConstraintObject: function() {
        return true;
    },
    constraintVariableFor: function(value, ivarname) {
        return new DBVariable(ivarname, value, this);
    },
    get strength() {
        return DBStrength;
    },
    always: function(opts, func) {
        if (Object.isString(opts.priority)) {
            opts.priority = this.strength[opts.priority];
        }

        var planner = this,
            ctx = opts.ctx,
            priority = opts.priority,
            methods = opts.methods;
        func.varMapping = ctx;
        if (!methods) {
            methods = func;
            func = undefined;
        }
        debugger
        methods.varMapping = ctx;
        var cobj = new Constraint(methods, planner);
        var formulas = cobj.constraintvariables.collect(function (v) {
            var v = v.externalVariables(planner);
            return v ? v.removeFormula() : null;
        }).compact();

        if (formulas.length > 0) {
            var constraint = new UserDBConstraint(priority, func, function (c) {
                formulas.each(function (m) {
                    var inputs = m.inputs.select(function (input) {
                        return input instanceof DBVariable
                    });
                    dbgOn(inputs.length !== m.inputs.length);
                    c.formula(m.output, inputs, m.func);
                });
            }, planner);
            cobj.addPrimitiveConstraint(constraint);
        };
        cobj.priority = priority;
        cobj.enable();
        return cobj;
    },

    weight: 100,
    addEditVar: function(v) {
        if (!this.currentEdits) {
            this.currentEdits = new DBOrderedCollection();
        }
        var edit = new EditDBConstraint(v, DBStrength.REQUIRED, this);
        this.currentEdits.add(edit);
        return edit;
    },
    solve: function() {
        // not required
    },

    beginEdit: function() {
        if (this.currentEditPlan) {
            throw "Trying to run nested edits - this isn't supported"
        }
        if (!this.currentEdits) {
            throw "No edit variables - cannot beginEdit"
        }
        this.currentEditPlan = this.extractDBPlanFromDBConstraints(this.currentEdits);
    },
    endEdit: function() {
        if (this.currentEdits && this.currentEdits.length !== 0) {
            this.currentEdits.elms.each(function (edit) {
                edit.destroyDBConstraint();
            })
        }
        this.currentEditPlan = null;
    },
    resolveArray: function(newValues) {
        if (!this.currentEdits) {
            throw "resolveArray only valid in edit"
        }
        this.currentEdits.elms.each(function (edit, idx) {
            edit.myOutput.value = newValues[idx];
        })
        this.currentEditPlan.execute();
    }
})

Object.extend(DBPlanner, {
    getInstance: function() {
        if (!this["$$instance"]) {
            this["$$instance"] = new DBPlanner();
        }
        return this["$$instance"];
    },

    resetInstance: function() {
        this["$$instance"] = undefined;
    }
});

Object.extend(DBStrength, {
    required: DBStrength.REQUIRED,
    strong: DBStrength.STRONG_DEFAULT,
    medium: DBStrength.NORMAL,
    weak: DBStrength.WEAK_DEFAULT
});

DBVariable.addMethods({
    isConstraintObject: function() {
        return true;
    },

    stay: function(strength) {
        var cn = new StayDBConstraint(this, strength || DBStrength.WEAK_DEFAULT, this.planner);
        cn.enable();
        this._stayConstraint = cn;
        return cn;
    },
    setReadonly: function(bool) {
        if (bool && !this.readonlyConstraint) {
            var cn = new StayDBConstraint(this, DBStrength.required, this.planner);
            cn.enable();
            this.readonlyConstraint = cn;
            return cn;
        } else if (!bool && this.readonlyConstraint) {
            this.readonlyConstraint.disable();
            this.readonlyConstraint = undefined;
        }
    },
    isReadonly: function() {
        return !!this.readonlyConstraint;
    },

    formula: function (inputs, func) {
        if (!Constraint.current) {
            throw "invalid outside constraint construction"
        }
        // var constraint = new Constraint(func, Constraint.current.solver),
        //     inputs = constraint.constraintvariables
        if (this.__formula__) {
            throw "two formulas for the same variable " + this;
        }
        this.__formula__ = {output: this, inputs: inputs, func: func};
    },

    removeFormula: function () {
        var f = this.__formula__;
        this.__formula__ = undefined;
        if (!f) {
            f = this.deriveFormula();
        }
        return f;
    },
    deriveFormula: function() {
        // TODO
        return;
    },

    removeStay: function() {
        if (this._stayConstraint) {
            try {
                this.planner.removeConstraint(this._stayConstraint);
            } catch(_) {
                this._stayConstraint = null;
            }
        }
    },

    suggestValue: function(value) {
        this.assignValue(value);
    },

    prepareEdit: function() {
        if (this.editConstraint) {
            // ignore?
        } else {
            this.editConstraint = this.planner.addEditVar(this);
        }
    },

    finishEdit: function() {
        this.editConstraint = null;
    },
    cnIdentical: function(other) {
        if (!(other instanceof DBVariable)) {
            other = new DBVariable("___", other, this.planner);
            var stay = new StayDBConstraint(other, DBStrength.required, this.planner);
            stay.enable(DBStrength.required);
        }
        return new EqualityDBConstraint(this, other, DBStrength.required, Constraint.current.solver);
    },
    cnEquals: function(other) {
        var self = this;
        cloneFunc = function (fromObj) {
            if (fromObj.clone) {
                return fromObj.clone();
            } else if (fromObj.copy) {
                return fromObj.copy();
            } else {
                return fromObj; // regress to identity constraint
            }
        }

        return new UserDBConstraint(
            function (c) {
                c.formula(self, [other], cloneFunc);
                c.formula(other, [self], cloneFunc);
            },
            Constraint.current.solver
        );
    },
    equals: function(argument) {
        return this.cnEquals(argument);
    },
})

DBConstraint.addMethods({
    isConstraintObject: function () {
        return true;
    },

    enable: function (priority) {
        this.strength = priority || this.strength;
        this.addDBConstraint()
    },

    disable: function () {
        this.destroyDBConstraint()
    }
});
EqualityDBConstraint.addMethods({
    setExecuteFunction: function (func) {
        var orig = this.execute.$originalFunction || this.execute;
        func.$originalFunction = orig;
        this.execute = func;
    },

    unsetExecuteFunction: function () {
        this.execute = this.execute.$originalFunction || this.execute;
    }
});}) // end of module
<commit_msg>commit stub of formula transform for deltablue<commit_after>module('users.timfelgentreff.babelsberg.deltablue_ext').requires('users.timfelgentreff.deltablue.deltablue').toRun(function() {

Function.addMethods({
    shouldBeSatisfiedWith: function(priority, methods, ctx) {
        // method for deltablue constraint (for now)
        if (!ctx) {
            ctx = methods;
            methods = priority;
            priority = DBStrength.required;
        }
        return DBPlanner.getInstance().always({
            priority: priority,
            methods: methods,
            ctx: ctx
        }, this);
    }
});

JSLoader.loadJs(module('users.timfelgentreff.babelsberg.uglify').uri());
Object.subclass('FormulaTransform', {

});

DBPlanner.addMethods({
    isConstraintObject: function() {
        return true;
    },
    constraintVariableFor: function(value, ivarname) {
        return new DBVariable(ivarname, value, this);
    },
    get strength() {
        return DBStrength;
    },
    always: function(opts, func) {
        if (Object.isString(opts.priority)) {
            opts.priority = this.strength[opts.priority];
        }

        var planner = this,
            ctx = opts.ctx,
            priority = opts.priority,
            methods = opts.methods;
        func.varMapping = ctx;
        if (!methods) {
            methods = func;
            func = undefined;
        }
        debugger
        methods.varMapping = ctx;
        var cobj = new Constraint(methods, planner);
        var formulas = cobj.constraintvariables.collect(function (v) {
            var v = v.externalVariables(planner);
            return v ? v.removeFormula() : null;
        }).compact();

        if (formulas.length > 0) {
            var constraint = new UserDBConstraint(priority, func, function (c) {
                formulas.each(function (m) {
                    var inputs = m.inputs.select(function (input) {
                        return input instanceof DBVariable
                    });
                    dbgOn(inputs.length !== m.inputs.length);
                    c.formula(m.output, inputs, m.func);
                });
            }, planner);
            cobj.addPrimitiveConstraint(constraint);
        };
        cobj.priority = priority;
        cobj.enable();
        return cobj;
    },

    weight: 100,
    addEditVar: function(v) {
        if (!this.currentEdits) {
            this.currentEdits = new DBOrderedCollection();
        }
        var edit = new EditDBConstraint(v, DBStrength.REQUIRED, this);
        this.currentEdits.add(edit);
        return edit;
    },
    solve: function() {
        // not required
    },

    beginEdit: function() {
        if (this.currentEditPlan) {
            throw "Trying to run nested edits - this isn't supported"
        }
        if (!this.currentEdits) {
            throw "No edit variables - cannot beginEdit"
        }
        this.currentEditPlan = this.extractDBPlanFromDBConstraints(this.currentEdits);
    },
    endEdit: function() {
        if (this.currentEdits && this.currentEdits.length !== 0) {
            this.currentEdits.elms.each(function (edit) {
                edit.destroyDBConstraint();
            })
        }
        this.currentEditPlan = null;
    },
    resolveArray: function(newValues) {
        if (!this.currentEdits) {
            throw "resolveArray only valid in edit"
        }
        this.currentEdits.elms.each(function (edit, idx) {
            edit.myOutput.value = newValues[idx];
        })
        this.currentEditPlan.execute();
    }
})

Object.extend(DBPlanner, {
    getInstance: function() {
        if (!this["$$instance"]) {
            this["$$instance"] = new DBPlanner();
        }
        return this["$$instance"];
    },

    resetInstance: function() {
        this["$$instance"] = undefined;
    }
});

Object.extend(DBStrength, {
    required: DBStrength.REQUIRED,
    strong: DBStrength.STRONG_DEFAULT,
    medium: DBStrength.NORMAL,
    weak: DBStrength.WEAK_DEFAULT
});

DBVariable.addMethods({
    isConstraintObject: function() {
        return true;
    },

    stay: function(strength) {
        var cn = new StayDBConstraint(this, strength || DBStrength.WEAK_DEFAULT, this.planner);
        cn.enable();
        this._stayConstraint = cn;
        return cn;
    },
    setReadonly: function(bool) {
        if (bool && !this.readonlyConstraint) {
            var cn = new StayDBConstraint(this, DBStrength.required, this.planner);
            cn.enable();
            this.readonlyConstraint = cn;
            return cn;
        } else if (!bool && this.readonlyConstraint) {
            this.readonlyConstraint.disable();
            this.readonlyConstraint = undefined;
        }
    },
    isReadonly: function() {
        return !!this.readonlyConstraint;
    },

    formula: function (inputs, func) {
        if (!Constraint.current) {
            throw "invalid outside constraint construction"
        }
        // var constraint = new Constraint(func, Constraint.current.solver),
        //     inputs = constraint.constraintvariables
        if (this.__formula__) {
            throw "two formulas for the same variable " + this;
        }
        this.__formula__ = {output: this, inputs: inputs, func: func};
    },

    removeFormula: function () {
        var f = this.__formula__;
        this.__formula__ = undefined;
        if (!f) {
            f = this.deriveFormula();
        }
        return f;
    },
    deriveFormula: function() {
        // TODO
        return;
    },

    removeStay: function() {
        if (this._stayConstraint) {
            try {
                this.planner.removeConstraint(this._stayConstraint);
            } catch(_) {
                this._stayConstraint = null;
            }
        }
    },

    suggestValue: function(value) {
        this.assignValue(value);
    },

    prepareEdit: function() {
        if (this.editConstraint) {
            // ignore?
        } else {
            this.editConstraint = this.planner.addEditVar(this);
        }
    },

    finishEdit: function() {
        this.editConstraint = null;
    },
    cnIdentical: function(other) {
        if (!(other instanceof DBVariable)) {
            other = new DBVariable("___", other, this.planner);
            var stay = new StayDBConstraint(other, DBStrength.required, this.planner);
            stay.enable(DBStrength.required);
        }
        return new EqualityDBConstraint(this, other, DBStrength.required, Constraint.current.solver);
    },
    cnEquals: function(other) {
        var self = this;
        cloneFunc = function (fromObj) {
            if (fromObj.clone) {
                return fromObj.clone();
            } else if (fromObj.copy) {
                return fromObj.copy();
            } else {
                return fromObj; // regress to identity constraint
            }
        }

        return new UserDBConstraint(
            function (c) {
                c.formula(self, [other], cloneFunc);
                c.formula(other, [self], cloneFunc);
            },
            Constraint.current.solver
        );
    },
    equals: function(argument) {
        return this.cnEquals(argument);
    },
})

DBConstraint.addMethods({
    isConstraintObject: function () {
        return true;
    },

    enable: function (priority) {
        this.strength = priority || this.strength;
        this.addDBConstraint()
    },

    disable: function () {
        this.destroyDBConstraint()
    }
});
EqualityDBConstraint.addMethods({
    setExecuteFunction: function (func) {
        var orig = this.execute.$originalFunction || this.execute;
        func.$originalFunction = orig;
        this.execute = func;
    },

    unsetExecuteFunction: function () {
        this.execute = this.execute.$originalFunction || this.execute;
    }
});}) // end of module
<|endoftext|>