<commit_before>/* global config */
const config = require('collections-online/lib/config');
const helpers = require('collections-online/shared/helpers');
// Remove brackets ({}) from the cumulus key to check the asset has the correct relation (backside).
const backsideAssetCumulusKey = helpers.getAssetField('backside').cumulusKey.slice(1, -1);

helpers.documentTitle = (metadata, fallback) => {
  let title = metadata.short_title || fallback || 'Billede uden titel';
  return helpers.capitalizeFirstLetter(title);
};

helpers.documentDescription = (metadata, fallback) => {
  let description = metadata.description || fallback || '';
  return helpers.capitalizeFirstLetter(description);
};

helpers.documentSecondaryDescription = (metadata, fallback) => {
  let description = metadata.secondary_description || fallback || '';
  return helpers.capitalizeFirstLetter(description);
};

helpers.documentLicense = (metadata) => {
  return metadata.license && metadata.license.id;
};

helpers.getBacksideAssets = (metadata) => {
  if (metadata.related && metadata.related.assets) {
    return metadata.related.assets.filter(asset => asset.id).filter(asset => asset.relation === backsideAssetCumulusKey);
  }
  return [];
};

// TODO: Delete this when metadata.catalog has transitioned to .collection
helpers.getDocumentURL = (metadata) => {
  let path = [metadata.collection || metadata.catalog];
  if(Object.keys(config.types).length > 1) {
    path.push(metadata.type);
  }
  path.push(metadata.id);
  return '/' + path.join('/');
};

helpers.determinePlayers = metadata => {
  const players = [];

  // We always have an image.
  players.push({
    type: 'image',
    thumbnailUrl: helpers.getThumbnailURL(metadata, 2000, 'bottom-right'),
    title: helpers.documentTitle(metadata)
  });

  // Add backside if we have one
  if (helpers.hasBacksideAsset(metadata)) {
    players.push({
      type: 'backside',
      thumbnailUrl: helpers.getThumbnailURL(metadata, 2000, 'bottom-right'),
      backsides: helpers.getBacksideAssets(metadata)
    });
  }

  return players;
};

helpers.generateSitemapElements = (metadata) => {
  throw new Exception('Not yet implemented');
};

function getFileDimensionsString(metadata, size) {
  let width = metadata.width_px;
  let height = metadata.height_px;
  if(typeof(size) === 'number') {
    let ratio = width / height;
    if(ratio > 1) {
      width = size;
      height = size / ratio;
    } else {
      width = size * ratio;
      height = size;
    }
  }
  return Math.round(width) + ' × ' + Math.round(height);
}

function generateSizeDownloadOption(optionKey, option) {
  return {
    label: metadata => {
      let dimensions = getFileDimensionsString(metadata, option.size);
      return option.labelPrefix + ' (' + dimensions + ') JPEG';
    },
    filter: (metadata, derived) => {
      return derived.maxSize >= option.size;
    },
    url: metadata => helpers.getDownloadURL(metadata, optionKey),
  };
}

if(config.downloadOptions) {
  // Loop though the download options defined in the configuration and make them
  // available as an iteratable array of 3-method objects
  const AVAILABLE_DOWNLOAD_OPTIONS = Object.keys(config.downloadOptions)
  .map(optionKey => {
    const option = config.downloadOptions[optionKey];
    if(option.size) {
      return generateSizeDownloadOption(optionKey, option);
    } else if(optionKey === 'original-jpeg') {
      return {
        label: metadata => {
          let label = option.labelPrefix;
          return label + ' (' + getFileDimensionsString(metadata) + ') JPEG';
        },
        filter: metadata => {
          return metadata.file_format !== 'JPEG Image';
        },
        url: metadata => helpers.getDownloadURL(metadata, optionKey),
      };
    } else if(optionKey === 'original') {
      return {
        label: metadata => {
          const type = metadata.file_format;
          // TODO: Consider translating the file_format
          const label = option.labelPrefix;
          return label + ' (' + getFileDimensionsString(metadata) + ') ' + type;
        },
        filter: metadata => {
          return true; // Let's always allow download of the original
        },
        url: metadata => helpers.getDownloadURL(metadata),
      };
    } else {
      throw new Error('Expected "orignal", "original-jpeg" or a size field');
    }
  });

  helpers.getDownloadOptions = (metadata) => {
    let derived = {
      maxSize: Math.max(metadata.width_px, metadata.height_px)
    };

    return AVAILABLE_DOWNLOAD_OPTIONS.filter(option => {
      return option.filter(metadata, derived);
    }).map(option => {
      return {
        label: option.label(metadata, derived),
        url: option.url(metadata, derived)
      };
    });
  };
}

helpers.isDownloadable = (metadata) => {
  return !metadata.license || metadata.license.id !== 7;
};

helpers.hasBacksideAsset = (metadata) => {
  let backsideAssets = helpers.getBacksideAssets(metadata);
  return backsideAssets.length > 0;
};

helpers.hasRelations = metadata => {
  // Filter out backside assets.
  if (metadata.related.assets) {
    return metadata.related.assets.filter(asset => asset.relation !== backsideAssetCumulusKey).length > 0;
  }
  return false;
};

helpers.isWatermarkRequired = (metadata) => {
  if(metadata.license) {
    const licenseMapped = config.licenseMapping[metadata.license.id];
    return licenseMapped && licenseMapped.watermark;
  } else {
    return false;
  }
};

helpers.cleanDocumentId = (id) => {
  // We simply return the id ..
  return id;
};

helpers.modifySearchQueryBody = (body, parameters) => {
  const q = (parameters.filters && parameters.filters.q) || '';
  // Boost the vision tags negatively
  // https://www.elastic.co/guide/en/elasticsearch/reference/2.3/query-dsl-boosting-query.html
  return {
    'query': {
      'boosting': {
        'positive': body.query,
        'negative': {
          'query_string': {
            'default_operator': 'OR',
            'default_field': 'tags_vision',
            'query': q
          }
        },
        'negative_boost' : 0.5
      }
    },
    'sort': body['sort']
  };
};

helpers.motifTagging = {
  getTags: metadata => metadata.tags || [],
  getVerifiedTags: metadata => metadata.tags_verified || [],
  getVisionTags: metadata => metadata.tags_vision || [],

  hasTags: metadata => {
    const { getTags, getVerifiedTags } = helpers.motifTagging;

    return getTags(metadata).length > 0 || getVerifiedTags(metadata).length > 0
  },

  addTag: (metadata, tag) => {
    // Add it to the tags if not already there
    if(metadata.tags.indexOf(tag) === -1) {
      metadata.tags.push(tag);
    }
    // Remove it from the vision tags if there
    helpers.motifTagging.removeVisionTag(metadata, tag);
  },
  removeTag: (metadata, tag) => {
    // Is it there?
    const tagIndex = metadata.tags.indexOf(tag);
    if(tagIndex > -1) {
      // Remove it
      metadata.tags.splice(tagIndex, 1);
    }
  },
  removeVisionTag: (metadata, tag) => {
    // Is it there?
    const visionTagIndex = metadata.tags_vision.indexOf(tag);
    if(visionTagIndex > -1) {
      // Remove it
      metadata.tags_vision.splice(visionTagIndex, 1);
    }
  }
};

helpers.geoTagging = {
  getLocation: metadata => {
    return {
      latitude: metadata.latitude,
      longitude: metadata.longitude,
      heading: parseFloat(metadata.heading, 10),
      isApproximate: metadata.location_is_approximate
    }
  },
  getAddress: metadata => {
    return helpers.geoTagging.getAddressRaw(metadata).filter(s => s).join(', ');
  },
  getAddressForMaps: metadata => {
    return helpers.geoTagging.getAddressRaw(metadata).filter(s => s).join('+');
  },
  getAddressRaw: metadata => {
    return [
      metadata.place,
      metadata.street_name,
      metadata.street_number,
      metadata.floor,
      metadata.district,
      metadata.zipcode,
      metadata.city,
      metadata.country
    ];
  },
  enabled: metadata => !metadata.google_maps_coordinates
};

module.exports = helpers;
<commit_msg>Support generating sitemap assets<commit_after>/* global config */
const config = require('collections-online/lib/config');
const helpers = require('collections-online/shared/helpers');
// Remove brackets ({}) from the cumulus key to check the asset has the correct relation (backside).
const backsideAssetCumulusKey = helpers.getAssetField('backside').cumulusKey.slice(1, -1);

helpers.documentTitle = (metadata, fallback) => {
  let title = metadata.short_title || fallback || 'Billede uden titel';
  return helpers.capitalizeFirstLetter(title);
};

helpers.documentDescription = (metadata, fallback) => {
  let description = metadata.description || fallback || '';
  return helpers.capitalizeFirstLetter(description);
};

helpers.documentSecondaryDescription = (metadata, fallback) => {
  let description = metadata.secondary_description || fallback || '';
  return helpers.capitalizeFirstLetter(description);
};

helpers.documentLicense = (metadata) => {
  return metadata.license && metadata.license.id;
};

helpers.getBacksideAssets = (metadata) => {
  if (metadata.related && metadata.related.assets) {
    return metadata.related.assets.filter(asset => asset.id).filter(asset => asset.relation === backsideAssetCumulusKey);
  }
  return [];
};

