<commit_before>var ChartConfig = require("../ChartConfig");

/**
 * ### Configuration of a Chart grid
 * @name chart_grid_config
 */

/**
* display
* @static
* @memberof chart_grid_config
* @property {Nem|number} afterTitle - Distance btwn top of title and top of legend or chart
* @property {Nem|number} afterLegend - Distance btwn top of legend and top of chart
* @property {Nem|number} blockerRectOffset - Distance btwn text of axis and its background blocker
* @property {Nem|number} paddingBerBar - Space btwn two bars in a bar grid
* @property {Nem|number} barHeight - Height of an individual bar in a bar grid
* @property {Nem|number} afterXYBottom - Vert distance btwn two chart grids that are stacked
* @property {Nem|number} afterXYRight - Horiz distance btwn two chart grids that are next to each other
* @property {Nem|number} columnExtraPadding - Extra padding given if a chart grid XY has columns
* @property {Nem|number} bottomPaddingWithoutFooter - Bottom padding if footer is not drawn
* @property {Nem|number} bottomPaddingWithoutFooter - Bottom padding if footer is not drawn
* @property {object} xy - Copy of `xy_config.display`, used in XY chart grids
* @property {object} margin - Distances btwn outer chart elements and container
* @property {object} padding - Distances btwn inner chart elements and container
*/
var display = {
	afterTitle: "1.6em", // distance between top of title and top of legend or chart
	afterLegend: "0.8em", // distance between top of legend and top of chart
	blockerRectOffset: "0.25em", // distance between text and background blocker rect
	paddingPerBar: "0.7em", // extra space around bars
	barHeight: "1.9em", // height of each bars
	afterXYBottom: "2em",
	afterXYRight: "0.8em",
	columnExtraPadding: "0.5em",
	barInnerPadding: 0.4, // % of col group width to pad btwn each
	barOuterPadding: 0.1, // % of col group width to pad btwn each
	bottomPaddingWithoutFooter: "0.5em",
	gridPadding: {
		xInnerPadding: 0.05,
		xOuterPadding: 0,
		yInnerPadding: 0.05,
		yOuterPadding: 0
	},
	xy: require("../cb-xy/xy-config").display,
	margin: {
		top: "0.8em",
		right: "0.25em",
		bottom: "0.15em",
		left: "0.25em"
	},
	padding: {
		top: "0.4em",
		right: 0,
		bottom: "1em",
		left: 0
	}
};
/**
* @name chart_grid_defaultProps
* @static
* @memberof chart_grid_config
*/
var defaultProps = {
	/**
	 * @name chartProps
	 * @property {object} scale - Default settings for date and primary scales
	 * @property {object} input
	 * @property {array} chartSettings - Default settings for a given series (column) of data
	 * @property {object} extraPadding - Additional padding. This is a dynamic
	 * value and is mostly changed within the component itself
	 * @property {object} _grid - Grid settings
	 * @property {number} _grid.rows - Number of rows in the grid
	 * @property {number} _grid.cols - Number of columns in the grid
	 * @property {string} _grid.type - Grid type `(bars|lines|dots|columns)`
	 * @property {object} mobile - Mobile-specific override settings
	 * @static
	 * @memberof chart_grid_defaultProps
	 */
	chartProps: {
		input: {},
		extraPadding: {
			top: 0,
			right: 0,
			bottom: 0,
			left: 0
		},
		scale: {
			primaryScale: {
				ticks: 5,
				precision: 0,
				prefix: "",
				suffix: ""
			},
			dateSettings: {
				dateFrequency: "auto",
				dateFormat: "auto",
				inputTZ: null,
				displayTZ: "as-entered"
			},
			numericSettings: {
				ticks: 5,
				precision: 0,
				prefix: "",
				suffix: ""
			}
		},
		chartSettings: [
			{
				colorIndex: 0,
				barHeight: "0.85em"
			}
		],
		_grid: {
			rows: 1,
			type: null
		},
		mobile: {}
	},
	/**
	 * @name metadata
	 * @property {string} chartType
	 * @property {string} size
	 * @static
	 * @memberof chart_grid_defaultProps
	 */
	metadata: {
		id: null,
		chartType: "chartgrid",
		title: "",
		source: "",
		credit: "Made with Chartbuilder",
		size: "auto"
	}
};

var chart_grid_config = new ChartConfig({
	displayName: "Chart grid",
	parser: require("./parse-chart-grid"),
	calculateDimensions: require("./chart-grid-dimensions"),
	display: display,
	defaultProps: defaultProps
});

module.exports = chart_grid_config;
<commit_msg>removed unused config settings<commit_after>var ChartConfig = require("../ChartConfig");

/**
 * ### Configuration of a Chart grid
 * @name chart_grid_config
 */

/**
* display
* @static
* @memberof chart_grid_config
* @property {Nem|number} afterTitle - Distance btwn top of title and top of legend or chart
* @property {Nem|number} afterLegend - Distance btwn top of legend and top of chart
* @property {Nem|number} blockerRectOffset - Distance btwn text of axis and its background blocker
* @property {Nem|number} paddingBerBar - Space btwn two bars in a bar grid
* @property {Nem|number} barHeight - Height of an individual bar in a bar grid
* @property {Nem|number} afterXYBottom - Vert distance btwn two chart grids that are stacked
* @property {Nem|number} afterXYRight - Horiz distance btwn two chart grids that are next to each other
* @property {Nem|number} columnExtraPadding - Extra padding given if a chart grid XY has columns
* @property {Nem|number} bottomPaddingWithoutFooter - Bottom padding if footer is not drawn
* @property {Nem|number} bottomPaddingWithoutFooter - Bottom padding if footer is not drawn
* @property {object} xy - Copy of `xy_config.display`, used in XY chart grids
* @property {object} margin - Distances btwn outer chart elements and container
* @property {object} padding - Distances btwn inner chart elements and container
*/
var display = {
	afterTitle: "1.6em", // distance between top of title and top of legend or chart
	afterLegend: "0.8em", // distance between top of legend and top of chart
	blockerRectOffset: "0.25em", // distance between text and background blocker rect
	barHeight: "1.9em", // height of each bars
	columnExtraPadding: "0.5em",
	barInnerPadding: 0.4, // % of col group width to pad btwn each
	barOuterPadding: 0.1, // % of col group width to pad btwn each
	bottomPaddingWithoutFooter: "0.5em",
	gridPadding: {
		xInnerPadding: 0.05,
		xOuterPadding: 0,
		yInnerPadding: 0.05,
		yOuterPadding: 0
	},
	xy: require("../cb-xy/xy-config").display,
	margin: {
		top: "0.8em",
		right: "0.25em",
		bottom: "0.15em",
		left: "0.25em"
	},
	padding: {
		top: "0.4em",
		right: 0,
		bottom: "1em",
		left: 0
	}
};
/**
* @name chart_grid_defaultProps
* @static
* @memberof chart_grid_config
*/
var defaultProps = {
	/**
	 * @name chartProps
	 * @property {object} scale - Default settings for date and primary scales
	 * @property {object} input
	 * @property {array} chartSettings - Default settings for a given series (column) of data
	 * @property {object} extraPadding - Additional padding. This is a dynamic
	 * value and is mostly changed within the component itself
	 * @property {object} _grid - Grid settings
	 * @property {number} _grid.rows - Number of rows in the grid
	 * @property {number} _grid.cols - Number of columns in the grid
	 * @property {string} _grid.type - Grid type `(bars|lines|dots|columns)`
	 * @property {object} mobile - Mobile-specific override settings
	 * @static
	 * @memberof chart_grid_defaultProps
	 */
	chartProps: {
		input: {},
		extraPadding: {
			top: 0,
			right: 0,
			bottom: 0,
			left: 0
		},
		scale: {
			primaryScale: {
				ticks: 5,
				precision: 0,
				prefix: "",
				suffix: ""
			},
			dateSettings: {
				dateFrequency: "auto",
				dateFormat: "auto",
				inputTZ: null,
				displayTZ: "as-entered"
			},
			numericSettings: {
				ticks: 5,
				precision: 0,
				prefix: "",
				suffix: ""
			}
		},
		chartSettings: [
			{
				colorIndex: 0,
				barHeight: "0.85em"
			}
		],
		_grid: {
			rows: 1,
			type: null
		},
		mobile: {}
	},
	/**
	 * @name metadata
	 * @property {string} chartType
	 * @property {string} size
	 * @static
	 * @memberof chart_grid_defaultProps
	 */
	metadata: {
		id: null,
		chartType: "chartgrid",
		title: "",
		source: "",
		credit: "Made with Chartbuilder",
		size: "auto"
	}
};

var chart_grid_config = new ChartConfig({
	displayName: "Chart grid",
	parser: require("./parse-chart-grid"),
	calculateDimensions: require("./chart-grid-dimensions"),
	display: display,
	defaultProps: defaultProps
});

module.exports = chart_grid_config;
<|endoftext|>


<commit_before>"use strict";

var gruntUtils = require('../../../lib/grunt/utils');
var versionInfo = require('../../../lib/versions/version-info');

/**
 * @dgService gitData
 * @description
 * Information from the local git repository
 */
module.exports = function gitData() {
  return {
    version: versionInfo.currentVersion,
    versions: versionInfo.previousVersions,
    info: versionInfo.gitRepoInfo
  };
};
<commit_msg>chore(docs): remove unused gruntUtils import from docs config<commit_after>"use strict";