// TODO: Delete this when metadata.catalog has transitioned to .collection
helpers.getDocumentURL = (metadata) => {
  let path = [metadata.collection || metadata.catalog];
  if(Object.keys(config.types).length > 1) {
    path.push(metadata.type);
  }
  path.push(metadata.id);
  return '/' + path.join('/');
};

helpers.determinePlayers = metadata => {
  const players = [];

  // We always have an image.
  players.push({
    type: 'image',
    thumbnailUrl: helpers.getThumbnailURL(metadata, 2000, 'bottom-right'),
    title: helpers.documentTitle(metadata)
  });

  // Add backside if we have one
  if (helpers.hasBacksideAsset(metadata)) {
    players.push({
      type: 'backside',
      thumbnailUrl: helpers.getThumbnailURL(metadata, 2000, 'bottom-right'),
      backsides: helpers.getBacksideAssets(metadata)
    });
  }

  return players;
};

/**
 * Generate a site-map entry for single asset.
 *
 * @param req
 *   Express request
 *
 * @param metadata
 *   ES asset data
 */
helpers.generateSitemapElements = (req, metadata) => {
  // Pull out the data we need for the _image_.
  const documentTitle = helpers.documentTitle(metadata);
  const documentDescription = helpers.documentDescription(metadata);
  const relativeThumbnailUrl = helpers.getThumbnailURL(metadata, 2000, 'bottom-right');
  const thumbnailUrl = helpers.getAbsoluteURL(req, relativeThumbnailUrl);
  const license = helpers.licenseMapped(metadata);
  const licenseUrl = license ? license.url : null;

  // Get the available players for the asset and go trough them to produce image
  // sections for the sitemap.
  // See https://www.google.com/schemas/sitemap-image/1.1/
  const players = helpers.determinePlayers(metadata);

  const elements = [];
  players.forEach(player => {

    if (player.type === 'image') {
      elements.push({
        type: 'image',
        location: thumbnailUrl,
        title: documentTitle,
        documentDescription,
        licenseUrl
      });
    }

    // Backsides are related assets, so if we have one we have to go trough
    // a couple of additional steps to get a hold of the thumbnails.
    if (player.type === 'backside') {
      // See https://www.google.com/schemas/sitemap-image/1.1/
      player.backsides.forEach((backside) => {
        // To speed things up we avoid loading the related assets via ES,
        // instead we syntizice whatever we need from the "parent" asset.
        // Inherit the collection.
        backside.collection = metadata.collection;
        // Remove the collection from the asset id, eg we go from
        // kbh-museum-49054 to 49054.
        backside.id = backside.id.substring(backside.collection.length+1);

        const backsideRelativeThumbnailUrl = helpers.getThumbnailURL(backside, 2000, 'bottom-right');
        const backsideThumbnailUrl = helpers.getAbsoluteURL(req, backsideRelativeThumbnailUrl);
        elements.push({
          type: 'image',
          location: backsideThumbnailUrl,
          title: player.title || `Bagsiden af billedet "${documentTitle}"`,
          description: false,
          licenseUrl
        });
      });
    }

  });
  return elements;
};

function getFileDimensionsString(metadata, size) {
  let width = metadata.width_px;
  let height = metadata.height_px;
  if(typeof(size) === 'number') {
    let ratio = width / height;
    if(ratio > 1) {
      width = size;
      height = size / ratio;
    } else {
      width = size * ratio;
      height = size;
    }
  }
  return Math.round(width) + ' × ' + Math.round(height);
}

function generateSizeDownloadOption(optionKey, option) {
  return {
    label: metadata => {
      let dimensions = getFileDimensionsString(metadata, option.size);
      return option.labelPrefix + ' (' + dimensions + ') JPEG';
    },
    filter: (metadata, derived) => {
      return derived.maxSize >= option.size;
    },
    url: metadata => helpers.getDownloadURL(metadata, optionKey),
  };
}

if(config.downloadOptions) {
  // Loop though the download options defined in the configuration and make them
  // available as an iteratable array of 3-method objects
  const AVAILABLE_DOWNLOAD_OPTIONS = Object.keys(config.downloadOptions)
  .map(optionKey => {
    const option = config.downloadOptions[optionKey];
    if(option.size) {
      return generateSizeDownloadOption(optionKey, option);
    } else if(optionKey === 'original-jpeg') {
      return {
        label: metadata => {
          let label = option.labelPrefix;
          return label + ' (' + getFileDimensionsString(metadata) + ') JPEG';
        },
        filter: metadata => {
          return metadata.file_format !== 'JPEG Image';
        },
        url: metadata => helpers.getDownloadURL(metadata, optionKey),
      };
    } else if(optionKey === 'original') {
      return {
        label: metadata => {
          const type = metadata.file_format;
          // TODO: Consider translating the file_format
          const label = option.labelPrefix;
          return label + ' (' + getFileDimensionsString(metadata) + ') ' + type;
        },
        filter: metadata => {
          return true; // Let's always allow download of the original
        },
        url: metadata => helpers.getDownloadURL(metadata),
      };
    } else {
      throw new Error('Expected "orignal", "original-jpeg" or a size field');
    }
  });

  helpers.getDownloadOptions = (metadata) => {
    let derived = {
      maxSize: Math.max(metadata.width_px, metadata.height_px)
    };

    return AVAILABLE_DOWNLOAD_OPTIONS.filter(option => {
      return option.filter(metadata, derived);
    }).map(option => {
      return {
        label: option.label(metadata, derived),
        url: option.url(metadata, derived)
      };
    });
  };
}

helpers.isDownloadable = (metadata) => {
  return !metadata.license || metadata.license.id !== 7;
};

helpers.hasBacksideAsset = (metadata) => {
  let backsideAssets = helpers.getBacksideAssets(metadata);
  return backsideAssets.length > 0;
};

helpers.hasRelations = metadata => {
  // Filter out backside assets.
  if (metadata.related.assets) {
    return metadata.related.assets.filter(asset => asset.relation !== backsideAssetCumulusKey).length > 0;
  }
  return false;
};

helpers.isWatermarkRequired = (metadata) => {
  if(metadata.license) {
    const licenseMapped = config.licenseMapping[metadata.license.id];
    return licenseMapped && licenseMapped.watermark;
  } else {
    return false;
  }
};

helpers.cleanDocumentId = (id) => {
  // We simply return the id ..
  return id;
};

helpers.modifySearchQueryBody = (body, parameters) => {
  const q = (parameters.filters && parameters.filters.q) || '';
  // Boost the vision tags negatively
  // https://www.elastic.co/guide/en/elasticsearch/reference/2.3/query-dsl-boosting-query.html
  return {
    'query': {
      'boosting': {
        'positive': body.query,
        'negative': {
          'query_string': {
            'default_operator': 'OR',
            'default_field': 'tags_vision',
            'query': q
          }
        },
        'negative_boost' : 0.5
      }
    },
    'sort': body['sort']
  };
};

helpers.motifTagging = {
  getTags: metadata => metadata.tags || [],
  getVerifiedTags: metadata => metadata.tags_verified || [],
  getVisionTags: metadata => metadata.tags_vision || [],

  hasTags: metadata => {
    const { getTags, getVerifiedTags } = helpers.motifTagging;

    return getTags(metadata).length > 0 || getVerifiedTags(metadata).length > 0
  },

  addTag: (metadata, tag) => {
    // Add it to the tags if not already there
    if(metadata.tags.indexOf(tag) === -1) {
      metadata.tags.push(tag);
    }
    // Remove it from the vision tags if there
    helpers.motifTagging.removeVisionTag(metadata, tag);
  },
  removeTag: (metadata, tag) => {
    // Is it there?
    const tagIndex = metadata.tags.indexOf(tag);
    if(tagIndex > -1) {
      // Remove it
      metadata.tags.splice(tagIndex, 1);
    }
  },
  removeVisionTag: (metadata, tag) => {
    // Is it there?
    const visionTagIndex = metadata.tags_vision.indexOf(tag);
    if(visionTagIndex > -1) {
      // Remove it
      metadata.tags_vision.splice(visionTagIndex, 1);
    }
  }
};

helpers.geoTagging = {
  getLocation: metadata => {
    return {
      latitude: metadata.latitude,
      longitude: metadata.longitude,
      heading: parseFloat(metadata.heading, 10),
      isApproximate: metadata.location_is_approximate
    }
  },
  getAddress: metadata => {
    return helpers.geoTagging.getAddressRaw(metadata).filter(s => s).join(', ');
  },
  getAddressForMaps: metadata => {
    return helpers.geoTagging.getAddressRaw(metadata).filter(s => s).join('+');
  },
  getAddressRaw: metadata => {
    return [
      metadata.place,
      metadata.street_name,
      metadata.street_number,
      metadata.floor,
      metadata.district,
      metadata.zipcode,
      metadata.city,
      metadata.country
    ];
  },
  enabled: metadata => !metadata.google_maps_coordinates
};

module.exports = helpers;
<|endoftext|>


<commit_before>var plugin = {
              name        : 'greet',
              trigger     : ['hi', 'hello', 'hey', 'whatsup', 'yo', 'whattup', 'wattup', 'how are you', 'hows it going', 'wassup', 'whatsup'],
              enabled     : 'true',
              fuzzy       : 'true',
              description : '',
              usage       : ''
             };

module.exports.plugin = plugin;