var versionInfo = require('../../../lib/versions/version-info');

/**
 * @dgService gitData
 * @description
 * Information from the local git repository
 */
module.exports = function gitData() {
  return {
    version: versionInfo.currentVersion,
    versions: versionInfo.previousVersions,
    info: versionInfo.gitRepoInfo
  };
};
<|endoftext|>


<commit_before>var cdb = require('cartodb.js');
var Utils = require('cdb.Utils');
var BaseDialog = require('../../views/base_dialog/view');
var ViewFactory = require('../../view_factory');
var randomQuote = require('../../view_helpers/random_quote');

module.exports = cdb.core.View.extend({

  _MAX_ROWS: 100000,
  _MAX_COLS: 60,
  _EXCLUDED_COLUMNS: [
    'cartodb_id', 'lat', 'lon', 'lng', 'long', 'latitude', 'longitude', 'longitudenumber','latitudenumber',
    'minlat', 'maxlat', 'minlon', 'maxlon', 'minlng', 'maxlng', 'center_lat', 'centerlat', 'center_lon', 'centerlon',
    'latdd', 'longdd', 'shape_length', 'shape_area', 'objectid', 'id', 'created_at', 'updated_at',
    'iso2', 'iso3', 'x', 'y', 'x_coord', 'y_coord', 'xcoord', 'ycoord', 'coord_x', 'coord_y', 'coordx', 'coordy',
    'cartodb_georef_status','scalerank', 'strokweig', 'country', 'state', 'area_sqkm', 'region', 'subregion', 'funcstat',
    'classfp', 'county_fip', 'county', 'aland10'
  ],

  initialize: function() {
    this.elder('initialize');

    if (!this.options.table) {
      throw new Error('table is required');
    }

    this._initModels();
    this._initViews();
  },

  _check: function() {

    var tableData     = this.options.table.data();
    var geometryTypes = tableData.table && tableData.table.get("stats_geometry_types");
    var hasGeometries = geometryTypes && geometryTypes.length > 0 ? true : false;

    var row_count     = tableData.table.get("rows_counted");
    var hasRows       = row_count > 0 && row_count < this._MAX_ROWS;

    var col_count = _(this.query_schema).size();
    var hasColumns = col_count > 0 && col_count < this._MAX_COLS;

    if (hasGeometries && hasRows && hasColumns) {
      return true;
    } else {
      return false;
    }
  },

  _initModels: function() {
    this.columns = new Backbone.Collection();
    this.model = new cdb.core.Model({ page: 1, maxPages: 0 });
  },

  _initViews: function() {

    this.table = this.options.table;
    this.query_schema = this.table.data().query_schema;
    this.backgroundPollingModel = this.options.backgroundPollingModel;

    if (this._check() && this.backgroundPollingModel.canAddAnalysis()) {
      this._setupColumns();
      this._start();
    }
  },

  _getSimplifiedGeometryType: function(g) {
    return {
      st_multipolygon: 'polygon',
      st_polygon: 'polygon',
      st_multilinestring: 'line',
      st_linestring: 'line',
      st_multipoint: 'point',
      st_point: 'point'
    }[g.toLowerCase()];
  },

  _getGeometryType: function() {
    var geometry_types = this.table.data().table.get("stats_geometry_types");
    return this._getSimplifiedGeometryType(geometry_types[0]);
  },

  _start: function() {
    var columns = this.columns.map(function(column) {
      return { table_id: this.table.id, column: column.get("name"), geometry_type: column.get("geometry_type") };
    }, this);

    this.backgroundPollingModel.addAnalysis(columns);
  },

  _setupColumns: function() {
    _(this.query_schema).each(function(type, name) {
      if (!_.include(this._EXCLUDED_COLUMNS, name)) {
        this.columns.add({ name: name.concat(""), geometry_type: this._getGeometryType() });
      }
    }, this);
  }

});
<commit_msg>Retrieves geometries from the right place<commit_after>var cdb = require('cartodb.js');
var Utils = require('cdb.Utils');
var BaseDialog = require('../../views/base_dialog/view');
var ViewFactory = require('../../view_factory');
var randomQuote = require('../../view_helpers/random_quote');

module.exports = cdb.core.View.extend({

  _MAX_ROWS: 100000,
  _MAX_COLS: 60,
  _EXCLUDED_COLUMNS: [
    'cartodb_id', 'lat', 'lon', 'lng', 'long', 'latitude', 'longitude', 'longitudenumber','latitudenumber',
    'minlat', 'maxlat', 'minlon', 'maxlon', 'minlng', 'maxlng', 'center_lat', 'centerlat', 'center_lon', 'centerlon',
    'latdd', 'longdd', 'shape_length', 'shape_area', 'objectid', 'id', 'created_at', 'updated_at',
    'iso2', 'iso3', 'x', 'y', 'x_coord', 'y_coord', 'xcoord', 'ycoord', 'coord_x', 'coord_y', 'coordx', 'coordy',
    'cartodb_georef_status','scalerank', 'strokweig', 'country', 'state', 'area_sqkm', 'region', 'subregion', 'funcstat',
    'classfp', 'county_fip', 'county', 'aland10'
  ],

  initialize: function() {
    this.elder('initialize');

    if (!this.options.table) {
      throw new Error('table is required');
    }

    this._initModels();
    this._initViews();
  },

  _check: function() {

    var tableData     = this.options.table.data();
    var geometryTypes = tableData.table && tableData.table.get("geometry_types");
    var hasGeometries = geometryTypes && geometryTypes.length > 0 ? true : false;

    var row_count     = tableData.table.get("rows_counted");
    var hasRows       = row_count > 0 && row_count < this._MAX_ROWS;

    var col_count = _(this.query_schema).size();
    var hasColumns = col_count > 0 && col_count < this._MAX_COLS;

    if (hasGeometries && hasRows && hasColumns) {
      return true;
    } else {
      return false;
    }
  },

  _initModels: function() {
    this.columns = new Backbone.Collection();
    this.model = new cdb.core.Model({ page: 1, maxPages: 0 });
  },

  _initViews: function() {

    this.table = this.options.table;
    this.query_schema = this.table.data().query_schema;
    this.backgroundPollingModel = this.options.backgroundPollingModel;

    if (this._check() && this.backgroundPollingModel.canAddAnalysis()) {
      this._setupColumns();
      this._start();
    }
  },

  _getSimplifiedGeometryType: function(g) {
    return {
      st_multipolygon: 'polygon',
      st_polygon: 'polygon',
      st_multilinestring: 'line',
      st_linestring: 'line',
      st_multipoint: 'point',
      st_point: 'point'
    }[g.toLowerCase()];
  },

  _getGeometryType: function() {
    var geometry_types = this.table.data().table.get("geometry_types");
    return this._getSimplifiedGeometryType(geometry_types[0]);
  },

  _start: function() {
    var columns = this.columns.map(function(column) {
      return { table_id: this.table.id, column: column.get("name"), geometry_type: column.get("geometry_type") };
    }, this);

    this.backgroundPollingModel.addAnalysis(columns);
  },

  _setupColumns: function() {
    _(this.query_schema).each(function(type, name) {
      if (!_.include(this._EXCLUDED_COLUMNS, name)) {
        this.columns.add({ name: name.concat(""), geometry_type: this._getGeometryType() });
      }
    }, this);
  }

});
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var _ = require('lodash');
var Err = require('../../../../errors');

module.exports = function (sails) {
  return function (modelDef) {

    // Backwards compatibilty for `Model.adapter`
    if (modelDef.adapter) {
      sails.log.verbose(
        'Deprecation warning :: ' +
        'Replacing `' + modelDef.globalId + '.adapter` ' +
        'with `' + modelDef.globalId + '.connection`....');
      modelDef.connection = modelDef.adapter;
      delete modelDef.adapter;
    }

    // Backwards compatiblity for lifecycle callbacks
    if (modelDef.beforeValidation) {
      sails.log.verbose(
        'Deprecation warning :: the `beforeValidation()` model lifecycle callback is now `beforeValidate()`.\n' +
        'For now, I\'m replacing it for you (in `' + modelDef.globalId + '`)...');
      modelDef.beforeValidate = modelDef.beforeValidation;
    }
    if (modelDef.afterValidation) {
      sails.log.verbose(
        'Deprecation warning :: the `afterValidation()` model lifecycle callback is now `afterValidate()`.\n' +
        'For now, I\'m replacing it for you (in `' + modelDef.globalId + '`)...');
      modelDef.afterValidate = modelDef.afterValidation;
    }

    // If no connection can be determined (even by using app-level defaults [config.models])
    // throw a fatal error.
    if (!modelDef.connection) {
      return Err.fatal.__ModelIsMissingConnection__(modelDef.globalId);
    }

    // Coerce `Model.connection` to an array
    if (!_.isArray(modelDef.connection)) {
      modelDef.connection = [modelDef.connection];
    }

    return modelDef;
  };
};
<commit_msg>Update upgrade-model-definition.js<commit_after>/**
 * Module dependencies
 */

var _ = require('lodash');
var Err = require('../../../../errors');