module.exports[plugin.name] = function(get)
{

    var generic = "Hello " + get.firstName;
    var greetings = ['excellent', 'superb', 'wonderful'];

    if(Util.it_has(get.fullMessage, 'it goin') || Util.it_has(get.fullMessage, 'e you'))
    {
        sendMessage(generic + ", I'm " + Util.chooseRandom(greetings) + ", fine thank you");
    }
    else if(Util.it_has(get.fullMessage, 'dawg') || Util.it_has(get.fullMessage, 'dog'))
    {
        sendMessage("Yo Dawg");
    }
    else
    {
        sendMessage(generic);
    }

    return true;
}
<commit_msg>New greeting case added<commit_after>var plugin = {
              name        : 'greet',
              trigger     : ['hi', 'hello', 'hey', 'whatsup', 'yo', 'whattup', 'wattup', 'how are you', 'hows it going', 'wassup', 'whatsup', 'how you doin', 'how are you doing'],
              enabled     : 'true',
              fuzzy       : 'true',
              description : '',
              usage       : ''
             };

module.exports.plugin = plugin;

module.exports[plugin.name] = function(get)
{

    var generic = "Hello " + get.firstName;
    var greetings = ['excellent', 'superb', 'wonderful'];

    if(Util.it_has(get.fullMessage, 'it goin') || Util.it_has(get.fullMessage, 'e you'))
    {
        sendMessage(generic + ", I'm " + Util.chooseRandom(greetings) + ", fine thank you");
    }
    if(Util.it_has(get.fullMessage, 'you doin'))
    {
        sendMessage(generic + ", I'm " + Util.chooseRandom(greetings) + ", fine thank you");
    }
    else if(Util.it_has(get.fullMessage, 'dawg') || Util.it_has(get.fullMessage, 'dog'))
    {
        sendMessage("Yo Dawg");
    }
    else
    {
        sendMessage(generic);
    }

    return true;
}
<|endoftext|>


<commit_before>// Require Backbone, underscore, if we're on the server.
// @TODO if we use the keyword 'var' in front of Backbone, _, IE will wipe the
// globally defined Backbone and underscore leaving us with broken objects.
// This is obviously not ideal.
if (typeof require !== 'undefined') {
    Backbone = require('backbone-filesystem');
    _ = require('underscore')._;
}

/**
 * Model: Settings
 *
 * Settings model. Stores any user-specific configuration related to the app.
 */
var Settings = Backbone.Model.extend({
    /**
     * Model name used for storage.
     */
    type: 'settings',
    /**
     * Override url() method for convenience so we don't always need a
     * collection reference around for CRUD operations on a single model.
     */
    url: function() {
        return '/api/Settings/' + this.id;
    },
    /**
     * Validate settings.
     */
    validate: function(attributes) {
        if (typeof attributes.mode !== 'undefined' && attributes.mode !== 'normal' && attributes.mode !== 'minimal') {
            return 'Invalid editor mode specified.';
        }
    }
});

/**
 * Model: Stylesheet
 *
 * This model is *not* backed directly by the server.
 * It is a child model of Project and is saved serialized as part of the parent
 * Project model.
 */
var Stylesheet = Backbone.Model.extend({
    initialize: function() {
        if (!this.get('data')) {
            this.set({ 'data': '' });
        }
    },
    validate: function(attributes) {
        if (/^[a-z0-9\-_.]+$/i.test(attributes.id) === false) {
            return 'Name must contain no space and only letters, numbers, dashes, underscores and periods.';
        }
    }
});

/**
 * Collection: StylesheetList
 *
 * This collection is *not* backed directly by the server.
 * This collection is a child of the Project model. When it is updated
 * (add/remove events) it updates the attributes of its parent model as well.
 */
var StylesheetList = Backbone.Collection.extend({
    model: Stylesheet,
    initialize: function(models, options) {
        var that = this;
        this.parent = options.parent;
        this.bind('change', function() {
            this.parent.set({ 'Stylesheet': that });
            this.parent.change();
        });
        this.bind('add', function() {
            this.parent.set({ 'Stylesheet': that });
            this.parent.change();
        });
        this.bind('remove', function() {
            this.parent.set({ 'Stylesheet': that });
            this.parent.change();
        });
    }
});

/**
 * Model: Layer
 *
 * This model is *not* backed directly by the server.
 * It is a child model of Project and is saved serialized as part of the parent
 * Project model.
 */
var Layer = Backbone.Model.extend({
    // @TODO either as a feature or a bug, object attributes are not set
    // automatically when passed to the constructor. We set it manually here.
    initialize: function(attributes) {
        this.set({'Datasource': attributes.Datasource});
    },
    validate: function(attributes) {
        if (/^[a-z0-9\-_]+$/i.test(attributes.id) === false) {
            return 'ID must contain only letters, numbers, dashes, and underscores.';
        }
        if (attributes['class'] && /^[a-z0-9\-_ ]+$/i.test(attributes['class']) === false) {
            return 'Class must contain only letters, numbers, dashes, and underscores.';
        }
        if (attributes.Datasource && !attributes.Datasource.file) {
            return 'Supplying a datasource is required.';
        }
    }
});

/**
 * Collection: LayerList
 *
 * This collection is *not* backed directly by the server.
 * This collection is a child of the Project model. When it is updated
 * (add/remove events) it updates the attributes of its parent model as well.
 */
var LayerList = Backbone.Collection.extend({
    model: Layer,
    initialize: function(models, options) {
        var self = this;
        this.parent = options.parent;
        this.bind('change', function() {
            this.parent.set({ 'Layer': self });
            this.parent.change();
        });
        this.bind('add', function() {
            this.parent.set({ 'Layer': self });
            this.parent.change();
        });
        this.bind('remove', function() {
            this.parent.set({ 'Layer': self });
            this.parent.change();
        });
    }
});

/**
 * Model: LayerFields
 *
 * This is a read-only model of inspection metadata about a map layer.
 */
var LayerFields = Backbone.Model.extend({
    // @TODO either as a feature or a bug, object attributes are not set
    // automatically when passed to the constructor. We set it manually here.
    initialize: function(attributes, options) {
        this.set({'fields': attributes.fields});
        this.project = options.project;
    },
    url: function() {
        return '/api/' + this.project.project64({ signed: true }) + '/' + this.id;
    }
});

/**
 * Model: Project
 *
 * This model represents a single TileMill project. It is used both client-side
 * and server-side for setting defaults and handling validation.
 */
var Project = Backbone.Model.extend({
    SRS_DEFAULT: '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 '
    + '+lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs',
    STYLESHEET_DEFAULT: [{
        id: 'style.mss',
        data: 'Map {\n'
            + '  background-color: #fff;\n'
            + '}\n\n'
            + '#world {\n'
            + '  polygon-fill: #eee;\n'
            + '  line-color: #ccc;\n'
            + '  line-width: 0.5;\n'
            + '}'
    }],
    LAYER_DEFAULT: [{
        id: 'world',
        name: 'world',
        srs: '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 '
        + '+lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs',
        Datasource: {
            file: 'http://tilemill-data.s3.amazonaws.com/world_borders_merc.zip',
            type: 'shape'
        }
    }],
    /**
     * Model name used for storage.
     */
    type: 'project',
    /**
     * Custom setDefaults() method for creating a project with default layers,
     * stylesheets, etc. Note that we do not use Backbone native initialize()
     * or defaults(), both of which make default values far pervasive than the
     * expected use here.
     */
    setDefaults: function() {
        if (!this.get('srs')) {
            this.set({'srs': this.SRS_DEFAULT});
        }
        if (!this.get('Stylesheet')) {
            this.set({
                'Stylesheet': new StylesheetList(this.STYLESHEET_DEFAULT, {
                    parent: this
                })
            });
        }
        if (!this.get('Layer')) {
            this.set({
                'Layer': new LayerList(this.LAYER_DEFAULT, {
                    parent: this
                })
            });
        }
    },
    /**
     * Instantiate StylesheetList and LayerList collections from JSON lists
     * of plain JSON objects.
     */
    parse: function(response) {
        var self = this;
        response.Stylesheet = new StylesheetList(response.Stylesheet ?
                response.Stylesheet :
                [], { parent: this });
        response.Layer = new LayerList(response.Layer ?
                response.Layer : [], { parent: this });
        return response;
    },
    /**
     * Override url() method for convenience so we don't always need a
     * collection reference around for CRUD operations on a single model.
     */
    url: function() {
        return '/api/Project/' + this.id;
    },
    /**
     * Base64 encode this project's MML URL.
     */
    project64: function(options) {
        // `window.location.origin` is not available in all browsers like
        // Firefox. @TODO This approach won't allow TileMill to be installed in
        // a subdirectory. Fix.
        var url = [
            window.location.protocol,
            window.location.host].join('//') + this.url();
        if (options.signed) {
            var md5 = new MD5();
            url += '?' + md5.digest(JSON.stringify(this)).substr(0, 6);
        }
        return Base64.urlsafe_encode(url);
    },
    /**
     * Layer URL based on the model URL.
     */
    layerURL: function(options) {
        return [window.location.protocol, window.location.host].join('//') + '/';
    },
    /**
     * Native Backbone validation method.
     */
    validate: function(attributes) {
        // Test character set of model ID.
        if (typeof attributes.id !== 'undefined') {
            if (/^[a-z0-9\-_]+$/i.test(attributes.id) === false) {
                return 'Name must contain only letters, numbers, dashes, '
                    + 'and underscores.';
            }
        }
        // Test that there is at least one stylesheet.
        if (typeof attributes.Stylesheet !== 'undefined') {
            var stylesheet = attributes.Stylesheet instanceof StylesheetList
                ? attributes.Stylesheet.models
                : attributes.Stylesheet;
            if (stylesheet.length === 0) {
                return 'No stylesheets found.';
            }
            // Test that each stylesheet has a unique ID.
            var counts = _.reduce(_.pluck(stylesheet, 'id'), function(memo, val) {
                memo[val] = memo[val] ? memo[val] + 1 : 1;
                return memo;
            }, {});
            if (_.max(_.values(counts)) > 1) {
                return 'Stylesheet IDs must be unique.';
            }
        }
    },
    /**
     * Custom validation method that allows for asynchronous processing.
     * Expects options.success and options.error callbacks to be consistent
     * with other Backbone methods.
     */
    validateAsync: function(options) {
        // If client-side, pass-through.
        if (typeof require === 'undefined') { options.success(this, null) }

        var Step = require('step');
        var mess = require('mess');
        var that = this;
        var stylesheets = this.get('Stylesheet');
        var stylesheets = stylesheets instanceof StylesheetList
            ? stylesheets.toJSON()
            : stylesheets;

        Step(
            function() {
                var group = this.group();
                if (stylesheets.length !== 0) {
                    _.each(stylesheets, function(stylesheet) {
                        new(mess.Parser)({ filename: stylesheet.id })
                            .parse(stylesheet.data, function(err, tree) {
                            if (!err) {
                                try {
                                    var errors = null;
                                    var l = tree.toList();
                                    var errorpool = { returnErrors: true, errors: [] };
                                    l.map(function(t) {
                                        t.toXML(errorpool);
                                    });
                                    if (errorpool.errors.length) {
                                        group()(errorpool.errors.map(function(r) {
                                            // TODO: line numbers are one less
                                            // than expected.
                                            r.line = tree.getLine(r.index) + 1;
                                            r.filename = stylesheet.id;
                                            return r;
                                        }));
                                    }
                                    else {
                                        group()(null);
                                    }
                                } catch (e) {
                                    group()([e]);
                                }
                            } else {
                                group()([ err ]);
                            }
                        });
                    });
                }
                else {
                    group()('No stylesheets found.');
                }
            },
            function(err, res) {
                if (err) {
                    options.error(that, err);
                }
                else {
                    options.success(that, null);
                }
            }
        );
    }
});