module.exports = function (sails) {
  return function (modelDef) {

    // Backwards compatibilty for `Model.adapter`
    if (modelDef.adapter && typeof modelDef.connection === 'undefined') {
      sails.log.verbose(
        'Deprecation warning :: ' +
        'Replacing `' + modelDef.globalId + '.adapter` ' +
        'with `' + modelDef.globalId + '.connection`....');
      modelDef.connection = modelDef.adapter;
      delete modelDef.adapter;
    }

    // Backwards compatiblity for lifecycle callbacks
    if (modelDef.beforeValidation) {
      sails.log.verbose(
        'Deprecation warning :: the `beforeValidation()` model lifecycle callback is now `beforeValidate()`.\n' +
        'For now, I\'m replacing it for you (in `' + modelDef.globalId + '`)...');
      modelDef.beforeValidate = modelDef.beforeValidation;
    }
    if (modelDef.afterValidation) {
      sails.log.verbose(
        'Deprecation warning :: the `afterValidation()` model lifecycle callback is now `afterValidate()`.\n' +
        'For now, I\'m replacing it for you (in `' + modelDef.globalId + '`)...');
      modelDef.afterValidate = modelDef.afterValidation;
    }

    // If no connection can be determined (even by using app-level defaults [config.models])
    // throw a fatal error.
    if (!modelDef.connection) {
      return Err.fatal.__ModelIsMissingConnection__(modelDef.globalId);
    }

    // Coerce `Model.connection` to an array
    if (!_.isArray(modelDef.connection)) {
      modelDef.connection = [modelDef.connection];
    }

    return modelDef;
  };
};
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var validators = require('utils/validator');
var stringUtils = require('utils/string_utils');
/**
 * Helper methods to process database values and properties
 * @module utils/configs/database
 */
module.exports = {
  /**
   * Database type properties with options attribute usually displayed as radio-button.
   * options attribute contains mapping of database type to special properties name such as
   * database host and database name.
   * @type {object}
   */
  dbServicePropertyMap: {
    HIVE: {
      dbType: 'hive_database',
      databaseName: 'ambari.hive.db.schema.name',
      connectionUrl: 'javax.jdo.option.ConnectionURL',
      fallbackHostName: 'hive_ambari_host'
    },
    OOZIE: {
      dbType: 'oozie_database',
      connectionUrl: 'oozie.service.JPAService.jdbc.url',
      databaseName: 'oozie.db.schema.name',
      fallbackHostName: 'oozieserver_host'
    }
  },

  /**
   * Map of jdbc url patterns related to supported database types.
   *
   * @type {object}
   */
  DB_JDBC_PATTERNS: {
    mysql: 'jdbc:mysql://{0}/{1}',
    mssql: 'jdbc:sqlserver://{0};databaseName={1}',
    postgres: 'jdbc:postgresql://{0}:5432/{1}',
    derby: 'jdbc:derby:{0}/{1}',
    oracle: 'jdbc:oracle:thin:@(?:\/?\/?){0}:1521(\:|\/){1}'
  },

  /**
   * Setup database related properties.
   *
   * @method bootstrapDatabaseProperties
   * @param {App.ServiceConfigProperty[]} serviceConfigs
   * @param {string} [serviceName=false]
   */
  bootstrapDatabaseProperties: function(serviceConfigs, serviceName) {
    var self = this;
    var supportedServices = Em.keys(this.dbServicePropertyMap);
    if (serviceName && !supportedServices.contains(serviceName)) return;
    var serviceNames = serviceName ? [serviceName] : serviceConfigs.mapProperty('serviceName').uniq();
    serviceNames.forEach(function(serviceName) {
      if (!supportedServices.contains(serviceName)) return;
      var configs = serviceConfigs.filterProperty('serviceName', serviceName) || [];
      var connectionConfigs = self.dbServicePropertyMap[serviceName];
      var databaseTypeProperty = configs.findProperty('name', connectionConfigs.dbType);
      if (!databaseTypeProperty) return;
      var databaseTypePropertyIndex = configs.indexOf(databaseTypeProperty);
      var generatedProperties = self.getPropsByOptions(databaseTypeProperty, configs);
      var jdbcObject = self.parseJdbcUrl(Em.get(configs.findProperty('name', connectionConfigs.connectionUrl), 'value'));
      generatedProperties.forEach(function(property) {
        if (Em.get(property, 'name').endsWith('_host')) {
          // set UI host names for each database type with value parsed from jdbc connection url
          // if value is not ip or hostname (in case of New Derby Database) for Oozie set fallbackUrl
          // from dbServicePropertyMap
          var dbHostName;
          if (self.isValidHostname(jdbcObject.location)) {
            dbHostName = jdbcObject.location;
          } else {
            dbHostName = Em.get(configs.findProperty('name', self.dbServicePropertyMap[serviceName].fallbackHostName), 'recommendedValue');
            dbHostName = Em.isArray(dbHostName) ? dbHostName[0] : dbHostName;
          }
          Em.setProperties(property, {
            value: dbHostName
          });
          self.addPropertyToServiceConfigs(property, serviceConfigs, databaseTypePropertyIndex);
        }
      });
    });
  },

  isValidHostname: function(value) {
    return validators.isHostname(value) || validators.isIpAddress(value);
  },

  /**
   * Add UI specific property to serviceConfigObject if it does not exist, and update value for existed property.
   * This code affects properties related to `_host` and `_database` which are hardcoded on UI.
   *
   * @param {object} property - property to append/update
   * @param {App.ServiceConfigProperty[]} configs - loaded and processed service configs
   * @param {integer} index of first occurrence of database type in config
   */
  addPropertyToServiceConfigs: function(property, configs, index) {
    var configProperty = configs.findProperty('name', Em.get(property, 'name'));
    if (configProperty) {
      Em.set(configProperty, 'value', Em.get(property, 'value'));
    } else {
      if (index) {
        configs.insertAt(index, App.ServiceConfigProperty.create(property));
      } else {
        configs.pushObject(App.ServiceConfigProperty.create(property));
      }
    }
  },

  /**
   * Get hardcoded properties from site_properties.js which UI use to display host name and database name.
   *
   * @method getPropsByOptions
   * @param {object} databaseTypeProperty - hardcoded property from site_properties.js usualy used as radiobutton
   * @param {App.ServiceConfigProperty[]} configs - loaded and processed configs
   * @returns {object[]} - hardcoded properties from site_properties.js related to database name and location
   */
  getPropsByOptions: function(databaseTypeProperty) {
    Em.assert('Property related to database type should contains `options` attribute', databaseTypeProperty.get('options'));
    return databaseTypeProperty.options.mapProperty('foreignKeys').reduce(function(p,c) {
      return p.concat(c);
    }).uniq().map(function(name) {
      return App.config.get('preDefinedSiteProperties').findProperty('name', name) || null;
    }).compact();
  },

  /**
   * Get database location from jdbc url value.
   *
   * @method getDBLocationFromJDBC
   * @param {string} jdbcUrl - url to parse
   * @returns {string|null}
   */
  getDBLocationFromJDBC: function(jdbcUrl) {
    var self = this;
    var matches = Em.keys(this.DB_JDBC_PATTERNS).map(function(key) {
      var reg = new RegExp(self.DB_JDBC_PATTERNS[key].format('(.*)', '(.*)'));
      return jdbcUrl.match(reg);
    }).compact();
    if (matches.length) {
      var dbLocation = Em.get(matches, '0.1');
      if (dbLocation.startsWith('${')) {
        return Em.getWithDefault(matches, '0.0', '').match(/\${[^}]+}/)[0];
      }
      return dbLocation != '{0}' ? dbLocation : null;
    } else {
      return null;
    }
  },

  parseJdbcUrl: function(jdbcUrl) {
    var self = this;
    var result = {
      dbType: null,
      location: null,
      databaseName: null
    };
    var dbName;

    result.dbType = Em.keys(this.DB_JDBC_PATTERNS).filter(function(key) {
      var scheme = self.DB_JDBC_PATTERNS[key].match(/^jdbc:(\w+):/)[1];
      return new RegExp('jdbc:' + scheme).test(jdbcUrl);
    })[0];

    result.location = this.getDBLocationFromJDBC(jdbcUrl);
    if (!jdbcUrl.endsWith('{1}')) {
      dbName = jdbcUrl.replace(new RegExp(this.DB_JDBC_PATTERNS[result.dbType].format(stringUtils.escapeRegExp(result.location),'')), '');
      if (dbName) {
        result.databaseName = dbName.split(/[;|?]/)[0];
      }
    }
    return result;
  }
};
<commit_msg>AMBARI-12133 Ambari: It could not load the YARN configs page. (ababiichuk)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var validators = require('utils/validator');
var stringUtils = require('utils/string_utils');
/**
 * Helper methods to process database values and properties
 * @module utils/configs/database
 */