/**
 * Collection: ProjectList
 *
 * Collection of project models.
 */
var ProjectList = Backbone.Collection.extend({
    model: Project,
    url: '/api/Project',
    /**
     * Model name used for storage.
     */
    type: 'project',
    comparator: function(project) {
        return project.get('id');
    }
});

/**
 * Model: ExportJob
 *
 * Job model.
 */
var ExportJob = Backbone.Model.extend({
    /**
     * Model name used for storage.
     */
    type: 'exportjob',
    initialize: function() {
        if (this.isNew()) {
            var date = new Date();
            this.set({timestamp: date.getTime()});
            if (typeof MD5 !== 'undefined') {
                var md5 = new MD5();
                var date = new Date();
                md5.digest(JSON.stringify(this)).substr(0, 6);
                this.set({'id': md5.digest(JSON.stringify(this) + date.getTime()).substr(0, 6)});
            }
        }
    },
    /**
     * Override url() method for convenience so we don't always need a
     * collection reference around for CRUD operations on a single model.
     */
    url: function() {
        return '/api/ExportJob/' + this.id;
    },
    defaults: {
        progress: 0,
        status: 'waiting'
    },
    validate: function(attributes) {
        if (attributes.status && ['waiting', 'processing', 'complete', 'error'].indexOf(attributes.status) === -1) {
            return 'Invalid status.';
        }
        if (attributes.progress && (typeof attributes.progress !== 'number' || attributes.progress > 1 || attributes.progress < 0)) {
            return 'Progress must be a value between 0 and 1 (inclusive).';
        }
    },
    /**
     * Generate a download URL for a model.
     */
    downloadURL: function() {
        return (this.get('status') === 'complete') && '/export/download/' + this.get('filename');
    },
    /**
     * Allow the export to add tasks to the task queue.
     */
    addTasks: function(taskQueue) {
        return require('jobtasks')(this, taskQueue);
    }
});

/**
 * Collection: ExportJobList
 *
 * A queue of job models.
 */
var ExportJobList = Backbone.Collection.extend({
    model: ExportJob,
    url: '/api/ExportJob',
    /**
     * Model name used for storage.
     */
    type: 'exportjob',
    comparator: function(job) {
        return job.get('timestamp');
    }
});

if (typeof module !== 'undefined') {
    module.exports = {
        Project: Project,
        ProjectList: ProjectList,
        ExportJob: ExportJob,
        ExportJobList: ExportJobList,
        Settings: Settings
    };
}

<commit_msg>Sending env to toList<commit_after>// Require Backbone, underscore, if we're on the server.
// @TODO if we use the keyword 'var' in front of Backbone, _, IE will wipe the
// globally defined Backbone and underscore leaving us with broken objects.
// This is obviously not ideal.
if (typeof require !== 'undefined') {
    Backbone = require('backbone-filesystem');
    _ = require('underscore')._;
}

/**
 * Model: Settings
 *
 * Settings model. Stores any user-specific configuration related to the app.
 */
var Settings = Backbone.Model.extend({
    /**
     * Model name used for storage.
     */
    type: 'settings',
    /**
     * Override url() method for convenience so we don't always need a
     * collection reference around for CRUD operations on a single model.
     */
    url: function() {
        return '/api/Settings/' + this.id;
    },
    /**
     * Validate settings.
     */
    validate: function(attributes) {
        if (typeof attributes.mode !== 'undefined' && attributes.mode !== 'normal' && attributes.mode !== 'minimal') {
            return 'Invalid editor mode specified.';
        }
    }
});

/**
 * Model: Stylesheet
 *
 * This model is *not* backed directly by the server.
 * It is a child model of Project and is saved serialized as part of the parent
 * Project model.
 */
var Stylesheet = Backbone.Model.extend({
    initialize: function() {
        if (!this.get('data')) {
            this.set({ 'data': '' });
        }
    },
    validate: function(attributes) {
        if (/^[a-z0-9\-_.]+$/i.test(attributes.id) === false) {
            return 'Name must contain no space and only letters, numbers, dashes, underscores and periods.';
        }
    }
});

/**
 * Collection: StylesheetList
 *
 * This collection is *not* backed directly by the server.
 * This collection is a child of the Project model. When it is updated
 * (add/remove events) it updates the attributes of its parent model as well.
 */
var StylesheetList = Backbone.Collection.extend({
    model: Stylesheet,
    initialize: function(models, options) {
        var that = this;
        this.parent = options.parent;
        this.bind('change', function() {
            this.parent.set({ 'Stylesheet': that });
            this.parent.change();
        });
        this.bind('add', function() {
            this.parent.set({ 'Stylesheet': that });
            this.parent.change();
        });
        this.bind('remove', function() {
            this.parent.set({ 'Stylesheet': that });
            this.parent.change();
        });
    }
});

/**
 * Model: Layer
 *
 * This model is *not* backed directly by the server.
 * It is a child model of Project and is saved serialized as part of the parent
 * Project model.
 */
var Layer = Backbone.Model.extend({
    // @TODO either as a feature or a bug, object attributes are not set
    // automatically when passed to the constructor. We set it manually here.
    initialize: function(attributes) {
        this.set({'Datasource': attributes.Datasource});
    },
    validate: function(attributes) {
        if (/^[a-z0-9\-_]+$/i.test(attributes.id) === false) {
            return 'ID must contain only letters, numbers, dashes, and underscores.';
        }
        if (attributes['class'] && /^[a-z0-9\-_ ]+$/i.test(attributes['class']) === false) {
            return 'Class must contain only letters, numbers, dashes, and underscores.';
        }
        if (attributes.Datasource && !attributes.Datasource.file) {
            return 'Supplying a datasource is required.';
        }
    }
});

/**
 * Collection: LayerList
 *
 * This collection is *not* backed directly by the server.
 * This collection is a child of the Project model. When it is updated
 * (add/remove events) it updates the attributes of its parent model as well.
 */
var LayerList = Backbone.Collection.extend({
    model: Layer,
    initialize: function(models, options) {
        var self = this;
        this.parent = options.parent;
        this.bind('change', function() {
            this.parent.set({ 'Layer': self });
            this.parent.change();
        });
        this.bind('add', function() {
            this.parent.set({ 'Layer': self });
            this.parent.change();
        });
        this.bind('remove', function() {
            this.parent.set({ 'Layer': self });
            this.parent.change();
        });
    }
});

/**
 * Model: LayerFields
 *
 * This is a read-only model of inspection metadata about a map layer.
 */
var LayerFields = Backbone.Model.extend({
    // @TODO either as a feature or a bug, object attributes are not set
    // automatically when passed to the constructor. We set it manually here.
    initialize: function(attributes, options) {
        this.set({'fields': attributes.fields});
        this.project = options.project;
    },
    url: function() {
        return '/api/' + this.project.project64({ signed: true }) + '/' + this.id;
    }
});

/**
 * Model: Project
 *
 * This model represents a single TileMill project. It is used both client-side
 * and server-side for setting defaults and handling validation.
 */
var Project = Backbone.Model.extend({
    SRS_DEFAULT: '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 '
    + '+lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs',
    STYLESHEET_DEFAULT: [{
        id: 'style.mss',
        data: 'Map {\n'
            + '  background-color: #fff;\n'
            + '}\n\n'
            + '#world {\n'
            + '  polygon-fill: #eee;\n'
            + '  line-color: #ccc;\n'
            + '  line-width: 0.5;\n'
            + '}'
    }],
    LAYER_DEFAULT: [{
        id: 'world',
        name: 'world',
        srs: '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 '
        + '+lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs',
        Datasource: {
            file: 'http://tilemill-data.s3.amazonaws.com/world_borders_merc.zip',
            type: 'shape'
        }
    }],
    /**
     * Model name used for storage.
     */
    type: 'project',
    /**
     * Custom setDefaults() method for creating a project with default layers,
     * stylesheets, etc. Note that we do not use Backbone native initialize()
     * or defaults(), both of which make default values far pervasive than the
     * expected use here.
     */
    setDefaults: function() {
        if (!this.get('srs')) {
            this.set({'srs': this.SRS_DEFAULT});
        }
        if (!this.get('Stylesheet')) {
            this.set({
                'Stylesheet': new StylesheetList(this.STYLESHEET_DEFAULT, {
                    parent: this
                })
            });
        }
        if (!this.get('Layer')) {
            this.set({
                'Layer': new LayerList(this.LAYER_DEFAULT, {
                    parent: this
                })
            });
        }
    },
    /**
     * Instantiate StylesheetList and LayerList collections from JSON lists
     * of plain JSON objects.
     */
    parse: function(response) {
        var self = this;
        response.Stylesheet = new StylesheetList(response.Stylesheet ?
                response.Stylesheet :
                [], { parent: this });
        response.Layer = new LayerList(response.Layer ?
                response.Layer : [], { parent: this });
        return response;
    },
    /**
     * Override url() method for convenience so we don't always need a
     * collection reference around for CRUD operations on a single model.
     */
    url: function() {
        return '/api/Project/' + this.id;
    },
    /**
     * Base64 encode this project's MML URL.
     */
    project64: function(options) {
        // `window.location.origin` is not available in all browsers like
        // Firefox. @TODO This approach won't allow TileMill to be installed in
        // a subdirectory. Fix.
        var url = [
            window.location.protocol,
            window.location.host].join('//') + this.url();
        if (options.signed) {
            var md5 = new MD5();
            url += '?' + md5.digest(JSON.stringify(this)).substr(0, 6);
        }
        return Base64.urlsafe_encode(url);
    },
    /**
     * Layer URL based on the model URL.
     */
    layerURL: function(options) {
        return [window.location.protocol, window.location.host].join('//') + '/';
    },
    /**
     * Native Backbone validation method.
     */
    validate: function(attributes) {
        // Test character set of model ID.
        if (typeof attributes.id !== 'undefined') {
            if (/^[a-z0-9\-_]+$/i.test(attributes.id) === false) {
                return 'Name must contain only letters, numbers, dashes, '
                    + 'and underscores.';
            }
        }
        // Test that there is at least one stylesheet.
        if (typeof attributes.Stylesheet !== 'undefined') {
            var stylesheet = attributes.Stylesheet instanceof StylesheetList
                ? attributes.Stylesheet.models
                : attributes.Stylesheet;
            if (stylesheet.length === 0) {
                return 'No stylesheets found.';
            }
            // Test that each stylesheet has a unique ID.
            var counts = _.reduce(_.pluck(stylesheet, 'id'), function(memo, val) {
                memo[val] = memo[val] ? memo[val] + 1 : 1;
                return memo;
            }, {});
            if (_.max(_.values(counts)) > 1) {
                return 'Stylesheet IDs must be unique.';
            }
        }
    },
    /**
     * Custom validation method that allows for asynchronous processing.
     * Expects options.success and options.error callbacks to be consistent
     * with other Backbone methods.
     */
    validateAsync: function(options) {
        // If client-side, pass-through.
        if (typeof require === 'undefined') { options.success(this, null) }

        var Step = require('step');
        var mess = require('mess');
        var that = this;
        var stylesheets = this.get('Stylesheet');
        var stylesheets = stylesheets instanceof StylesheetList
            ? stylesheets.toJSON()
            : stylesheets;

        Step(
            function() {
                var group = this.group();
                if (stylesheets.length !== 0) {
                    _.each(stylesheets, function(stylesheet) {
                        new(mess.Parser)({ filename: stylesheet.id })
                            .parse(stylesheet.data, function(err, tree) {
                            if (!err) {
                                try {
                                    var errors = null;
                                    var env = {};
                                    var l = tree.toList(env);
                                    var errorpool = { returnErrors: true, errors: [] };
                                    l.map(function(t) {
                                        t.toXML(errorpool);
                                    });
                                    if (errorpool.errors.length) {
                                        group()(errorpool.errors.map(function(r) {
                                            // TODO: line numbers are one less
                                            // than expected.
                                            r.line = tree.getLine(r.index) + 1;
                                            r.filename = stylesheet.id;
                                            return r;
                                        }));
                                    }
                                    else {
                                        group()(null);
                                    }
                                } catch (e) {
                                    group()([e]);
                                }
                            } else {
                                group()([ err ]);
                            }
                        });
                    });
                }
                else {
                    group()('No stylesheets found.');
                }
            },
            function(err, res) {
                if (err) {
                    options.error(that, err);
                }
                else {
                    options.success(that, null);
                }
            }
        );
    }
});

/**
 * Collection: ProjectList
 *
 * Collection of project models.
 */
var ProjectList = Backbone.Collection.extend({
    model: Project,
    url: '/api/Project',
    /**
     * Model name used for storage.
     */
    type: 'project',
    comparator: function(project) {
        return project.get('id');
    }
});

/**
 * Model: ExportJob
 *
 * Job model.
 */
var ExportJob = Backbone.Model.extend({
    /**
     * Model name used for storage.
     */
    type: 'exportjob',
    initialize: function() {
        if (this.isNew()) {
            var date = new Date();
            this.set({timestamp: date.getTime()});
            if (typeof MD5 !== 'undefined') {
                var md5 = new MD5();
                var date = new Date();
                md5.digest(JSON.stringify(this)).substr(0, 6);
                this.set({'id': md5.digest(JSON.stringify(this) + date.getTime()).substr(0, 6)});
            }
        }
    },
    /**
     * Override url() method for convenience so we don't always need a
     * collection reference around for CRUD operations on a single model.
     */
    url: function() {
        return '/api/ExportJob/' + this.id;
    },
    defaults: {
        progress: 0,
        status: 'waiting'
    },
    validate: function(attributes) {
        if (attributes.status && ['waiting', 'processing', 'complete', 'error'].indexOf(attributes.status) === -1) {
            return 'Invalid status.';
        }
        if (attributes.progress && (typeof attributes.progress !== 'number' || attributes.progress > 1 || attributes.progress < 0)) {
            return 'Progress must be a value between 0 and 1 (inclusive).';
        }
    },
    /**
     * Generate a download URL for a model.
     */
    downloadURL: function() {
        return (this.get('status') === 'complete') && '/export/download/' + this.get('filename');
    },
    /**
     * Allow the export to add tasks to the task queue.
     */
    addTasks: function(taskQueue) {
        return require('jobtasks')(this, taskQueue);
    }
});

/**
 * Collection: ExportJobList
 *
 * A queue of job models.
 */
var ExportJobList = Backbone.Collection.extend({
    model: ExportJob,
    url: '/api/ExportJob',
    /**
     * Model name used for storage.
     */
    type: 'exportjob',
    comparator: function(job) {
        return job.get('timestamp');
    }
});

if (typeof module !== 'undefined') {
    module.exports = {
        Project: Project,
        ProjectList: ProjectList,
        ExportJob: ExportJob,
        ExportJobList: ExportJobList,
        Settings: Settings
    };
}

<|endoftext|>


<commit_before>/*
  shortMethods.js v0.0.2
  For Shmup.js 1.0.11 and newer
  https://github.com/Trung0246/Shmup/new/master/plugins
*/