module.exports = {
  /**
   * Database type properties with options attribute usually displayed as radio-button.
   * options attribute contains mapping of database type to special properties name such as
   * database host and database name.
   * @type {object}
   */
  dbServicePropertyMap: {
    HIVE: {
      dbType: 'hive_database',
      databaseName: 'ambari.hive.db.schema.name',
      connectionUrl: 'javax.jdo.option.ConnectionURL',
      fallbackHostName: 'hive_ambari_host'
    },
    OOZIE: {
      dbType: 'oozie_database',
      connectionUrl: 'oozie.service.JPAService.jdbc.url',
      databaseName: 'oozie.db.schema.name',
      fallbackHostName: 'oozieserver_host'
    }
  },

  /**
   * Map of jdbc url patterns related to supported database types.
   *
   * @type {object}
   */
  DB_JDBC_PATTERNS: {
    mysql: 'jdbc:mysql://{0}/{1}',
    mssql: 'jdbc:sqlserver://{0};databaseName={1}',
    postgres: 'jdbc:postgresql://{0}:5432/{1}',
    derby: 'jdbc:derby:{0}/{1}',
    oracle: 'jdbc:oracle:thin:@(?:\/?\/?){0}:1521(\:|\/){1}'
  },

  /**
   * Setup database related properties.
   *
   * @method bootstrapDatabaseProperties
   * @param {App.ServiceConfigProperty[]} serviceConfigs
   * @param {string} [serviceName=false]
   */
  bootstrapDatabaseProperties: function(serviceConfigs, serviceName) {
    var self = this;
    var supportedServices = Em.keys(this.dbServicePropertyMap);
    if (serviceName && !supportedServices.contains(serviceName)) return;
    var serviceNames = serviceName ? [serviceName] : serviceConfigs.mapProperty('serviceName').uniq();
    serviceNames.forEach(function(serviceName) {
      if (!supportedServices.contains(serviceName)) return;
      var configs = serviceConfigs.filterProperty('serviceName', serviceName) || [];
      var connectionConfigs = self.dbServicePropertyMap[serviceName];
      var databaseTypeProperty = configs.findProperty('name', connectionConfigs.dbType);
      if (!databaseTypeProperty) return;
      var databaseTypePropertyIndex = configs.indexOf(databaseTypeProperty);
      var generatedProperties = self.getPropsByOptions(databaseTypeProperty, configs);
      var jdbcObject = self.parseJdbcUrl(Em.get(configs.findProperty('name', connectionConfigs.connectionUrl), 'value'));
      generatedProperties.forEach(function(property) {
        if (Em.get(property, 'name').endsWith('_host')) {
          // set UI host names for each database type with value parsed from jdbc connection url
          // if value is not ip or hostname (in case of New Derby Database) for Oozie set fallbackUrl
          // from dbServicePropertyMap
          Em.setProperties(property, {
            value: jdbcObject.location || ''
          });
          self.addPropertyToServiceConfigs(property, serviceConfigs, databaseTypePropertyIndex);
        }
      });
    });
  },

  isValidHostname: function(value) {
    return validators.isHostname(value) || validators.isIpAddress(value);
  },

  /**
   * Add UI specific property to serviceConfigObject if it does not exist, and update value for existed property.
   * This code affects properties related to `_host` and `_database` which are hardcoded on UI.
   *
   * @param {object} property - property to append/update
   * @param {App.ServiceConfigProperty[]} configs - loaded and processed service configs
   * @param {integer} index of first occurrence of database type in config
   */
  addPropertyToServiceConfigs: function(property, configs, index) {
    var configProperty = configs.findProperty('name', Em.get(property, 'name'));
    if (configProperty) {
      Em.set(configProperty, 'value', Em.get(property, 'value'));
    } else {
      if (index) {
        configs.insertAt(index, App.ServiceConfigProperty.create(property));
      } else {
        configs.pushObject(App.ServiceConfigProperty.create(property));
      }
    }
  },

  /**
   * Get hardcoded properties from site_properties.js which UI use to display host name and database name.
   *
   * @method getPropsByOptions
   * @param {object} databaseTypeProperty - hardcoded property from site_properties.js usualy used as radiobutton
   * @param {App.ServiceConfigProperty[]} configs - loaded and processed configs
   * @returns {object[]} - hardcoded properties from site_properties.js related to database name and location
   */
  getPropsByOptions: function(databaseTypeProperty) {
    Em.assert('Property related to database type should contains `options` attribute', databaseTypeProperty.get('options'));
    return databaseTypeProperty.options.mapProperty('foreignKeys').reduce(function(p,c) {
      return p.concat(c);
    }).uniq().map(function(name) {
      return App.config.get('preDefinedSiteProperties').findProperty('name', name) || null;
    }).compact();
  },

  /**
   * Get database location from jdbc url value.
   *
   * @method getDBLocationFromJDBC
   * @param {string} jdbcUrl - url to parse
   * @returns {string|null}
   */
  getDBLocationFromJDBC: function(jdbcUrl) {
    var self = this;
    var matches = Em.keys(this.DB_JDBC_PATTERNS).map(function(key) {
      var reg = new RegExp(self.DB_JDBC_PATTERNS[key].format('(.*)', '(.*)'));
      return jdbcUrl.match(reg);
    }).compact();
    if (matches.length) {
      var dbLocation = Em.get(matches, '0.1');
      if (dbLocation.startsWith('${')) {
        return Em.getWithDefault(matches, '0.0', '').match(/\${[^}]+}/)[0];
      }
      return dbLocation != '{0}' ? dbLocation : null;
    } else {
      return null;
    }
  },

  parseJdbcUrl: function(jdbcUrl) {
    var self = this;
    var result = {
      dbType: null,
      location: null,
      databaseName: null
    };
    var dbName;

    result.dbType = Em.keys(this.DB_JDBC_PATTERNS).filter(function(key) {
      var scheme = self.DB_JDBC_PATTERNS[key].match(/^jdbc:(\w+):/)[1];
      return new RegExp('jdbc:' + scheme).test(jdbcUrl);
    })[0];

    result.location = this.getDBLocationFromJDBC(jdbcUrl);
    if (!jdbcUrl.endsWith('{1}')) {
      dbName = jdbcUrl.replace(new RegExp(this.DB_JDBC_PATTERNS[result.dbType].format(stringUtils.escapeRegExp(result.location),'')), '');
      if (dbName) {
        result.databaseName = dbName.split(/[;|?]/)[0];
      }
    }
    return result;
  }
};
<|endoftext|>


<commit_before>import React from 'react'

import SelectService from './selectservice'
import SelectCall from './selectcall'
import RichDescription from './richdescription'
import GenericButton from './genericbutton'
import TextArea from './textarea'
import i18n from 'app/utils/i18n'

function class_sbds_to_sui(klass){
  switch(klass){
    case "half column":
      return "half"
    default:
      return ""
  }
}

const GenericField=React.createClass({
  getInitialState(){
    return {
      items: [],
      show: this.check_if_show(this.props)
    }
  },
  handleChange: function(ev){
    this.props.setValue(this.props.name, ev.target.value)
  },
  handleChecked: function(ev){
    this.props.setValue(this.props.name, ev.target.checked)
  },
  componentDidMount(){
    // Some may need post initialization
    switch (this.props.type){
      case 'select':
        $(this.refs.select).dropdown()
        break;
      default:
        ;;
      break;
    }
  },
  componentWillReceiveProps(newprops){
    const should_show=this.check_if_show(newprops)
    if (this.state.show!=should_show)
      this.setState({show:should_show})
  },
  check_if_show(props){
    if (props.show_if){
      const value = props.form_data[props.show_if]
      if (value==undefined || value=="")
        return false
    }
    return true;
  },
  render(){
    if (!this.state.show)
      return null;
    let props=this.props
    switch (props.type){
      case undefined:
      case '':
      case 'text':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars}/>
            <input type="text"
              name={props.name}
              placeholder={i18n(props.placeholder || props.description)}
              defaultValue={props.value}
              onChange={this.handleChange}/>

        )
      case 'url':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars}/>
            <input type="url"
              name={props.name}
              placeholder={i18n(props.placeholder || props.description)}
              defaultValue={props.value}
              onChange={this.handleChange}/>

        )
      case 'textarea':
        return (
          <TextArea {...props} onChange={this.handleChange} className={class_sbds_to_sui(props["class"])}/>
        )
      case 'password':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars}/>
            <input type="password"
              name={props.name}
              placeholder={i18n(props.placeholder || props.description)}
              defaultValue={props.value}
              onChange={this.handleChange}/>

        )
      case "checkbox":
        return (

            <input type="checkbox" defaultChecked={props.value} id={props.name} onChange={this.handleChecked}/>
            {props.label}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars}/>

        )
      case 'description':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars} form_data={props.form_data}/>

        )
      case 'hidden':
        return (
          <input type="hidden" disabled={true} name={props.name} value={props.value}/>
        )
      case 'select':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars} form_data={props.form_data}/>
            <select ref="select"
                name={props.name}
                defaultValue={props.value}
                className={`ui fluid ${props.search ? "search" : ""} dropdown`}
                onChange={this.handleChange}
                dynamic={props.dynamic}
                form_data={props.form_data}
                >
              {props.options.map((o) => ( o.value ? (
                <option key={o.value} value={o.value}>{o.label || o.name}</option>
              ) : (
                <option key={o} value={o}>{o}</option>
              ) ) ) }
            </select>

        )
      case 'button':
        return (
          <GenericButton {...props} className={class_sbds_to_sui(props["class"])}/>
        )
      case 'select call':
        return (
          <SelectCall {...props} onChange={this.handleChange} className={class_sbds_to_sui(props["class"])}/>
        )
      case 'service':
        return (
          <SelectService {...props} onChange={this.handleChange} className={class_sbds_to_sui(props["class"])}/>
        )
      default:
        return (

Unknown field type "{props.type}"

        )
    }
  }
})

export default GenericField
<commit_msg>Show properly checkbox generic fields<commit_after>import React from 'react'

import SelectService from './selectservice'
import SelectCall from './selectcall'
import RichDescription from './richdescription'
import GenericButton from './genericbutton'
import TextArea from './textarea'
import i18n from 'app/utils/i18n'

function class_sbds_to_sui(klass){
  switch(klass){
    case "half column":
      return "half"
    default:
      return ""
  }
}

const GenericField=React.createClass({
  getInitialState(){
    return {
      items: [],
      show: this.check_if_show(this.props)
    }
  },
  handleChange: function(ev){
    this.props.setValue(this.props.name, ev.target.value)
  },
  handleChecked: function(ev){
    this.props.setValue(this.props.name, ev.target.checked)
  },
  componentDidMount(){
    // Some may need post initialization
    switch (this.props.type){
      case 'select':
        $(this.refs.select).dropdown()
        break;
      default:
        ;;
      break;
    }
  },
  componentWillReceiveProps(newprops){
    const should_show=this.check_if_show(newprops)
    if (this.state.show!=should_show)
      this.setState({show:should_show})
  },
  check_if_show(props){
    if (props.show_if){
      const value = props.form_data[props.show_if]
      if (value==undefined || value=="")
        return false
    }
    return true;
  },
  render(){
    if (!this.state.show)
      return null;
    let props=this.props
    switch (props.type){
      case undefined:
      case '':
      case 'text':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars}/>
            <input type="text"
              name={props.name}
              placeholder={i18n(props.placeholder || props.description)}
              defaultValue={props.value}
              onChange={this.handleChange}/>

        )
      case 'url':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars}/>
            <input type="url"
              name={props.name}
              placeholder={i18n(props.placeholder || props.description)}
              defaultValue={props.value}
              onChange={this.handleChange}/>

        )
      case 'textarea':
        return (
          <TextArea {...props} onChange={this.handleChange} className={class_sbds_to_sui(props["class"])}/>
        )
      case 'password':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars}/>
            <input type="password"
              name={props.name}
              placeholder={i18n(props.placeholder || props.description)}
              defaultValue={props.value}
              onChange={this.handleChange}/>

        )
      case "checkbox":
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>

              <input type="checkbox" defaultChecked={props.value} id={props.name} onChange={this.handleChecked}/>
              {props.label}
              <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars}/>

        )
      case 'description':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars} form_data={props.form_data}/>

        )
      case 'hidden':
        return (
          <input type="hidden" disabled={true} name={props.name} value={props.value}/>
        )
      case 'select':
        return (
          <div className={`field ${class_sbds_to_sui(props["class"])}`}>
            {i18n(props.label)}
            <RichDescription className="ui meta" value={i18n(props.description)} vars={props.vars} form_data={props.form_data}/>
            <select ref="select"
                name={props.name}
                defaultValue={props.value}
                className={`ui fluid ${props.search ? "search" : ""} dropdown`}
                onChange={this.handleChange}
                dynamic={props.dynamic}
                form_data={props.form_data}
                >
              {props.options.map((o) => ( o.value ? (
                <option key={o.value} value={o.value}>{o.label || o.name}</option>
              ) : (
                <option key={o} value={o}>{o}</option>
              ) ) ) }
            </select>

        )
      case 'button':
        return (
          <GenericButton {...props} className={class_sbds_to_sui(props["class"])}/>
        )
      case 'select call':
        return (
          <SelectCall {...props} onChange={this.handleChange} className={class_sbds_to_sui(props["class"])}/>
        )
      case 'service':
        return (
          <SelectService {...props} onChange={this.handleChange} className={class_sbds_to_sui(props["class"])}/>
        )
      default:
        return (

Unknown field type "{props.type}"

        )
    }
  }
})

export default GenericField
<|endoftext|>


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

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

/* eslint-disable node/no-sync, node/shebang, no-console */

'use strict';

// MAIN //

var path = require( 'path' );
var fs = require( 'fs' );
var contains = require( '@stdlib/assert/contains' );
var stdin = require( '@stdlib/process/read-stdin' );
var stdinStream = require( '@stdlib/streams/node/stdin' );
var RE_EOL = require( '@stdlib/regexp/eol' ).REGEXP;
var removePunctuation = require( '@stdlib/string/remove-punctuation' );
var readJSON = require( '@stdlib/fs/read-json' ).sync;
var replace = require( '@stdlib/string/replace' );
var camelcase = require( '@stdlib/string/camelcase' );
var currentYear = require( '@stdlib/time/current-year' );
var rootDir = require( '@stdlib/_tools/utils/root-dir' );

// VARIABLES //

var IMPORT_STATEMENT = 'import <name> = require( \'<path>\' );';
var RE_TS_EXPORT = /export = ([^;]+);/;
var RE_EXAMPLE = /@example[\s\S]*?(?=@example|\*\/)/g;
var RE_NAMESPACE = /@namespace ([a-z.0-9]+)/i;
var RE_COPYRIGHT_YEAR = /Copyright \(c\) (\d{4}) The Stdlib Authors\./;

// FUNCTIONS //

/**
* Returns contents of a `test.ts` file for the chosen namespace.
*
* @private
* @param {string} ns - namespace name
* @returns {string} `test.ts` contents
*/
function createTestFile( ns ) {
	ns = camelcase( ns );
	return [
		'/*',
		'* @license Apache-2.0',
		'*',
		'* Copyright (c) {{year}} The Stdlib Authors.',
		'*',
		'* Licensed under the Apache License, Version 2.0 (the "License");',
		'* you may not use this file except in compliance with the License.',
		'* You may obtain a copy of the License at',
		'*',
		'*    http://www.apache.org/licenses/LICENSE-2.0',
		'*',
		'* Unless required by applicable law or agreed to in writing, software',
		'* distributed under the License is distributed on an "AS IS" BASIS,',
		'* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
		'* See the License for the specific language governing permissions and',
		'* limitations under the License.',
		'*/',
		'',
		'/* tslint:disable:no-unused-expression */',
		'',
		'import '+ns+' = require( \'./index\' );',
		'',
		'',
		'// TESTS //',
		'',
		'// The exported value is the expected interface...',
		'{',
		'	'+ns+'; // $ExpectType Namespace',
		'}',
		''
	].join( '\n' );
}

/**
* Returns contents of a `index.d.ts` definition file for the chosen namespace.
*
* @private
* @param {string} ns - namespace name
* @param {Array<string>} imports - import statements for namespace packages
* @param {Array<string>} properties - interface property documentation for namespace contents
* @param {string} description - namespace description
* @returns {string} `index.d.ts` contents
*/
function createDefinitionFile( ns, imports, properties, description ) {
	return [
		'/*',
		'* @license Apache-2.0',
		'*',
		'* Copyright (c) {{year}} The Stdlib Authors.',
		'*',
		'* Licensed under the Apache License, Version 2.0 (the "License");',
		'* you may not use this file except in compliance with the License.',
		'* You may obtain a copy of the License at',
		'*',
		'*    http://www.apache.org/licenses/LICENSE-2.0',
		'*',
		'* Unless required by applicable law or agreed to in writing, software',
		'* distributed under the License is distributed on an "AS IS" BASIS,',
		'* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
		'* See the License for the specific language governing permissions and',
		'* limitations under the License.',
		'*/',
		'',
		'// TypeScript Version: 2.0',
		'',
		'/* tslint:disable:max-line-length */',
		'/* tslint:disable:max-file-line-count */',
		'',
		imports.join( '\n' ),
		'',
		'/**',
		'* Interface describing the `'+ns+'` namespace.',
		'*/',
		'interface Namespace {',
		properties.join( '\n' ),
		'}',
		'',
		'/**',
		'* '+description,
		'*/',
		'declare var ns: Namespace;',
		'',
		'',
		'// EXPORTS //',
		'',
		'export = ns;',
		''
	].join( '\n' );
}