var MD = {};
MD.rp = function(times, actions) {
  return {
    func: "repeat",
    times: times,
    actions: actions,
  };
};
MD.w = function(type, times) {
  return {
    func: "wait",
    type: type,
    times: times,
  };
};
MD.fr = function(type, label, movement, position, direction, speed) {
  if (typeof movement === "function") {
    return {
      func: "fire",
      type: type,
      label: label,
      movement: movement,
    };
  } else {
    return {
      func: "fire",
      type: type,
      label: label,
      position: position,
      direction: direction,
      speed: speed,
    };
  }
};
MD.d = function(type, value, base, target) {
  return {
    value: value,
    base: base,
    type: type,
    target: target,
  };
};
MD.s = function(HType, HValue, VType, VValue) {
  return {
    horizontal: {
      value: HValue,
      type: HType,
    },
    vertical: {
      value: VValue,
      type: VType,
    },
  };
};
MD.p = function(now, end) {
  return {
    now: now,
    end: end,
  };
};
MD.v = function(type, value) {
  if (type === "current" || type === "all") {
    return {
      func: "vanish",
      type: type,
    };
  } else {
    return {
      func: "vanish",
      type: type,
      value: value,
    };
  }
};
MD.c = function(position, movement, direction, speed) {
  if (typeof movement === "function") {
    return {
      func: "change",
      movement: movement,
    };
  } else {
    return {
      func: "change",
      position: position,
      direction: direction,
      speed: speed,
    };
  }
};
MD.cp = function(now, end, times) {
  return {
    now: now,
    end: end,
    times: times,
  };
};
MD.cd = function(value, times, type) {
  return {
    value: value,
    times: times,
    type: type,
  };
};
MD.cs = function(HValue, HTimes, HType, VValue, VTimes, VType) {
  return {
    horizontal: {
      value: HValue,
      times: HTimes,
      type: HType,
    },
    vertical: {
      value: Vvalue,
      times: VTimes,
      type: VType,
    },
  };
};
MD.fz = function(label, times) {
  return {
    func: "freeze",
    label: label,
    times: times,
  };
};
MD.rs = function(label, type, value) {
  return {
    func: "reset",
    label: label,
    type: type,
    value: value,
  };
};
MD.fc = function(callback) {
  return {
    func: "func",
    callback: callback,
  };
};
<commit_msg>Update shortMethods.js<commit_after>/*
  shortMethods.js v0.0.2
  For Shmup.js 1.0.11 and newer
  https://github.com/Trung0246/Shmup/new/master/plugins
*/

var MD = {}; //For plugins
MD.rp = function(times, actions) {
  return {
    func: "repeat",
    times: times,
    actions: actions,
  };
};
MD.w = function(type, times) {
  return {
    func: "wait",
    type: type,
    times: times,
  };
};
MD.fr = function(type, label, movement, position, direction, speed, actionRef, fireRef) {
  if (typeof movement === "function") {
    return {
      func: "fire",
      type: type,
      label: label,
      movement: movement,
      actionRef: actionRef,
      fireRef: fireRef,
    };
  } else {
    return {
      func: "fire",
      type: type,
      label: label,
      position: position,
      direction: direction,
      speed: speed,
      actionRef: actionRef,
      fireRef: fireRef,
    };
  }
};
MD.d = function(type, value, base, target) {
  return {
    value: value,
    base: base,
    type: type,
    target: target,
  };
};
MD.s = function(HType, HValue, VType, VValue) {
  return {
    horizontal: {
      value: HValue,
      type: HType,
    },
    vertical: {
      value: VValue,
      type: VType,
    },
  };
};
MD.p = function(now, end) {
  return {
    now: now,
    end: end,
  };
};
MD.v = function(type, value) {
  if (type === "current" || type === "all") {
    return {
      func: "vanish",
      type: type,
    };
  } else {
    return {
      func: "vanish",
      type: type,
      value: value,
    };
  }
};
MD.c = function(position, movement, direction, speed) {
  if (typeof movement === "function") {
    return {
      func: "change",
      movement: movement,
    };
  } else {
    return {
      func: "change",
      position: position,
      direction: direction,
      speed: speed,
    };
  }
};
MD.cp = function(now, end, times) {
  return {
    now: now,
    end: end,
    times: times,
  };
};
MD.cd = function(value, times, type) {
  return {
    value: value,
    times: times,
    type: type,
  };
};
MD.cs = function(HValue, HTimes, HType, VValue, VTimes, VType) {
  return {
    horizontal: {
      value: HValue,
      times: HTimes,
      type: HType,
    },
    vertical: {
      value: VValue,
      times: VTimes,
      type: VType,
    },
  };
};
MD.fz = function(label, times) {
  return {
    func: "freeze",
    label: label,
    times: times,
  };
};
MD.rs = function(label, type, value) {
  return {
    func: "reset",
    label: label,
    type: type,
    value: value,
  };
};
MD.fc = function(callback) {
  return {
    func: "func",
    callback: callback,
  };
};
<|endoftext|>


<commit_before>var util = require('util');

exports.init = function (y, config, messages, cron, logger) {
	var yammer_account = config.yammer[config.yammer_account];

	var getHTML = function () {
		var html = ''
			+ '<!DOCTYPE html>'
			+ ''
			+ ''
			+ '<meta charset="utf-8" />'
			+ '<title>PID ' + process.pid + ' ' + y.userAgent() + '</title>'
			+ ''
			+ ''
			+ '
PID ' + process.pid + ' ' + y.userAgent() + '
'
			+ '
' + yammer_account.email + '
'
			+ '
'
			+ '
'
			+ '
Open Threads
'
			+ '
';

		var threads = y.openThreads();
		for (var i = 0; i < threads.length; i++) {
			var thread = threads[i];

			html += '
' + thread.id() + '
'
				+ '

' + util.inspect(thread, false, 3) + '

';
		}

		html += ''
			+ '
'
			+ '
Closed Threads
'
			+ '
';

		threads = y.closedThreads();
		for (var i = 0; i < threads.length; i++) {
			var thread = threads[i];

			html += '
' + thread.id() + '
'
				+ '

' + util.inspect(thread, false, 3) + '

';
		}

		html += ''
			+ '
'
			+ ''
			+ '';

		return html;
	};

	var http = require('http');
	http.createServer(function (req, res) {
		res.writeHead(200, {'Content-Type': 'text/html'});
		res.end(getHTML());
	}).listen(1337, "127.0.0.1");
	console.log('Server running at http://127.0.0.1:1337/');

};
<commit_msg>Changed listen IP<commit_after>var util = require('util');

exports.init = function (y, config, messages, cron, logger) {
	var yammer_account = config.yammer[config.yammer_account];

	var getHTML = function () {
		var html = ''
			+ '<!DOCTYPE html>'
			+ ''
			+ ''
			+ '<meta charset="utf-8" />'
			+ '<title>PID ' + process.pid + ' ' + y.userAgent() + '</title>'
			+ ''
			+ ''
			+ '
PID ' + process.pid + ' ' + y.userAgent() + '
'
			+ '
' + yammer_account.email + '
'
			+ '
'
			+ '
'
			+ '
Open Threads
'
			+ '
';

		var threads = y.openThreads();
		for (var i = 0; i < threads.length; i++) {
			var thread = threads[i];

			html += '
' + thread.id() + '
'
				+ '

' + util.inspect(thread, false, 3) + '

';
		}

		html += ''
			+ '
'
			+ '
Closed Threads
'
			+ '
';

		threads = y.closedThreads();
		for (var i = 0; i < threads.length; i++) {
			var thread = threads[i];

			html += '
' + thread.id() + '
'
				+ '

' + util.inspect(thread, false, 3) + '

';
		}

		html += ''
			+ '
'
			+ ''
			+ '';

		return html;
	};

	var http = require('http');
	http.createServer(function (req, res) {
		res.writeHead(200, {'Content-Type': 'text/html'});
		res.end(getHTML());
	}).listen(1337, "0.0.0.0");

};
<|endoftext|>


<commit_before>"use strict";

// local modules _must_ be explicitly mocked
jest.mock("../lib/get-packages-without-license");
jest.mock("../lib/verify-npm-package-access");
jest.mock("../lib/get-npm-username");
jest.mock("../lib/get-unpublished-packages");
// FIXME: better mock for version command
jest.mock("../../version/lib/git-push");
jest.mock("../../version/lib/is-anything-committed");
jest.mock("../../version/lib/is-behind-upstream");
jest.mock("../../version/lib/remote-branch-exists");

// mocked or stubbed modules
const npmDistTag = require("@lerna/npm-dist-tag");
const npmPublish = require("@lerna/npm-publish");
const PromptUtilities = require("@lerna/prompt");
const collectUpdates = require("@lerna/collect-updates");
const output = require("@lerna/output");
const checkWorkingTree = require("@lerna/check-working-tree");
const getNpmUsername = require("../lib/get-npm-username");
const verifyNpmPackageAccess = require("../lib/verify-npm-package-access");
const getUnpublishedPackages = require("../lib/get-unpublished-packages");
const Project = require("@lerna/project");

// helpers
const loggingOutput = require("@lerna-test/logging-output");
const gitTag = require("@lerna-test/git-tag");
const initFixture = require("@lerna-test/init-fixture")(__dirname);

// file under test
const lernaPublish = require("@lerna-test/command-runner")(require("../command"));

describe("PublishCommand", () => {
  describe("cli validation", () => {
    let cwd;

    beforeAll(async () => {
      cwd = await initFixture("normal");
    });

    it("exits early when no changes found", async () => {
      collectUpdates.setUpdated(cwd);

      await lernaPublish(cwd)();

      const logMessages = loggingOutput("success");
      expect(logMessages).toContain("No changed packages to publish");
      expect(verifyNpmPackageAccess).not.toBeCalled();
    });

    ["from-git", "from-package"].forEach(fromArg => {
      it(`exits early when no changes found ${fromArg}`, async () => {
        collectUpdates.setUpdated(cwd);

        await lernaPublish(cwd)(fromArg);

        const logMessages = loggingOutput("success");
        expect(logMessages).toContain("No changed packages to publish");
        expect(verifyNpmPackageAccess).not.toBeCalled();
      });
    });

    it("exits non-zero with --scope", async () => {
      try {
        await lernaPublish(cwd)("--scope", "package-1");
      } catch (err) {
        expect(err.exitCode).toBe(1);
        expect(err.message).toBe("Unknown argument: scope");
      }

      expect.assertions(2);
    });

    it("exits non-zero with --since", async () => {
      try {
        await lernaPublish(cwd)("--since", "master");
      } catch (err) {
        expect(err.exitCode).toBe(1);
        expect(err.message).toBe("Unknown argument: since");
      }

      expect.assertions(2);
    });
  });

  describe("with implied versioning", () => {
    it("publishes changed packages", async () => {
      const testDir = await initFixture("normal");

      await lernaPublish(testDir)();

      expect(PromptUtilities.confirm).toHaveBeenLastCalledWith(
        "Are you sure you want to publish these packages?"
      );
      expect(npmPublish.packed).toMatchInlineSnapshot(`
Set {
  "package-1",
  "package-3",
  "package-4",
  "package-2",
}
`);
      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
      expect(npmDistTag.check).not.toBeCalled();
      expect(npmDistTag.remove).not.toBeCalled();
      expect(npmDistTag.add).not.toBeCalled();

      expect(getNpmUsername).toHaveBeenCalled();
      expect(getNpmUsername.registry.get(testDir).get("registry")).toBe("https://registry.npmjs.org/");

      expect(verifyNpmPackageAccess).toHaveBeenCalled();
      expect(verifyNpmPackageAccess.registry.get(testDir)).toMatchInlineSnapshot(`
Set {
  "package-1",
  "package-2",
  "package-3",
  "package-4",
  "username: lerna-test",
}
`);
    });

    it("publishes changed independent packages", async () => {
      const testDir = await initFixture("independent");

      await lernaPublish(testDir)();

      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
    });

    it("--skip-npm yields immediately to VersionCommand with warning", async () => {
      const cwd = await initFixture("normal");

      await lernaPublish(cwd)("--skip-npm");

      expect(npmPublish.order()).toHaveLength(0);

      const logMessages = loggingOutput("warn");
      expect(logMessages).toContain("Instead of --skip-npm, call `lerna version` directly");
    });

    it("throws an error in fixed mode when --independent is passed", async () => {
      const testDir = await initFixture("normal");

      try {
        await lernaPublish(testDir)("--independent");
      } catch (err) {
        expect(err.message).toMatch("independent");
      }

      expect.assertions(1);
    });
  });

  describe("from-git", () => {
    it("publishes tagged packages", async () => {
      const testDir = await initFixture("normal");

      await gitTag(testDir, "v1.0.0");
      await lernaPublish(testDir)("from-git");

      // called from chained describeRef()
      expect(checkWorkingTree.throwIfUncommitted).toHaveBeenCalled();

      expect(PromptUtilities.confirm).toHaveBeenLastCalledWith(
        "Are you sure you want to publish these packages?"
      );
      expect(output.logged()).toMatch("Found 4 packages to publish:");
      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
    });

    it("publishes tagged independent packages", async () => {
      const testDir = await initFixture("independent");

      await Promise.all([
        gitTag(testDir, "package-1@1.0.0"),
        gitTag(testDir, "package-2@2.0.0"),
        gitTag(testDir, "package-3@3.0.0"),
        gitTag(testDir, "package-4@4.0.0"),
        gitTag(testDir, "package-5@5.0.0"),
      ]);
      await lernaPublish(testDir)("from-git");

      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
    });

    it("only publishes independent packages with matching tags", async () => {
      const testDir = await initFixture("independent");

      await gitTag(testDir, "package-3@3.0.0");
      await lernaPublish(testDir)("from-git");

      expect(output.logged()).toMatch("Found 1 package to publish:");
      expect(npmPublish.order()).toEqual(["package-3"]);
    });

    it("exits early when the current commit is not tagged", async () => {
      const testDir = await initFixture("normal");

      await lernaPublish(testDir)("from-git");

      expect(npmPublish).not.toBeCalled();

      const logMessages = loggingOutput("info");
      expect(logMessages).toContain("No tagged release found");
    });

    it("throws an error when uncommitted changes are present", async () => {
      checkWorkingTree.throwIfUncommitted.mockImplementationOnce(() => {
        throw new Error("uncommitted");
      });

      const testDir = await initFixture("normal");

      try {
        await lernaPublish(testDir)("from-git");
      } catch (err) {
        expect(err.message).toBe("uncommitted");
        // notably different than the actual message, but good enough here
      }

      expect.assertions(1);
    });
  });

  describe("from-package", () => {
    it("publishes unpublished packages", async () => {
      const testDir = await initFixture("normal");
      const project = new Project(testDir);

      getUnpublishedPackages.mockImplementationOnce(async () => {
        const pkgs = await project.getPackages();
        return pkgs.slice(1, 3);
      });

      await lernaPublish(testDir)("from-package");

      expect(PromptUtilities.confirm).lastCalledWith("Are you sure you want to publish these packages?");
      expect(output.logged()).toMatch("Found 2 packages to publish:");
      expect(npmPublish.order()).toEqual(["package-2", "package-3"]);
    });

    it("publishes unpublished independent packages", async () => {
      const testDir = await initFixture("independent");
      const project = new Project(testDir);

      getUnpublishedPackages.mockImplementationOnce(() => project.getPackages());

      await lernaPublish(testDir)("from-package");

      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
    });

    it("exits early when all packages are published", async () => {
      const testDir = await initFixture("normal");

      await lernaPublish(testDir)("from-package");

      expect(npmPublish).not.toBeCalled();

      const logMessages = loggingOutput("info");
      expect(logMessages).toContain("No unpublished release found");
    });

    it("throws an error when uncommitted changes are present", async () => {
      checkWorkingTree.throwIfUncommitted.mockImplementationOnce(() => {
        throw new Error("uncommitted");
      });

      const testDir = await initFixture("normal");

      try {
        await lernaPublish(testDir)("from-package");
      } catch (err) {
        expect(err.message).toBe("uncommitted");
        // notably different than the actual message, but good enough here
      }

      expect.assertions(1);
    });
  });

  describe("--registry", () => {
    it("passes registry to npm commands", async () => {
      const testDir = await initFixture("normal");
      const registry = "https://my-private-registry";

      await lernaPublish(testDir)("--registry", registry);

      expect(npmPublish).toHaveBeenCalledWith(
        expect.objectContaining({ name: "package-1" }),
        undefined, // dist-tag
        expect.objectContaining({ registry })
      );
    });

    it("overwrites yarn registry proxy with https://registry.npmjs.org/", async () => {
      const testDir = await initFixture("normal");
      const registry = "https://registry.yarnpkg.com";

      await lernaPublish(testDir)("--registry", registry);

      expect(npmPublish).toHaveBeenCalledWith(
        expect.objectContaining({ name: "package-1" }),
        undefined, // dist-tag
        expect.objectContaining({ registry: "https://registry.npmjs.org/" })
      );

      const logMessages = loggingOutput("warn");
      expect(logMessages).toContain("Yarn's registry proxy is broken, replacing with public npm registry");
      expect(logMessages).toContain("If you don't have an npm token, you should exit and run `npm login`");
    });
  });

  describe("--no-verify-access", () => {
    it("skips package access verification", async () => {
      const cwd = await initFixture("normal");

      await lernaPublish(cwd)("--no-verify-access");

      expect(verifyNpmPackageAccess).not.toBeCalled();
    });

    it("is implied when npm username is undefined", async () => {
      getNpmUsername.mockImplementationOnce(() => Promise.resolve());

      const cwd = await initFixture("normal");

      await lernaPublish(cwd)("--registry", "https://my-private-registry");

      expect(verifyNpmPackageAccess).not.toBeCalled();
    });
  });

  describe("in a cyclical repo", () => {
    it("should throw an error with --reject-cycles", async () => {
      expect.assertions(1);

      try {
        const testDir = await initFixture("toposort");

        await lernaPublish(testDir)("--reject-cycles");
      } catch (err) {
        expect(err.message).toMatch("Dependency cycles detected, you should fix these!");
      }
    });
  });
});
<commit_msg>chore(lint): fix warning<commit_after>"use strict";

// local modules _must_ be explicitly mocked
jest.mock("../lib/get-packages-without-license");
jest.mock("../lib/verify-npm-package-access");
jest.mock("../lib/get-npm-username");
jest.mock("../lib/get-unpublished-packages");
// FIXME: better mock for version command
jest.mock("../../version/lib/git-push");
jest.mock("../../version/lib/is-anything-committed");
jest.mock("../../version/lib/is-behind-upstream");
jest.mock("../../version/lib/remote-branch-exists");

// mocked or stubbed modules
const npmDistTag = require("@lerna/npm-dist-tag");
const npmPublish = require("@lerna/npm-publish");
const PromptUtilities = require("@lerna/prompt");
const collectUpdates = require("@lerna/collect-updates");
const output = require("@lerna/output");
const checkWorkingTree = require("@lerna/check-working-tree");
const getNpmUsername = require("../lib/get-npm-username");
const verifyNpmPackageAccess = require("../lib/verify-npm-package-access");
const getUnpublishedPackages = require("../lib/get-unpublished-packages");
const Project = require("@lerna/project");

// helpers
const loggingOutput = require("@lerna-test/logging-output");
const gitTag = require("@lerna-test/git-tag");
const initFixture = require("@lerna-test/init-fixture")(__dirname);