/**
* Creates Typescript definition and test files for the chosen namespace.
*
* @private
* @param {string} fullPath - full namespace name
* @returns {void}
*/
function create( fullPath ) {
	var RE_DOC_MAIN_DECLARE;
	var copyrightYear;
	var nsIdentifier;
	var defFilePath;
	var description;
	var importStmts;
	var entryPoint;
	var mainExport;
	var properties;
	var indexFile;
	var tsDefPath;
	var testFile;
	var typesDir;
	var defFile;
	var pkgPath;
	var match;
	var tsDef;
	var tsDoc;
	var name;
	var last;
	var prop;
	var stmt;
	var str;
	var ns;
	var RE;

	importStmts = [];
	properties = [];

	if ( fullPath === '@stdlib/stdlib' ) {
		// Special case of creating type definitions for the main `@stdlib/stdlib` package:
		ns = 'stdlib';
		entryPoint = path.join( rootDir(), 'lib', 'main.js' );
	}
	else {
		ns = path.basename( fullPath );
		entryPoint = require.resolve( fullPath );
	}
	fullPath = path.join( entryPoint, '..', '..' );
	typesDir = path.join( fullPath, 'docs', 'types' );

	if ( !fs.existsSync( typesDir ) ) {
		return;
	}
	defFilePath = path.join( typesDir, 'index.d.ts' );

	if ( fs.existsSync( defFilePath ) ) {
		// Use existing copyright year from definition file if available...
		defFile = fs.readFileSync( defFilePath, 'utf8' );
		match = defFile.match( RE_COPYRIGHT_YEAR );
		copyrightYear = match ? match[ 1 ] : currentYear();
	} else {
		// Use current year as copyright year:
		copyrightYear = currentYear();
	}

	// Extract the copyright year from the existing definition file...
	RE_DOC_MAIN_DECLARE = /@declare\s+(\w+)\s+\((\w+)\)/;

	indexFile = fs.readFileSync( entryPoint, 'utf-8' );
	console.log( 'Loading '+entryPoint+'...' );
	if ( !RE_NAMESPACE.test( indexFile ) ) {
		return;
	}
	nsIdentifier = RE_NAMESPACE.exec( indexFile )[ 1 ];
	nsIdentifier = removePunctuation( nsIdentifier );
	RE = new RegExp( 'setReadOnly\\( '+nsIdentifier+', \'([a-z0-9_]+)\', require\\( \'([^\']+)\' \\) \\)', 'ig' );
	match = RE.exec( indexFile );
	if ( !match ) {
		nsIdentifier = 'ns';
		RE = new RegExp( 'setReadOnly\\( '+nsIdentifier+', \'([a-z0-9_]+)\', require\\( \'([^\']+)\' \\) \\)', 'ig' );
		match = RE.exec( indexFile );
	}
	while ( match !== null) {
		name = match[ 1 ];
		pkgPath = match[ 2 ];
		stmt = replace( IMPORT_STATEMENT, '<name>', name );
		stmt = replace( stmt, '<path>', pkgPath );
		importStmts.push( stmt );

		tsDefPath = replace( require.resolve( pkgPath ), 'lib/index.js', 'docs/types/index.d.ts' );
		if ( fs.existsSync( tsDefPath ) ) {
			tsDef = fs.readFileSync( tsDefPath, 'utf-8' );
			mainExport = tsDef.match( RE_TS_EXPORT );
			RE_DOC_MAIN_DECLARE = new RegExp( '(\\/\\*\\*\\n[\\s\\S]+?\\*\\/)\ndeclare (function|var|const) '+mainExport[ 1 ]+'([\\s\\S]*): ([\\s\\S]+?);' );
			last = tsDef.lastIndexOf( '/**' );
			tsDoc = tsDef.substring( last ).match( RE_DOC_MAIN_DECLARE );
			if ( !tsDoc ) {
				tsDoc = tsDef.match( /(\/\*\*\n[^/]+?\*\/)\ndeclare class/ );
			}
			prop = '\t'+name+': typeof '+name+';';
			if ( tsDoc && tsDoc[ 1 ] ) {
				str = tsDoc[ 1 ];
				str = replace( str, RE_EXAMPLE, onReplace );
				str = replace( str, '\n', '\n\t' );
				prop = '\t' + str + '\n' + prop;
			}
			else {
				tsDoc = tsDef.match( /(\/\*\*\n[\s\S]+?\*\/)\nexport =/ );
				if ( tsDoc && tsDoc[ 1 ] ) {
					str = tsDoc[ 1 ];
					str = replace( str, RE_EXAMPLE, onReplace );
					str = replace( str, '\n', '\n\t' );
					prop = '\t' + str + '\n' + prop;
				}
			}
			match = RE.exec( indexFile );
			if ( match ) {
				prop += '\n';
			}
			properties.push( prop );
		} else {
			match = RE.exec( indexFile );
		}
	}
	description = readJSON( path.join( fullPath, 'package.json' ) ).description;

	console.log( 'Writing definition file...' );
	defFile = createDefinitionFile( ns, importStmts, properties, description );
	defFile = replace( defFile, '{{year}}', String( copyrightYear ) );
	fs.writeFileSync( defFilePath, defFile );

	console.log( 'Writing test file...' );
	testFile = createTestFile( ns );
	testFile = replace( testFile, '{{year}}', String( copyrightYear ) );
	fs.writeFileSync( path.join( typesDir, 'test.ts' ), testFile );

	/**
	* Replaces variable names inside of example code to use exported namespace methods.
	*
	* @private
	* @param {string} match - example code
	* @returns {string} example code using namespace exports
	*/
	function onReplace( match ) {
		var RE;

		match = replace( match, mainExport[ 1 ], name );
		RE = new RegExp( '([^a-zA-Z@])'+name, 'g' );
		return replace( match, RE, '$1ns.'+name );
	}
}

/**
* Callback invoked upon reading from `stdin`.
*
* @private
* @param {(Error|null)} error - error object
* @param {Buffer} data - data
* @returns {void}
*/
function onRead( error, data ) {
	var lines;
	var i;
	if ( error ) {
		return console.error( error.message );
	}
	lines = data.toString().split( RE_EOL );
	for ( i = 0; i < lines.length; i++ ) {
		if ( lines[ i ] && !contains( lines[ i ], '_tools' ) ) {
			create( lines[ i ] );
		}
	}
}

/**
* Main execution sequence.
*
* @private
* @returns {void}
*/
function main() {
	// Check if we are receiving data from `stdin`...
	if ( !stdinStream.isTTY ) {
		return stdin( onRead );
	}
	create( process.argv[ 2 ] );
}

main();
<commit_msg>Use generic name in namespace TypeScript tests<commit_after>#!/usr/bin/env node

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

/* eslint-disable node/no-sync, node/shebang, no-console */

'use strict';

// MAIN //

var path = require( 'path' );
var fs = require( 'fs' );
var contains = require( '@stdlib/assert/contains' );
var stdin = require( '@stdlib/process/read-stdin' );
var stdinStream = require( '@stdlib/streams/node/stdin' );
var RE_EOL = require( '@stdlib/regexp/eol' ).REGEXP;
var removePunctuation = require( '@stdlib/string/remove-punctuation' );
var readJSON = require( '@stdlib/fs/read-json' ).sync;
var replace = require( '@stdlib/string/replace' );
var camelcase = require( '@stdlib/string/camelcase' );
var currentYear = require( '@stdlib/time/current-year' );
var rootDir = require( '@stdlib/_tools/utils/root-dir' );

// VARIABLES //

var IMPORT_STATEMENT = 'import <name> = require( \'<path>\' );';
var RE_TS_EXPORT = /export = ([^;]+);/;
var RE_EXAMPLE = /@example[\s\S]*?(?=@example|\*\/)/g;
var RE_NAMESPACE = /@namespace ([a-z.0-9]+)/i;
var RE_COPYRIGHT_YEAR = /Copyright \(c\) (\d{4}) The Stdlib Authors\./;

// FUNCTIONS //

/**
* Returns contents of a `test.ts` file for the chosen namespace.
*
* @private
* @returns {string} `test.ts` contents
*/
function createTestFile() {
	return [
		'/*',
		'* @license Apache-2.0',
		'*',
		'* Copyright (c) {{year}} The Stdlib Authors.',
		'*',
		'* Licensed under the Apache License, Version 2.0 (the "License");',
		'* you may not use this file except in compliance with the License.',
		'* You may obtain a copy of the License at',
		'*',
		'*    http://www.apache.org/licenses/LICENSE-2.0',
		'*',
		'* Unless required by applicable law or agreed to in writing, software',
		'* distributed under the License is distributed on an "AS IS" BASIS,',
		'* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
		'* See the License for the specific language governing permissions and',
		'* limitations under the License.',
		'*/',
		'',
		'/* tslint:disable:no-unused-expression */',
		'',
		'import ns = require( \'./index\' );',
		'',
		'',
		'// TESTS //',
		'',
		'// The exported value is the expected interface...',
		'{',
		'	ns; // $ExpectType Namespace',
		'}',
		''
	].join( '\n' );
}

/**
* Returns contents of a `index.d.ts` definition file for the chosen namespace.
*
* @private
* @param {string} ns - namespace name
* @param {Array<string>} imports - import statements for namespace packages
* @param {Array<string>} properties - interface property documentation for namespace contents
* @param {string} description - namespace description
* @returns {string} `index.d.ts` contents
*/
function createDefinitionFile( ns, imports, properties, description ) {
	return [
		'/*',
		'* @license Apache-2.0',
		'*',
		'* Copyright (c) {{year}} The Stdlib Authors.',
		'*',
		'* Licensed under the Apache License, Version 2.0 (the "License");',
		'* you may not use this file except in compliance with the License.',
		'* You may obtain a copy of the License at',
		'*',
		'*    http://www.apache.org/licenses/LICENSE-2.0',
		'*',
		'* Unless required by applicable law or agreed to in writing, software',
		'* distributed under the License is distributed on an "AS IS" BASIS,',
		'* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
		'* See the License for the specific language governing permissions and',
		'* limitations under the License.',
		'*/',
		'',
		'// TypeScript Version: 2.0',
		'',
		'/* tslint:disable:max-line-length */',
		'/* tslint:disable:max-file-line-count */',
		'',
		imports.join( '\n' ),
		'',
		'/**',
		'* Interface describing the `'+ns+'` namespace.',
		'*/',
		'interface Namespace {',
		properties.join( '\n' ),
		'}',
		'',
		'/**',
		'* '+description,
		'*/',
		'declare var ns: Namespace;',
		'',
		'',
		'// EXPORTS //',
		'',
		'export = ns;',
		''
	].join( '\n' );
}

/**
* Creates Typescript definition and test files for the chosen namespace.
*
* @private
* @param {string} fullPath - full namespace name
* @returns {void}
*/
function create( fullPath ) {
	var RE_DOC_MAIN_DECLARE;
	var copyrightYear;
	var nsIdentifier;
	var defFilePath;
	var description;
	var importStmts;
	var entryPoint;
	var mainExport;
	var properties;
	var indexFile;
	var tsDefPath;
	var testFile;
	var typesDir;
	var defFile;
	var pkgPath;
	var match;
	var tsDef;
	var tsDoc;
	var name;
	var last;
	var prop;
	var stmt;
	var str;
	var ns;
	var RE;

	importStmts = [];
	properties = [];

	if ( fullPath === '@stdlib/stdlib' ) {
		// Special case of creating type definitions for the main `@stdlib/stdlib` package:
		ns = 'stdlib';
		entryPoint = path.join( rootDir(), 'lib', 'main.js' );
	}
	else {
		ns = path.basename( fullPath );
		entryPoint = require.resolve( fullPath );
	}
	fullPath = path.join( entryPoint, '..', '..' );
	typesDir = path.join( fullPath, 'docs', 'types' );

	if ( !fs.existsSync( typesDir ) ) {
		return;
	}
	defFilePath = path.join( typesDir, 'index.d.ts' );

	if ( fs.existsSync( defFilePath ) ) {
		// Use existing copyright year from definition file if available...
		defFile = fs.readFileSync( defFilePath, 'utf8' );
		match = defFile.match( RE_COPYRIGHT_YEAR );
		copyrightYear = match ? match[ 1 ] : currentYear();
	} else {
		// Use current year as copyright year:
		copyrightYear = currentYear();
	}

	// Extract the copyright year from the existing definition file...
	RE_DOC_MAIN_DECLARE = /@declare\s+(\w+)\s+\((\w+)\)/;

	indexFile = fs.readFileSync( entryPoint, 'utf-8' );
	console.log( 'Loading '+entryPoint+'...' );
	if ( !RE_NAMESPACE.test( indexFile ) ) {
		return;
	}
	nsIdentifier = RE_NAMESPACE.exec( indexFile )[ 1 ];
	nsIdentifier = removePunctuation( nsIdentifier );
	RE = new RegExp( 'setReadOnly\\( '+nsIdentifier+', \'([a-z0-9_]+)\', require\\( \'([^\']+)\' \\) \\)', 'ig' );
	match = RE.exec( indexFile );
	if ( !match ) {
		nsIdentifier = 'ns';
		RE = new RegExp( 'setReadOnly\\( '+nsIdentifier+', \'([a-z0-9_]+)\', require\\( \'([^\']+)\' \\) \\)', 'ig' );
		match = RE.exec( indexFile );
	}
	while ( match !== null) {
		name = match[ 1 ];
		pkgPath = match[ 2 ];
		stmt = replace( IMPORT_STATEMENT, '<name>', name );
		stmt = replace( stmt, '<path>', pkgPath );
		importStmts.push( stmt );

		tsDefPath = replace( require.resolve( pkgPath ), 'lib/index.js', 'docs/types/index.d.ts' );
		if ( fs.existsSync( tsDefPath ) ) {
			tsDef = fs.readFileSync( tsDefPath, 'utf-8' );
			mainExport = tsDef.match( RE_TS_EXPORT );
			RE_DOC_MAIN_DECLARE = new RegExp( '(\\/\\*\\*\\n[\\s\\S]+?\\*\\/)\ndeclare (function|var|const) '+mainExport[ 1 ]+'([\\s\\S]*): ([\\s\\S]+?);' );
			last = tsDef.lastIndexOf( '/**' );
			tsDoc = tsDef.substring( last ).match( RE_DOC_MAIN_DECLARE );
			if ( !tsDoc ) {
				tsDoc = tsDef.match( /(\/\*\*\n[^/]+?\*\/)\ndeclare class/ );
			}
			prop = '\t'+name+': typeof '+name+';';
			if ( tsDoc && tsDoc[ 1 ] ) {
				str = tsDoc[ 1 ];
				str = replace( str, RE_EXAMPLE, onReplace );
				str = replace( str, '\n', '\n\t' );
				prop = '\t' + str + '\n' + prop;
			}
			else {
				tsDoc = tsDef.match( /(\/\*\*\n[\s\S]+?\*\/)\nexport =/ );
				if ( tsDoc && tsDoc[ 1 ] ) {
					str = tsDoc[ 1 ];
					str = replace( str, RE_EXAMPLE, onReplace );
					str = replace( str, '\n', '\n\t' );
					prop = '\t' + str + '\n' + prop;
				}
			}
			match = RE.exec( indexFile );
			if ( match ) {
				prop += '\n';
			}
			properties.push( prop );
		} else {
			match = RE.exec( indexFile );
		}
	}
	description = readJSON( path.join( fullPath, 'package.json' ) ).description;

	console.log( 'Writing definition file...' );
	defFile = createDefinitionFile( ns, importStmts, properties, description );
	defFile = replace( defFile, '{{year}}', String( copyrightYear ) );
	fs.writeFileSync( defFilePath, defFile );

	console.log( 'Writing test file...' );
	testFile = createTestFile( ns );
	testFile = replace( testFile, '{{year}}', String( copyrightYear ) );
	fs.writeFileSync( path.join( typesDir, 'test.ts' ), testFile );

	/**
	* Replaces variable names inside of example code to use exported namespace methods.
	*
	* @private
	* @param {string} match - example code
	* @returns {string} example code using namespace exports
	*/
	function onReplace( match ) {
		var RE;

		match = replace( match, mainExport[ 1 ], name );
		RE = new RegExp( '([^a-zA-Z@])'+name, 'g' );
		return replace( match, RE, '$1ns.'+name );
	}
}

/**
* Callback invoked upon reading from `stdin`.
*
* @private
* @param {(Error|null)} error - error object
* @param {Buffer} data - data
* @returns {void}
*/
function onRead( error, data ) {
	var lines;
	var i;
	if ( error ) {
		return console.error( error.message );
	}
	lines = data.toString().split( RE_EOL );
	for ( i = 0; i < lines.length; i++ ) {
		if ( lines[ i ] && !contains( lines[ i ], '_tools' ) ) {
			create( lines[ i ] );
		}
	}
}

/**
* Main execution sequence.
*
* @private
* @returns {void}
*/
function main() {
	// Check if we are receiving data from `stdin`...
	if ( !stdinStream.isTTY ) {
		return stdin( onRead );
	}
	create( process.argv[ 2 ] );
}

main();
<|endoftext|>


<commit_before>/**
 * @class Denkmal_Component_MessageList_Abstract
 * @extends Denkmal_Component_Abstract
 */
var Denkmal_Component_MessageList_Abstract = Denkmal_Component_Abstract.extend({

  /** @type String */
  _class: 'Denkmal_Component_MessageList_Abstract',

  /** @type {Boolean} */
  isAdmin: false,

  events: {
    'click .deleteMessage': function(event) {
      var messageId = $(event.currentTarget).closest('.message').data('id');
      this.deleteMessage(messageId);
    },
    'click .showImage': function(event) {
      var $image = $(event.currentTarget);
      $image.floatOut();
    }
  },

  /**
   * @param {Number} messageId
   */
  deleteMessage: function(messageId) {
    this.ajaxModal('deleteMessage', {message: messageId});
  },

  /**
   * @param {Object} message
   */
  prependMessage: function(message) {
    if (this.$('.messageList > .message[data-id="' + message.id + '"]').length > 0) {
      return;
    }
    this.renderTemplate('template-message', {
      id: message.id,
      created: message.created,
      venue: message.venue.name,
      hasText: message.text !== null,
      text: message.text,
      hasImage: message.image !== null,
      imageUrl: (message.image !== null) ? message.image['url-thumb'] : null,
      hasTags: (message.tagList.length > 0),
      tagList: message.tagList,
      hasUser: (message.user !== null),
      user: message.user,
      isAdmin: this.isAdmin
    }).prependTo(this.$('.messageList'));
  }
});
<commit_msg>Allow to close floatout image with click<commit_after>/**
 * @class Denkmal_Component_MessageList_Abstract
 * @extends Denkmal_Component_Abstract
 */
var Denkmal_Component_MessageList_Abstract = Denkmal_Component_Abstract.extend({

  /** @type String */
  _class: 'Denkmal_Component_MessageList_Abstract',

  /** @type {Boolean} */
  isAdmin: false,

  events: {
    'click .deleteMessage': function(event) {
      var messageId = $(event.currentTarget).closest('.message').data('id');
      this.deleteMessage(messageId);
    },
    'click .showImage': function(event) {
      var $image = $(event.currentTarget);
      this.showImage($image);
    }
  },

  /**
   * @param {jQuery} $image
   */
  showImage: function($image) {
    $image.floatOut();

    $image.on('click.closeImage', function() {
      $image.floatIn();
    });
    $image.on('floatbox-close', function() {
      $image.off('click.closeImage');
    });
  },

  /**
   * @param {Number} messageId
   */
  deleteMessage: function(messageId) {
    this.ajaxModal('deleteMessage', {message: messageId});
  },

  /**
   * @param {Object} message
   */
  prependMessage: function(message) {
    if (this.$('.messageList > .message[data-id="' + message.id + '"]').length > 0) {
      return;
    }
    this.renderTemplate('template-message', {
      id: message.id,
      created: message.created,
      venue: message.venue.name,
      hasText: message.text !== null,
      text: message.text,
      hasImage: message.image !== null,
      imageUrl: (message.image !== null) ? message.image['url-thumb'] : null,
      hasTags: (message.tagList.length > 0),
      tagList: message.tagList,
      hasUser: (message.user !== null),
      user: message.user,
      isAdmin: this.isAdmin
    }).prependTo(this.$('.messageList'));
  }
});
<|endoftext|>