// file under test
const lernaPublish = require("@lerna-test/command-runner")(require("../command"));

describe("PublishCommand", () => {
  describe("cli validation", () => {
    let cwd;

    beforeAll(async () => {
      cwd = await initFixture("normal");
    });

    it("exits early when no changes found", async () => {
      collectUpdates.setUpdated(cwd);

      await lernaPublish(cwd)();

      const logMessages = loggingOutput("success");
      expect(logMessages).toContain("No changed packages to publish");
      expect(verifyNpmPackageAccess).not.toBeCalled();
    });

    ["from-git", "from-package"].forEach(fromArg => {
      it(`exits early when no changes found ${fromArg}`, async () => {
        collectUpdates.setUpdated(cwd);

        await lernaPublish(cwd)(fromArg);

        const logMessages = loggingOutput("success");
        expect(logMessages).toContain("No changed packages to publish");
        expect(verifyNpmPackageAccess).not.toBeCalled();
      });
    });

    it("exits non-zero with --scope", async () => {
      try {
        await lernaPublish(cwd)("--scope", "package-1");
      } catch (err) {
        expect(err.exitCode).toBe(1);
        expect(err.message).toBe("Unknown argument: scope");
      }

      expect.assertions(2);
    });

    it("exits non-zero with --since", async () => {
      try {
        await lernaPublish(cwd)("--since", "master");
      } catch (err) {
        expect(err.exitCode).toBe(1);
        expect(err.message).toBe("Unknown argument: since");
      }

      expect.assertions(2);
    });
  });

  describe("with implied versioning", () => {
    it("publishes changed packages", async () => {
      const testDir = await initFixture("normal");

      await lernaPublish(testDir)();

      expect(PromptUtilities.confirm).toHaveBeenLastCalledWith(
        "Are you sure you want to publish these packages?"
      );
      expect(npmPublish.packed).toMatchInlineSnapshot(`
Set {
  "package-1",
  "package-3",
  "package-4",
  "package-2",
}
`);
      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
      expect(npmDistTag.check).not.toBeCalled();
      expect(npmDistTag.remove).not.toBeCalled();
      expect(npmDistTag.add).not.toBeCalled();

      expect(getNpmUsername).toHaveBeenCalled();
      expect(getNpmUsername.registry.get(testDir).get("registry")).toBe("https://registry.npmjs.org/");

      expect(verifyNpmPackageAccess).toHaveBeenCalled();
      expect(verifyNpmPackageAccess.registry.get(testDir)).toMatchInlineSnapshot(`
Set {
  "package-1",
  "package-2",
  "package-3",
  "package-4",
  "username: lerna-test",
}
`);
    });

    it("publishes changed independent packages", async () => {
      const testDir = await initFixture("independent");

      await lernaPublish(testDir)();

      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
    });

    it("--skip-npm yields immediately to VersionCommand with warning", async () => {
      const cwd = await initFixture("normal");

      await lernaPublish(cwd)("--skip-npm");

      expect(npmPublish.order()).toHaveLength(0);

      const logMessages = loggingOutput("warn");
      expect(logMessages).toContain("Instead of --skip-npm, call `lerna version` directly");
    });

    it("throws an error in fixed mode when --independent is passed", async () => {
      const testDir = await initFixture("normal");

      try {
        await lernaPublish(testDir)("--independent");
      } catch (err) {
        expect(err.message).toMatch("independent");
      }

      expect.assertions(1);
    });
  });

  describe("from-git", () => {
    it("publishes tagged packages", async () => {
      const testDir = await initFixture("normal");

      await gitTag(testDir, "v1.0.0");
      await lernaPublish(testDir)("from-git");

      // called from chained describeRef()
      expect(checkWorkingTree.throwIfUncommitted).toHaveBeenCalled();

      expect(PromptUtilities.confirm).toHaveBeenLastCalledWith(
        "Are you sure you want to publish these packages?"
      );
      expect(output.logged()).toMatch("Found 4 packages to publish:");
      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
    });

    it("publishes tagged independent packages", async () => {
      const testDir = await initFixture("independent");

      await Promise.all([
        gitTag(testDir, "package-1@1.0.0"),
        gitTag(testDir, "package-2@2.0.0"),
        gitTag(testDir, "package-3@3.0.0"),
        gitTag(testDir, "package-4@4.0.0"),
        gitTag(testDir, "package-5@5.0.0"),
      ]);
      await lernaPublish(testDir)("from-git");

      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
    });

    it("only publishes independent packages with matching tags", async () => {
      const testDir = await initFixture("independent");

      await gitTag(testDir, "package-3@3.0.0");
      await lernaPublish(testDir)("from-git");

      expect(output.logged()).toMatch("Found 1 package to publish:");
      expect(npmPublish.order()).toEqual(["package-3"]);
    });

    it("exits early when the current commit is not tagged", async () => {
      const testDir = await initFixture("normal");

      await lernaPublish(testDir)("from-git");

      expect(npmPublish).not.toBeCalled();

      const logMessages = loggingOutput("info");
      expect(logMessages).toContain("No tagged release found");
    });

    it("throws an error when uncommitted changes are present", async () => {
      checkWorkingTree.throwIfUncommitted.mockImplementationOnce(() => {
        throw new Error("uncommitted");
      });

      const testDir = await initFixture("normal");

      try {
        await lernaPublish(testDir)("from-git");
      } catch (err) {
        expect(err.message).toBe("uncommitted");
        // notably different than the actual message, but good enough here
      }

      expect.assertions(1);
    });
  });

  describe("from-package", () => {
    it("publishes unpublished packages", async () => {
      const testDir = await initFixture("normal");
      const project = new Project(testDir);

      getUnpublishedPackages.mockImplementationOnce(async () => {
        const pkgs = await project.getPackages();
        return pkgs.slice(1, 3);
      });

      await lernaPublish(testDir)("from-package");

      expect(PromptUtilities.confirm).toHaveBeenLastCalledWith(
        "Are you sure you want to publish these packages?"
      );
      expect(output.logged()).toMatch("Found 2 packages to publish:");
      expect(npmPublish.order()).toEqual(["package-2", "package-3"]);
    });

    it("publishes unpublished independent packages", async () => {
      const testDir = await initFixture("independent");
      const project = new Project(testDir);

      getUnpublishedPackages.mockImplementationOnce(() => project.getPackages());

      await lernaPublish(testDir)("from-package");

      expect(npmPublish.order()).toEqual([
        "package-1",
        "package-3",
        "package-4",
        "package-2",
        // package-5 is private
      ]);
    });

    it("exits early when all packages are published", async () => {
      const testDir = await initFixture("normal");

      await lernaPublish(testDir)("from-package");

      expect(npmPublish).not.toBeCalled();

      const logMessages = loggingOutput("info");
      expect(logMessages).toContain("No unpublished release found");
    });

    it("throws an error when uncommitted changes are present", async () => {
      checkWorkingTree.throwIfUncommitted.mockImplementationOnce(() => {
        throw new Error("uncommitted");
      });

      const testDir = await initFixture("normal");

      try {
        await lernaPublish(testDir)("from-package");
      } catch (err) {
        expect(err.message).toBe("uncommitted");
        // notably different than the actual message, but good enough here
      }

      expect.assertions(1);
    });
  });

  describe("--registry", () => {
    it("passes registry to npm commands", async () => {
      const testDir = await initFixture("normal");
      const registry = "https://my-private-registry";

      await lernaPublish(testDir)("--registry", registry);

      expect(npmPublish).toHaveBeenCalledWith(
        expect.objectContaining({ name: "package-1" }),
        undefined, // dist-tag
        expect.objectContaining({ registry })
      );
    });

    it("overwrites yarn registry proxy with https://registry.npmjs.org/", async () => {
      const testDir = await initFixture("normal");
      const registry = "https://registry.yarnpkg.com";

      await lernaPublish(testDir)("--registry", registry);

      expect(npmPublish).toHaveBeenCalledWith(
        expect.objectContaining({ name: "package-1" }),
        undefined, // dist-tag
        expect.objectContaining({ registry: "https://registry.npmjs.org/" })
      );

      const logMessages = loggingOutput("warn");
      expect(logMessages).toContain("Yarn's registry proxy is broken, replacing with public npm registry");
      expect(logMessages).toContain("If you don't have an npm token, you should exit and run `npm login`");
    });
  });

  describe("--no-verify-access", () => {
    it("skips package access verification", async () => {
      const cwd = await initFixture("normal");

      await lernaPublish(cwd)("--no-verify-access");

      expect(verifyNpmPackageAccess).not.toBeCalled();
    });

    it("is implied when npm username is undefined", async () => {
      getNpmUsername.mockImplementationOnce(() => Promise.resolve());

      const cwd = await initFixture("normal");

      await lernaPublish(cwd)("--registry", "https://my-private-registry");

      expect(verifyNpmPackageAccess).not.toBeCalled();
    });
  });

  describe("in a cyclical repo", () => {
    it("should throw an error with --reject-cycles", async () => {
      expect.assertions(1);

      try {
        const testDir = await initFixture("toposort");

        await lernaPublish(testDir)("--reject-cycles");
      } catch (err) {
        expect(err.message).toMatch("Dependency cycles detected, you should fix these!");
      }
    });
  });
});
<|endoftext|>