<commit_before>import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(<App />, document.getElementById('app'))
<commit_msg>Update demo to use ReactDOM.createRoot<commit_after>import React from 'react'
import { createRoot } from 'react-dom/client'
import App from './App'

const root = createRoot(document.getElementById('app'));
root.render(<App />);
<|endoftext|>


<commit_before>var _ = require('underscore'),
    fs = require('fs'),
    path = require('path');

module.exports = function(static) {
  var outputPluginIndex = _.debounce(function() {
    pluginIndex.update();
  }, 1000);

  var plugins = {},
      pluginIndex = static.createFile('plugins/index.html');

  //process markdown files with handlebars then markdown
  static.file(/plugins\/.+\.md$/, function(file) {
    file.transform(function(buffer, next) {
      var content = buffer.toString(),
          title = /^#\s*(.*?)\s*#*$/m.exec(content);
      plugins[file.target] = {
        title: title && title[1],
        summary: ''
      };
      next(buffer);
    });
  });
  static.file(/\.(md|markdown)$/, function(file) {
    file.transform('markdown');
    file.changeExtensionTo('html');
  });

  //process handlebars files with handlebars
  static.file(/\.handlebars$/, function(file) {
    file.transform('handlebars');
    file.changeExtensionTo('html');
  });

  //process stylus files with stylus
  static.file(/\.styl$/, function(file) {
    file.transform('stylus');
    file.changeExtensionTo('css');
  });

  //copy assets to assets folder in target
  static.file(/^assets\//, function(file) {
    file.write('assets');
  });

  //copy scripts to scripts folder in target
  static.file(/^scripts\//, function(file) {
    file.write('scripts');
  });

  //copy styles to styles folder in target
  static.file(/^styles\//, function(file) {
    file.write('styles');
  });

  //copy pages to root
  static.file(/\.(?:html?|md)$/, function(file) {
    //add package.json values to scope of file
    for (var key in static.package) {
      file.set(key, static.package[key]);
    }

    //save to root of target directory
    file.write('.', '');

    //wrap pages in template
    file.transform(function(buffer, next) {
      next(file.render('templates/index.handlebars', {
        yield: buffer
      }));
    });
  });

  static.file(/(plugins\/)?.+\.md$/, function(file) {
    file.$(function(window) {
      //set the title of the page to be the first h1 in the body if present
      var title, title_element = window.$('.container h1:first')[0];
      if (title_element) {
        title = title_element.innerHTML;
        window.$('title').html(title)
      }

      // Update all markdown links to point to the html equivalent
      // NOTE: forEach is not supported by the return from $ in this context
      var anchors = window.$('a[href$=".md"]');
      for (var i = 0; i < anchors.length; i++) {
        var anchor = anchors[i];
        anchor.href = anchor.getAttribute('href').replace(/\.md$/, '.html');
      }
    });
  });

  static.file(/[^\/]+\.md$/, function(file) {
    file.$(function(window) {
      //assign ids
      window.$('.container h2').each(function() {
        this.id = this.innerHTML.split(/\s/).shift().replace(/\./g,'-').toLowerCase();
      });
      window.$('.container h3').each(function() {
        var name = this.innerHTML.split(/\s/).shift();
        var header = window.$(this).prevAll('h2:first')[0];
        this.id = (header.innerHTML.replace(/\./g,'-') + '-' + name).toLowerCase();
      });

      //build toc
      var toc_html = '
';
      window.$('.container h2').each(function() {
        toc_html += '
' + this.innerHTML + '';
        var signatures = window.$(this).nextUntil('h2').filter('h3');
        if (signatures.length) {
          toc_html += '
';
          signatures.each(function(){
            toc_html += '
' + this.innerHTML.split(/\</).shift() + '
'
          });
          toc_html += '

';
        }
      });
      toc_html += '
';

      //append toc
      window.$('#sidebar').html(toc_html);
    });
  });

  static.file(/plugins\/.+$/, function(file) {
    file.$(function(window) {
      var toc_html = '
'
        + '
Plugins'
        + '
';
      _.chain(plugins).keys().sort().each(function(name) {
        toc_html += '
' + plugins[name].title + '
';
      });
      toc_html += '

'
        + '
Home
'
        + '
';
      window.$('#sidebar').html(toc_html);

      // Collect the intro info (ignoring the index file)
      var plugin = plugins[file.target];
      if (plugin) {
        plugin.summary = '';
        window.$('#introduction').nextUntil('h2').each(function() {
          plugin.summary += this.outerHTML;
        });
      }
    });
  });

  static.file(/plugins\/index\.html$/, function(file) {
    file.$(function(window) {
      var pluginList = '';
      for (var name in plugins) {
        pluginList += '
' + plugins[name].title + '
' + plugins[name].summary;
      }

      window.$('.container').html(pluginList);
    });
  });

  static.file(/plugins\/.+\.md$/, function(file) {
    file.on('write', function(file, next) {
      outputPluginIndex()
      next();
    });
  });
};
<commit_msg>Simplify id header generation<commit_after>var _ = require('underscore'),
    fs = require('fs'),
    path = require('path');

module.exports = function(static) {
  var outputPluginIndex = _.debounce(function() {
    pluginIndex.update();
  }, 1000);

  var plugins = {},
      pluginIndex = static.createFile('plugins/index.html');

  //process markdown files with handlebars then markdown
  static.file(/plugins\/.+\.md$/, function(file) {
    file.transform(function(buffer, next) {
      var content = buffer.toString(),
          title = /^#\s*(.*?)\s*#*$/m.exec(content);
      plugins[file.target] = {
        title: title && title[1],
        summary: ''
      };
      next(buffer);
    });
  });
  static.file(/\.(md|markdown)$/, function(file) {
    file.transform('markdown');
    file.changeExtensionTo('html');
  });

  //process handlebars files with handlebars
  static.file(/\.handlebars$/, function(file) {
    file.transform('handlebars');
    file.changeExtensionTo('html');
  });

  //process stylus files with stylus
  static.file(/\.styl$/, function(file) {
    file.transform('stylus');
    file.changeExtensionTo('css');
  });

  //copy assets to assets folder in target
  static.file(/^assets\//, function(file) {
    file.write('assets');
  });

  //copy scripts to scripts folder in target
  static.file(/^scripts\//, function(file) {
    file.write('scripts');
  });

  //copy styles to styles folder in target
  static.file(/^styles\//, function(file) {
    file.write('styles');
  });

  //copy pages to root
  static.file(/\.(?:html?|md)$/, function(file) {
    //add package.json values to scope of file
    for (var key in static.package) {
      file.set(key, static.package[key]);
    }

    //save to root of target directory
    file.write('.', '');

    //wrap pages in template
    file.transform(function(buffer, next) {
      next(file.render('templates/index.handlebars', {
        yield: buffer
      }));
    });
  });

  static.file(/(plugins\/)?.+\.md$/, function(file) {
    file.$(function(window) {
      //set the title of the page to be the first h1 in the body if present
      var title, title_element = window.$('.container h1:first')[0];
      if (title_element) {
        title = title_element.innerHTML;
        window.$('title').html(title)
      }

      // Update all markdown links to point to the html equivalent
      // NOTE: forEach is not supported by the return from $ in this context
      var anchors = window.$('a[href$=".md"]');
      for (var i = 0; i < anchors.length; i++) {
        var anchor = anchors[i];
        anchor.href = anchor.getAttribute('href').replace(/\.md$/, '.html');
      }
    });
  });

  static.file(/[^\/]+\.md$/, function(file) {
    file.$(function(window) {
      //assign ids
      window.$('h2, h3, h4').each(function() {
        this.id = this.innerHTML.split(/\s/).shift().replace(/\./g,'-').toLowerCase();
      });

      //build toc
      var toc_html = '
';
      window.$('h2').each(function() {
        toc_html += '
' + this.innerHTML + '';
        var signatures = window.$(this).nextUntil('h2').filter('h3');
        if (signatures.length) {
          toc_html += '
';
          signatures.each(function(){
            toc_html += '
' + this.innerHTML.split(/\</).shift() + '
'
          });
          toc_html += '

';
        }
      });
      toc_html += '
';

      //append toc
      window.$('#sidebar').html(toc_html);
    });
  });

  static.file(/plugins\/.+$/, function(file) {
    file.$(function(window) {
      var toc_html = '
'
        + '
Plugins'
        + '
';
      _.chain(plugins).keys().sort().each(function(name) {
        toc_html += '
' + plugins[name].title + '
';
      });
      toc_html += '

'
        + '
Home
'
        + '
';
      window.$('#sidebar').html(toc_html);

      // Collect the intro info (ignoring the index file)
      var plugin = plugins[file.target];
      if (plugin) {
        plugin.summary = '';
        window.$('#introduction').nextUntil('h2').each(function() {
          plugin.summary += this.outerHTML;
        });
      }
    });
  });

  static.file(/plugins\/index\.html$/, function(file) {
    file.$(function(window) {
      var pluginList = '';
      for (var name in plugins) {
        pluginList += '
' + plugins[name].title + '
' + plugins[name].summary;
      }

      window.$('.container').html(pluginList);
    });
  });

  static.file(/plugins\/.+\.md$/, function(file) {
    file.on('write', function(file, next) {
      outputPluginIndex()
      next();
    });
  });
};
<|endoftext|>