<commit_before>import React, { Component } from 'react'
import { Field, FieldArray, reduxForm, formValueSelector,  change  } from 'redux-form'
import validate from './validate'
import {processInputFileMetadata} from './avroschema.js'
import Dropzone from 'react-dropzone'
import TestSelect2 from './TestSelect2';
import { connect } from 'react-redux';
import {
  Modal,
  ModalHeader,
  ModalTitle,
  ModalClose,
  ModalBody,
  ModalFooter
} from 'react-modal-bootstrap';
import OverlayLoader from 'react-overlay-loading/lib/OverlayLoader'

/*
const calcDataFields = (obj, fields, files) =>
     processInputFileMetadata(files, (resData)=>{
        console.log(JSON.stringify(resData))
        resData.names.map((item, index) => {
           console.log(item)
           fields.push({nome : item, tipo : resData.props[index].type, concetto : '',
            desc : '', required : 0, field_type : '' , cat : '', tag : '',
            constr : [{"`type`": "","param": ""}], semantics : { id: '',context: '' },
            data :  resData.data[item]})
        } ,
          fields.push({nome : 'file', tipo : files[0]})
        )
        obj.setState({uploading: false})
     })
*/

//  var metadata = { "desc": "", "required": 0, "field_type": "","cat": "","tag": "","constr": [{"`type`": "","param": ""}],"semantics": {"id": "","context": ""}}
const themes = [
{'val' : 'AGRI', 'name' : 'AGRICOLTURA'},{'val' : 'EDUC', 'name' : 'EDUCAZIONE'},
{'val' : 'ECON', 'name' : 'ECONOMIA'},
{'val' : 'ENVI', 'name' : 'AMBIENTE'},{'val' : 'HEAL', 'name' : 'SANITA'},
{'val' : 'INTR', 'name' : 'INTERNAZIONALE'},{'val' : 'JUST', 'name' : 'GIUSTIZIA'},
{'val' : 'SOCI', 'name' : 'REGIONE'},{'val' : 'TECH', 'name' : 'TECNOLOGIA'},
{'val' : 'TRAN', 'name' : 'TRASPORTO'}]

const renderThemes = ({ input, meta: { touched, error } }) => (

      Categoria

          <select className="form-control" {...input}>
            {themes.map(value => <option value={value.val} key={value.val}>{value.name}</option>)}
          </select>
        {touched && error &&
{error}
}

);

const renderField = ({ input, label, type, value = '', readonly, meta: { touched, error } }) => (

    {label}
      {(touched && error) ?

          <input {...input} placeholder={label} type={type} className="form-control form-control-danger"/>

{error}

      :

          <input {...input} placeholder={label} readOnly={readonly} type={type} className="form-control"/>

      }

)

  const renderFieldMeta = ({ input, label, type, value = '', meta: { touched, error } }) => (

    {label}

      <input {...input} placeholder={label} type={type} className="form-control"/>
      {touched && error &&
{error}
}

)

const renderYesNoSelector = ({ input, type, label, value, meta: { touched, error } }) => (

    {label}

    <select className="form-control" {...input}>
      <option value="0" defaultValue key='false'>No</option>
      <option value="1" key="1">Si</option>
    </select>
    {touched && error &&
{error}
}

);

const renderFieldType = ({ input, meta: { touched, error } }) => (

    Tipo Colonna

    <select className="form-control" {...input}>
      <option value="" defaultValue key=''></option>
      <option value="dimension" key='dimension'>Dimensione</option>
      <option value="numerical" key="numerical">Valore numerico</option>
      <option value="textual" key="textual">Valore testuale</option>
    </select>
    {touched && error &&
{error}
}

);

const addMetadataFromFile = ({ fields, meta: { error, submitFailed } }) =>

      <button type="button" onClick={() => fields.push({})}>
        Add Member
      </button>
      {submitFailed &&
        error &&

{error}
}

    {fields.map((test, index) =>

        <button
          type="button"
          title="Remove Member"

          onClick={() => fields.remove(index)}
        />

          Member #{index + 1}

        <Field
          name={`${test}.nome`}
          type="text"
          component={renderField}
          label="Nome Campo"
          value={`${test}.nome`}
        />
        <Field
          name={`${test}.tipo`}
          type="text"
          component={renderField}
          label="Tipo"
          value={`${test}.tipo`}
        />

    )}

class WizardFormMetadata extends Component {
  constructor(props) {
    super(props);
    this.state = {
      files: [],
      uploading: false
    }
    this.calcDataFields = this.calcDataFields.bind(this);
    this.setUploading = this.setUploading.bind(this);
  }

  setUploading(obj, state){
    console.log('setUploading')
    console.log(obj)
    console.log('state: ' + state)
    obj.setState({uploading: state})
  }

  calcDataFields (obj, fields, files) {
    processInputFileMetadata(files, (resData)=>{
      resData.names.map((item, index) => {
          fields.push({nome : item, tipo : resData.props[index].type, concetto : '',
          desc : '', required : 0, field_type : '' , cat : '', tag : '',
          constr : [{"`type`": "","param": ""}], semantics : { id: '',context: '' },
          data :  resData.data[item]})
      } ,
        fields.push({nome : 'file', tipo : files[0]}),
      );
    });
  }

  renderDropzoneInput = ({fields,columnCard, input, reset, calcDataFields, meta : {touched, error} }) =>

      {fields.length === 0 &&

Benvenuto nel cruscotto per la registrazione di nuovi dataset.

Scegli se caricare il file tramite URL (PULL) oppure se caricare il file direttamente attraverso la dropbox (PUSH).

Nel caso scegliessi la seconda opzione se il file è minore di 10 mega verrà metadatato e caricato direttamente nel DAF altrimenti il file verrà lo stesso metadatato ma il contenuto dovrà essere caricato in un secondo momento.

Per ulteriori informazioni clicca qui

            Inserisci un link al tuo file:

              <input placeholder="http://" type="text" className="form-control-90"/>
              <button type="button"  className="btn btn-primary" data-toggle="button" aria-pressed="false" autoComplete="off"></button>

            Oppure carica il file (max 10MB):
            <OverlayLoader
              color={'blue'}
              loader="PulseLoader"
              text="Caricamento in corso..."
              active={this.state.uploading}
              backgroundColor={'grey'}
              >
              <Dropzone
                name="input"
                className="dropzone"
                multiple={false}
                maxSize={10485760}
                onDrop={( filesToUpload, e ) => {
                  //this.setUploading(this, true)
                  const {dispatch} = this.props
                  if(filesToUpload.length>0){
                    this.setState({errorDrop:''})
                    calcDataFields(this, fields, filesToUpload)
                    //this.setUploading(this, false)
                    let fileName = filesToUpload[0].name.toLowerCase().split(".")[0]
                    fileName = fileName.toLowerCase()
                    fileName.split(" ").join("-")
                    dispatch(change('wizard', 'title', fileName))
                  }else{
                    alert('Dimensioni file non consentite')
                    this.setState({errorDrop: 'Dimensioni file non consentite'})
                    this.setState({uploading: false})
                  }
                }
                }>

Trascina il tuo file qui, oppure clicca per selezionare il file da caricare.

                      {this.state.errorDrop &&

File non conforme alle specifiche, controllare la dimensione e l'estensione.

                      }

              </Dropzone>
          </OverlayLoader>

      }
      {touched && error &&
{error}
}
      {fields.map((test, index) =>
      (index == 0) ?

            <Field
              name={`${test}.tipo.name`}
              type="text"
              component={renderField}
              label="Nome File"
              value={`${test}.tipo.name`}
              readonly="readonly"
            />

            <button type="button" className="btn btn-primary" onClick={reset}>Elimina</button>

            <Field
              name={'private'}
              type="text"
              component={renderYesNoSelector}
              label="Privato"
            />

      :

              Colonna #{index}

            <Field
              name={`${test}.nome`}
              type="text"
              component={renderField}
              label="Nome Campo"
              value={`${test}.nome`}
            />
            <Field
              name={`${test}.tipo`}
              type="text"
              component={renderField}
              label="Tipo"
              value={`${test}.tipo`}
            />
            <Field
              name={`${test}.concetto`}
              type="text"
              component={TestSelect2}
              label="Concetto"
              value={`${test}.concetto`}
            />

Metadata  Colonna #{index}

            <Field
              name={`${test}.desc`}
              type="text"
              component={renderFieldMeta}
              label="Descrizione"
              value={`${test}.desc`}
            />
            <Field
              name={`${test}.required`}
              type="text"
              component={renderYesNoSelector}
              label="Obbligatorio"
              value={`${test}.required`}
            />
            <Field
              name={`${test}.field_type`}
              type="text"
              component={renderFieldType}
              label="Tipo Colonna"
              value={`${test}.field_type`}
            />
            <Field
              name={`${test}.cat`}
              type="text"
              component={renderFieldMeta}
              label="Categoria"
              value={`${test}.cat`}
            />

              <button type="button" onClick={() => fields.remove(index)} className="btn btn-primary float-right" data-toggle="button" aria-pressed="false" autoComplete="off">
                Rimuovi
              </button>

                Dati colonna #{index}

RT-1364431454

RT1803171066

RT1116389446

RT-543437881

RT128053814

RT179531997

RT-1976941392

      )}
      {fields.length > 0 &&

            <button type="submit" className="btn btn-primary float-right">Avanti</button>

}

  render() {
    const { handleSubmit, previousPage, pristine, submitting, reset, title, columnCard } = this.props;
    return (

    <form onSubmit={handleSubmit}>
        <FieldArray
              name="tests"
              component={this.renderDropzoneInput}
              title={title}
              reset={reset}
              columnCard={columnCard}
              calcDataFields={this.calcDataFields}
            />
    </form>

    )
  }
}

WizardFormMetadata = connect(state => {
  // can select values individually
  const nomefile = state.nomefile || 'prova';
  //const dataSample = state.dataSample || [];
  return {
    nomefile
    //,
 //   dataSample
  }
})(WizardFormMetadata)

export default reduxForm({
  form: 'wizard', //                 <------ same form name
  destroyOnUnmount: false, //        <------ preserve form data
  forceUnregisterOnUnmount: true, // <------ unregister fields on unmount
  validate,
})(WizardFormMetadata);
<commit_msg>ingestion form empty column data<commit_after>import React, { Component } from 'react'
import { Field, FieldArray, reduxForm, formValueSelector,  change  } from 'redux-form'
import validate from './validate'
import {processInputFileMetadata} from './avroschema.js'
import Dropzone from 'react-dropzone'
import TestSelect2 from './TestSelect2';
import { connect } from 'react-redux';
import {
  Modal,
  ModalHeader,
  ModalTitle,
  ModalClose,
  ModalBody,
  ModalFooter
} from 'react-modal-bootstrap';
import OverlayLoader from 'react-overlay-loading/lib/OverlayLoader'

/*
const calcDataFields = (obj, fields, files) =>
     processInputFileMetadata(files, (resData)=>{
        console.log(JSON.stringify(resData))
        resData.names.map((item, index) => {
           console.log(item)
           fields.push({nome : item, tipo : resData.props[index].type, concetto : '',
            desc : '', required : 0, field_type : '' , cat : '', tag : '',
            constr : [{"`type`": "","param": ""}], semantics : { id: '',context: '' },
            data :  resData.data[item]})
        } ,
          fields.push({nome : 'file', tipo : files[0]})
        )
        obj.setState({uploading: false})
     })
*/

//  var metadata = { "desc": "", "required": 0, "field_type": "","cat": "","tag": "","constr": [{"`type`": "","param": ""}],"semantics": {"id": "","context": ""}}
const themes = [
{'val' : 'AGRI', 'name' : 'AGRICOLTURA'},{'val' : 'EDUC', 'name' : 'EDUCAZIONE'},
{'val' : 'ECON', 'name' : 'ECONOMIA'},
{'val' : 'ENVI', 'name' : 'AMBIENTE'},{'val' : 'HEAL', 'name' : 'SANITA'},
{'val' : 'INTR', 'name' : 'INTERNAZIONALE'},{'val' : 'JUST', 'name' : 'GIUSTIZIA'},
{'val' : 'SOCI', 'name' : 'REGIONE'},{'val' : 'TECH', 'name' : 'TECNOLOGIA'},
{'val' : 'TRAN', 'name' : 'TRASPORTO'}]

const renderThemes = ({ input, meta: { touched, error } }) => (

      Categoria

          <select className="form-control" {...input}>
            {themes.map(value => <option value={value.val} key={value.val}>{value.name}</option>)}
          </select>
        {touched && error &&
{error}
}

);

const renderField = ({ input, label, type, value = '', readonly, meta: { touched, error } }) => (

    {label}
      {(touched && error) ?

          <input {...input} placeholder={label} type={type} className="form-control form-control-danger"/>

{error}

      :

          <input {...input} placeholder={label} readOnly={readonly} type={type} className="form-control"/>

      }

)

  const renderFieldMeta = ({ input, label, type, value = '', meta: { touched, error } }) => (

    {label}

      <input {...input} placeholder={label} type={type} className="form-control"/>
      {touched && error &&
{error}
}

)

const renderYesNoSelector = ({ input, type, label, value, meta: { touched, error } }) => (

    {label}

    <select className="form-control" {...input}>
      <option value="0" defaultValue key='false'>No</option>
      <option value="1" key="1">Si</option>
    </select>
    {touched && error &&
{error}
}

);

const renderFieldType = ({ input, meta: { touched, error } }) => (

    Tipo Colonna

    <select className="form-control" {...input}>
      <option value="" defaultValue key=''></option>
      <option value="dimension" key='dimension'>Dimensione</option>
      <option value="numerical" key="numerical">Valore numerico</option>
      <option value="textual" key="textual">Valore testuale</option>
    </select>
    {touched && error &&
{error}
}

);

const addMetadataFromFile = ({ fields, meta: { error, submitFailed } }) =>

      <button type="button" onClick={() => fields.push({})}>
        Add Member
      </button>
      {submitFailed &&
        error &&

{error}
}

    {fields.map((test, index) =>

        <button
          type="button"
          title="Remove Member"

          onClick={() => fields.remove(index)}
        />

          Member #{index + 1}

        <Field
          name={`${test}.nome`}
          type="text"
          component={renderField}
          label="Nome Campo"
          value={`${test}.nome`}
        />
        <Field
          name={`${test}.tipo`}
          type="text"
          component={renderField}
          label="Tipo"
          value={`${test}.tipo`}
        />

    )}

class WizardFormMetadata extends Component {
  constructor(props) {
    super(props);
    this.state = {
      files: [],
      uploading: false
    }
    this.calcDataFields = this.calcDataFields.bind(this);
    this.setUploading = this.setUploading.bind(this);
  }

  setUploading(obj, state){
    console.log('setUploading')
    console.log(obj)
    console.log('state: ' + state)
    obj.setState({uploading: state})
  }

  calcDataFields (obj, fields, files) {
    processInputFileMetadata(files, (resData)=>{
      resData.names.map((item, index) => {
          fields.push({nome : item, tipo : resData.props[index].type, concetto : '',
          desc : '', required : 0, field_type : '' , cat : '', tag : '',
          constr : [{"`type`": "","param": ""}], semantics : { id: '',context: '' },
          data :  resData.data[item]})
      } ,
        fields.push({nome : 'file', tipo : files[0]}),
      );
    });
  }

  renderDropzoneInput = ({fields,columnCard, input, reset, calcDataFields, meta : {touched, error} }) =>

      {fields.length === 0 &&

Benvenuto nel cruscotto per la registrazione di nuovi dataset.

Scegli se caricare il file tramite URL (PULL) oppure se caricare il file direttamente attraverso la dropbox (PUSH).

Nel caso scegliessi la seconda opzione se il file è minore di 10 mega verrà metadatato e caricato direttamente nel DAF altrimenti il file verrà lo stesso metadatato ma il contenuto dovrà essere caricato in un secondo momento.

Per ulteriori informazioni clicca qui

            Inserisci un link al tuo file:

              <input placeholder="http://" type="text" className="form-control-90"/>
              <button type="button"  className="btn btn-primary" data-toggle="button" aria-pressed="false" autoComplete="off"></button>

            Oppure carica il file (max 10MB):
            <OverlayLoader
              color={'blue'}
              loader="PulseLoader"
              text="Caricamento in corso..."
              active={this.state.uploading}
              backgroundColor={'grey'}
              >
              <Dropzone
                name="input"
                className="dropzone"
                multiple={false}
                maxSize={10485760}
                onDrop={( filesToUpload, e ) => {
                  //this.setUploading(this, true)
                  const {dispatch} = this.props
                  if(filesToUpload.length>0){
                    this.setState({errorDrop:''})
                    calcDataFields(this, fields, filesToUpload)
                    //this.setUploading(this, false)
                    let fileName = filesToUpload[0].name.toLowerCase().split(".")[0]
                    fileName = fileName.toLowerCase()
                    fileName.split(" ").join("-")
                    dispatch(change('wizard', 'title', fileName))
                  }else{
                    alert('Dimensioni file non consentite')
                    this.setState({errorDrop: 'Dimensioni file non consentite'})
                    this.setState({uploading: false})
                  }
                }
                }>

Trascina il tuo file qui, oppure clicca per selezionare il file da caricare.

                      {this.state.errorDrop &&

File non conforme alle specifiche, controllare la dimensione e l'estensione.

                      }

              </Dropzone>
          </OverlayLoader>

      }
      {touched && error &&
{error}
}
      {fields.map((test, index) =>
      (index == 0) ?

            <Field
              name={`${test}.tipo.name`}
              type="text"
              component={renderField}
              label="Nome File"
              value={`${test}.tipo.name`}
              readonly="readonly"
            />

            <button type="button" className="btn btn-primary" onClick={reset}>Elimina</button>

            <Field
              name={'private'}
              type="text"
              component={renderYesNoSelector}
              label="Privato"
            />

      :

              Colonna #{index}

            <Field
              name={`${test}.nome`}
              type="text"
              component={renderField}
              label="Nome Campo"
              value={`${test}.nome`}
            />
            <Field
              name={`${test}.tipo`}
              type="text"
              component={renderField}
              label="Tipo"
              value={`${test}.tipo`}
            />
            <Field
              name={`${test}.concetto`}
              type="text"
              component={TestSelect2}
              label="Concetto"
              value={`${test}.concetto`}
            />

Metadata  Colonna #{index}

            <Field
              name={`${test}.desc`}
              type="text"
              component={renderFieldMeta}
              label="Descrizione"
              value={`${test}.desc`}
            />
            <Field
              name={`${test}.required`}
              type="text"
              component={renderYesNoSelector}
              label="Obbligatorio"
              value={`${test}.required`}
            />
            <Field
              name={`${test}.field_type`}
              type="text"
              component={renderFieldType}
              label="Tipo Colonna"
              value={`${test}.field_type`}
            />
            <Field
              name={`${test}.cat`}
              type="text"
              component={renderFieldMeta}
              label="Categoria"
              value={`${test}.cat`}
            />

              <button type="button" onClick={() => fields.remove(index)} className="btn btn-primary float-right" data-toggle="button" aria-pressed="false" autoComplete="off">
                Rimuovi
              </button>

                Dati colonna #{index}

      )}
      {fields.length > 0 &&

            <button type="submit" className="btn btn-primary float-right">Avanti</button>

}

  render() {
    const { handleSubmit, previousPage, pristine, submitting, reset, title, columnCard } = this.props;
    return (

    <form onSubmit={handleSubmit}>
        <FieldArray
              name="tests"
              component={this.renderDropzoneInput}
              title={title}
              reset={reset}
              columnCard={columnCard}
              calcDataFields={this.calcDataFields}
            />
    </form>

    )
  }
}

WizardFormMetadata = connect(state => {
  // can select values individually
  const nomefile = state.nomefile || 'prova';
  //const dataSample = state.dataSample || [];
  return {
    nomefile
    //,
 //   dataSample
  }
})(WizardFormMetadata)

export default reduxForm({
  form: 'wizard', //                 <------ same form name
  destroyOnUnmount: false, //        <------ preserve form data
  forceUnregisterOnUnmount: true, // <------ unregister fields on unmount
  validate,
})(WizardFormMetadata);
<|endoftext|>


<commit_before>const path = require('path');
const webpack = require('webpack');
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const getBabelConfig = require('../utils/getBabelConfig');
const babelPreset = require('./babel-preset');
const config = require('./index');

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

const plugins = [
  new webpack.EnvironmentPlugin({ NODE_ENV: 'development' }),
  new webpack.NamedModulesPlugin(),
  new FriendlyErrorsPlugin(),
  new CaseSensitivePathsPlugin(),
];

if (isDev) {
  plugins.push(
    new webpack.NoEmitOnErrorsPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  );
} else {
  plugins.push(
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
      },
      mangle: true,
      sourceMap: true,
    }),
  );
}

const baseWebpackConfig = {
  plugins,
  entry: config.scripts.entries,
  output: {
    path: path.resolve(config.output, config.scripts.path),
    publicPath: config.scripts.publicPath,
    filename: '[name].js',
    chunkFilename: '[name].js',
  },
  context: path.resolve(config.source, config.scripts.path),
  devtool: isDev ? 'cheap-module-inline-source-map' : 'source-map',
  performance: {
    hints: false,
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        loader: 'babel-loader',
        options: Object.assign(
          {
            cacheDirectory: true,
          },
          babelPreset,
          getBabelConfig(config.source),
        ),
      },
      {
        test: /\.html$/,
        exclude: /(node_modules)/,
        loader: 'html-loader',
      },
    ],
  },
};

function withUserConfig(conf) {
  if (config.webpackConfig) {
    return config.webpackConfig(conf, { isDev });
  }

  return conf;
}

module.exports = withUserConfig(baseWebpackConfig);
<commit_msg>Put chunks in separate directory<commit_after>const path = require('path');
const webpack = require('webpack');
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const getBabelConfig = require('../utils/getBabelConfig');
const babelPreset = require('./babel-preset');
const config = require('./index');

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

const plugins = [
  new webpack.EnvironmentPlugin({ NODE_ENV: 'development' }),
  new webpack.NamedModulesPlugin(),
  new FriendlyErrorsPlugin(),
  new CaseSensitivePathsPlugin(),
];

if (isDev) {
  plugins.push(
    new webpack.NoEmitOnErrorsPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  );
} else {
  plugins.push(
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
      },
      mangle: true,
      sourceMap: true,
    }),
  );
}

const baseWebpackConfig = {
  plugins,
  entry: config.scripts.entries,
  output: {
    path: path.resolve(config.output, config.scripts.path),
    publicPath: config.scripts.publicPath,
    filename: '[name].js',
    chunkFilename: 'chunks/[name].js',
  },
  context: path.resolve(config.source, config.scripts.path),
  devtool: isDev ? 'cheap-module-inline-source-map' : 'source-map',
  performance: {
    hints: false,
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        loader: 'babel-loader',
        options: Object.assign(
          {
            cacheDirectory: true,
          },
          babelPreset,
          getBabelConfig(config.source),
        ),
      },
      {
        test: /\.html$/,
        exclude: /(node_modules)/,
        loader: 'html-loader',
      },
    ],
  },
};

function withUserConfig(conf) {
  if (config.webpackConfig) {
    return config.webpackConfig(conf, { isDev });
  }

  return conf;
}

module.exports = withUserConfig(baseWebpackConfig);
<|endoftext|>


<commit_before><commit_msg>Big fix: Submenu clones invalid nodes sometimes<commit_after><|endoftext|>


<commit_before>var _ = require('lib/underscore')._;
var Choice = require('models/choice');
var Question = require('models/question');
var Option = require('models/option');
var progressBarView = require('ui/common/components/ProgressBar');

var Answer = new Ti.App.joli.model({
  table : 'answers',
  columns : {
    id : 'INTEGER PRIMARY KEY',
    content : 'TEXT',
    response_id : 'INTEGER',
    question_id : 'INTEGER',
    web_id : 'INTEGER',
    updated_at : 'TEXT',
    image : 'TEXT',
    photo_updated_at : 'TEXT'
  },

  methods : {
    createRecord : function(answerData, responseID) {
      var _ = require('lib/underscore')._;
      var that = this;
      answerData.response_id = responseID
      var question = Question.findOneById(answerData['question_id']);
      if (question.type === 'MultiChoiceQuestion') {
        var optionIds = answerData['content'];
        answerData['content'] = "";
        answerData['updated_at'] = (new Date()).toString();
        var answer = that.newRecord(answerData);
        answer.save();
        _(optionIds).each(function(option_id) {
          Choice.createRecord(answer.id, option_id);
        });
      } else if (question.type === 'PhotoQuestion') {
        var image = answerData['content'];
        answerData['content'] = "";
        answerData['image'] = image;
        answerData['photo_updated_at'] = (new Date()).toString();
        answerData['updated_at'] = (new Date()).toString();
        var answer = that.newRecord(answerData);
        answer.save();
      } else {
        answerData['updated_at'] = (new Date()).toString();
        that.newRecord(answerData).save();
      }
    },

    validate : function(answerData, status) {
      var question = Question.findOneById(answerData.question_id);
      var errors = {};
      if (answerData.content) {
        if (question.max_length && (answerData.content.length >= question.max_length))
          errors['max_length'] = "You have exceeded the maximum length for this question";
        if (question.min_value && answerData.content < question.min_value)
          errors['min_value'] = "You have fallen short of the minimum limit";
        if (question.max_value && answerData.content > question.max_value)
          errors['max_value'] = "You have exceeded the maximum limit";
        if (question.type === 'NumericQuestion' && isNaN(answerData.content))
          errors['content'] = "You have to enter only a number";
      } else if (status === "complete" && question.mandatory)
        errors['mandatory'] = "This question is mandatory";
      return errors;
    }
  },
  objectMethods : {

    update : function(content) {
      Ti.API.info("CONTENT IS ");
      Ti.API.info(content);
      Ti.API.info("updating answer");

      var question = Question.findOneById(this.question_id);
      var updated_at = content === this.content ? this.updated_at : (new Date()).toString();

      if (question.type === 'MultiChoiceQuestion') {
        var optionIds = content;
        var that = this;

        existing_optionIDs = _(Choice.findBy('answer_id', this.id)).map(function(choice) {
          return choice.option_id;
        })
        var updated_at = optionIds.sort() === existing_optionIDs.sort() ? this.updated_at : (new Date()).toString();

        _(Choice.findBy('answer_id', this.id)).each(function(choice) {
          choice.destroy();
        });

        _(optionIds).each(function(option_id) {
          Choice.createRecord(that.id, option_id);
        });

        this.fromArray({
          'id' : this.id,
          'content' : '',
          'response_id' : this.response_id,
          'question_id' : this.question_id,
          'web_id' : this.web_id,
          'updated_at' : updated_at
        });
      } else if (question.type === 'PhotoQuestion') {
        var image = content;
        var that = this;
        var updated_at = image === this.image ? this.updated_at : (new Date()).toString();

        this.fromArray({
          'id' : this.id,
          'content' : '',
          'response_id' : this.response_id,
          'question_id' : this.question_id,
          'web_id' : this.web_id,
          'updated_at' : updated_at,
          'image' : image
        });
      } else {
        this.fromArray({
          'id' : this.id,
          'content' : content,
          'response_id' : this.response_id,
          'question_id' : this.question_id,
          'web_id' : this.web_id,
          'updated_at' : updated_at
        });
      }
      this.save();
      Ti.API.info("answer saved with content" + this.content);
    },

    hasChoices : function() {
      return Question.findOneById(this.question_id).type === 'MultiChoiceQuestion';
    },
    isImage : function() {
      return Question.findOneById(this.question_id).type === 'PhotoQuestion';
    },

    optionIDs : function() {
      return _(Choice.findBy('answer_id', this.id)).map(function(choice) {
        return choice.option_id;
      });
    },

    question : function() {
      return Question.findOneById(this.question_id);

    },

    contentForDisplay : function() {
      if (this.isImage()) {
        return '';
      } else if (this.hasChoices()) {
        return _(this.optionIDs()).map(function(optionId) {
          return Option.findOneById(optionId).content;
        }).join(', ');
      } else {
        return this.content;
      }
    },

    destroyChoices : function() {
      return _(Choice.findBy('answer_id', this.id)).each(function(choice) {
        choice.destroy();
      });
    },

    getRemoteImage : function(imageUrl) {
      var self = this;
      var filename = this.image
      if (!filename)
        filename = "image_" + (new Date()).valueOf() + ".jpg";
      var file = Titanium.Filesystem.getFile(filename);
      var client = Titanium.Network.createHTTPClient();
      client.onload = function() {
        file.write(this.responseData);
        self.image = file.nativePath;
        self.save();
        progressBarView.updateValue(1);
      }
      var url = Ti.App.Properties.getString('server_url') + imageUrl
      client.open('GET', url);
      client.send({
        access_token : Ti.App.Properties.getString('access_token')
      });
    },
    uploadImage : function(status, webId) {
      var client = Ti.Network.createHTTPClient();
      var self = this;

      client.onload = function(e) {
        Ti.API.info("Response recieved for image : " + this.responseText);
        Ti.API.info("Succceesssss fully saved IMAGE!" + e);

        var received_response = JSON.parse(this.responseText);

        self.photo_updated_at = received_response['photo_updated_at'];

        if (status == "complete") {
          var imageFile = Titanium.Filesystem.getFile(self.image);
          imageFile.deleteFile();
        } else {
          progressBarView.updateMax(1);
          self.getRemoteImage(received_response.image_url);
        }
        Ti.API.info(this.image);
        progressBarView.updateValue(1);
        progressBarView.keepVisible = false;
      };

      client.onerror = function(e) {
        progressBarView.updateValue(1);
        Ti.API.info("Error saving IMAGE! :( ");
        Ti.API.info(e.error);
        progressBarView.keepVisible = false;
      };

      var image = Titanium.Filesystem.getFile(this.image);
      read_image = image.read();
      var imageUrl = Ti.App.Properties.getString('server_url') + '/api/responses/' + webId + '/image_upload';
      client.open('PUT', imageUrl);
      client.setRequestHeader("enctype", "multipart/form-data;");
      client.send({
        media : read_image,
        answer_id : this.web_id,
        photo_updated_at : this.photo_updated_at,
        access_token : Ti.App.Properties.getString('access_token')
      });
    }
  }
});

Ti.App.joli.models.initialize();
module.exports = Answer;

<commit_msg>Changed the error message in Answer to be more meaningful<commit_after>var _ = require('lib/underscore')._;
var Choice = require('models/choice');
var Question = require('models/question');
var Option = require('models/option');
var progressBarView = require('ui/common/components/ProgressBar');

var Answer = new Ti.App.joli.model({
  table : 'answers',
  columns : {
    id : 'INTEGER PRIMARY KEY',
    content : 'TEXT',
    response_id : 'INTEGER',
    question_id : 'INTEGER',
    web_id : 'INTEGER',
    updated_at : 'TEXT',
    image : 'TEXT',
    photo_updated_at : 'TEXT'
  },

  methods : {
    createRecord : function(answerData, responseID) {
      var _ = require('lib/underscore')._;
      var that = this;
      answerData.response_id = responseID
      var question = Question.findOneById(answerData['question_id']);
      if (question.type === 'MultiChoiceQuestion') {
        var optionIds = answerData['content'];
        answerData['content'] = "";
        answerData['updated_at'] = (new Date()).toString();
        var answer = that.newRecord(answerData);
        answer.save();
        _(optionIds).each(function(option_id) {
          Choice.createRecord(answer.id, option_id);
        });
      } else if (question.type === 'PhotoQuestion') {
        var image = answerData['content'];
        answerData['content'] = "";
        answerData['image'] = image;
        answerData['photo_updated_at'] = (new Date()).toString();
        answerData['updated_at'] = (new Date()).toString();
        var answer = that.newRecord(answerData);
        answer.save();
      } else {
        answerData['updated_at'] = (new Date()).toString();
        that.newRecord(answerData).save();
      }
    },

    validate : function(answerData, status) {
      var question = Question.findOneById(answerData.question_id);
      var errors = {};
      if (answerData.content) {
        if (question.max_length && (answerData.content.length >= question.max_length))
          errors['max_length'] = "You have exceeded the maximum length for this question";
        if (question.min_value && answerData.content < question.min_value)
          errors['min_value'] = "The answer is not in the required range";
        if (question.max_value && answerData.content > question.max_value)
          errors['max_value'] = "The answer is not in the required range";
        if (question.type === 'NumericQuestion' && isNaN(answerData.content))
          errors['content'] = "You have to enter only a number";
      } else if (status === "complete" && question.mandatory)
        errors['mandatory'] = "This question is mandatory";
      return errors;
    }
  },
  objectMethods : {

    update : function(content) {
      Ti.API.info("CONTENT IS ");
      Ti.API.info(content);
      Ti.API.info("updating answer");

      var question = Question.findOneById(this.question_id);
      var updated_at = content === this.content ? this.updated_at : (new Date()).toString();

      if (question.type === 'MultiChoiceQuestion') {
        var optionIds = content;
        var that = this;

        existing_optionIDs = _(Choice.findBy('answer_id', this.id)).map(function(choice) {
          return choice.option_id;
        })
        var updated_at = optionIds.sort() === existing_optionIDs.sort() ? this.updated_at : (new Date()).toString();

        _(Choice.findBy('answer_id', this.id)).each(function(choice) {
          choice.destroy();
        });

        _(optionIds).each(function(option_id) {
          Choice.createRecord(that.id, option_id);
        });

        this.fromArray({
          'id' : this.id,
          'content' : '',
          'response_id' : this.response_id,
          'question_id' : this.question_id,
          'web_id' : this.web_id,
          'updated_at' : updated_at
        });
      } else if (question.type === 'PhotoQuestion') {
        var image = content;
        var that = this;
        var updated_at = image === this.image ? this.updated_at : (new Date()).toString();

        this.fromArray({
          'id' : this.id,
          'content' : '',
          'response_id' : this.response_id,
          'question_id' : this.question_id,
          'web_id' : this.web_id,
          'updated_at' : updated_at,
          'image' : image
        });
      } else {
        this.fromArray({
          'id' : this.id,
          'content' : content,
          'response_id' : this.response_id,
          'question_id' : this.question_id,
          'web_id' : this.web_id,
          'updated_at' : updated_at
        });
      }
      this.save();
      Ti.API.info("answer saved with content" + this.content);
    },

    hasChoices : function() {
      return Question.findOneById(this.question_id).type === 'MultiChoiceQuestion';
    },
    isImage : function() {
      return Question.findOneById(this.question_id).type === 'PhotoQuestion';
    },

    optionIDs : function() {
      return _(Choice.findBy('answer_id', this.id)).map(function(choice) {
        return choice.option_id;
      });
    },

    question : function() {
      return Question.findOneById(this.question_id);

    },

    contentForDisplay : function() {
      if (this.isImage()) {
        return '';
      } else if (this.hasChoices()) {
        return _(this.optionIDs()).map(function(optionId) {
          return Option.findOneById(optionId).content;
        }).join(', ');
      } else {
        return this.content;
      }
    },

    destroyChoices : function() {
      return _(Choice.findBy('answer_id', this.id)).each(function(choice) {
        choice.destroy();
      });
    },

    getRemoteImage : function(imageUrl) {
      var self = this;
      var filename = this.image
      if (!filename)
        filename = "image_" + (new Date()).valueOf() + ".jpg";
      var file = Titanium.Filesystem.getFile(filename);
      var client = Titanium.Network.createHTTPClient();
      client.onload = function() {
        file.write(this.responseData);
        self.image = file.nativePath;
        self.save();
        progressBarView.updateValue(1);
      }
      var url = Ti.App.Properties.getString('server_url') + imageUrl
      client.open('GET', url);
      client.send({
        access_token : Ti.App.Properties.getString('access_token')
      });
    },
    uploadImage : function(status, webId) {
      var client = Ti.Network.createHTTPClient();
      var self = this;

      client.onload = function(e) {
        Ti.API.info("Response recieved for image : " + this.responseText);
        Ti.API.info("Succceesssss fully saved IMAGE!" + e);

        var received_response = JSON.parse(this.responseText);

        self.photo_updated_at = received_response['photo_updated_at'];

        if (status == "complete") {
          var imageFile = Titanium.Filesystem.getFile(self.image);
          imageFile.deleteFile();
        } else {
          progressBarView.updateMax(1);
          self.getRemoteImage(received_response.image_url);
        }
        Ti.API.info(this.image);
        progressBarView.updateValue(1);
        progressBarView.keepVisible = false;
      };

      client.onerror = function(e) {
        progressBarView.updateValue(1);
        Ti.API.info("Error saving IMAGE! :( ");
        Ti.API.info(e.error);
        progressBarView.keepVisible = false;
      };

      var image = Titanium.Filesystem.getFile(this.image);
      read_image = image.read();
      var imageUrl = Ti.App.Properties.getString('server_url') + '/api/responses/' + webId + '/image_upload';
      client.open('PUT', imageUrl);
      client.setRequestHeader("enctype", "multipart/form-data;");
      client.send({
        media : read_image,
        answer_id : this.web_id,
        photo_updated_at : this.photo_updated_at,
        access_token : Ti.App.Properties.getString('access_token')
      });
    }
  }
});

Ti.App.joli.models.initialize();
module.exports = Answer;

<|endoftext|>


<commit_before>/**
 * © 2017 Liferay, Inc. <https://liferay.com>
 *
 * SPDX-License-Identifier: MIT
 */

const DESCRIPTION = 'it() strings should not start with "should"';

module.exports = {
	create(context) {
		return {
			CallExpression(node) {
				if (
					node.callee.type === 'Identifier' &&
					node.callee.name === 'it'
				) {
					const argument = node.arguments && node.arguments[0];
					if (
						argument &&
						argument.type === 'Literal' &&
						typeof argument.value === 'string' &&
						argument.value.match(/^\s*should/)
					) {
						context.report({
							message: DESCRIPTION,
							node: argument,
						});
					}
				}
			},
		};
	},

	meta: {
		docs: {
			category: 'Test style',
			description: DESCRIPTION,
			recommended: false,
			url:
				'https://github.com/liferay/liferay-frontend-guidelines/blob/master/guidelines/general/testing.md#start-it-descriptions-with-a-verb-not-with-should',
		},
		fixable: null, // or "code" or "whitespace"
		schema: [],
		type: 'suggestion',
	},
};
<commit_msg>fix: repair broken link in no-it-should rule<commit_after>/**
 * © 2017 Liferay, Inc. <https://liferay.com>
 *
 * SPDX-License-Identifier: MIT
 */

const DESCRIPTION = 'it() strings should not start with "should"';

module.exports = {
	create(context) {
		return {
			CallExpression(node) {
				if (
					node.callee.type === 'Identifier' &&
					node.callee.name === 'it'
				) {
					const argument = node.arguments && node.arguments[0];
					if (
						argument &&
						argument.type === 'Literal' &&
						typeof argument.value === 'string' &&
						argument.value.match(/^\s*should/)
					) {
						context.report({
							message: DESCRIPTION,
							node: argument,
						});
					}
				}
			},
		};
	},

	meta: {
		docs: {
			category: 'Test style',
			description: DESCRIPTION,
			recommended: false,
			url:
				'https://github.com/liferay/liferay-frontend-guidelines/blob/master/general/testing/anatomy.md',
		},
		fixable: null, // or "code" or "whitespace"
		schema: [],
		type: 'suggestion',
	},
};
<|endoftext|>


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

module("DG.Utilities", {
  setup: function() {
    window.DG = window.DG || {};
  },
  teardown: function() {
  }
});

test("Tests leastSquaresLinearRegression", function() {
  var tResult;

  var tThreeOnALine = [{x: 0, y: 0 },{x: 1, y: 1 },{x: 2, y: 2 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tThreeOnALine, false);
  ok(tResult.slope === 1 && tResult.intercept === 0 && tResult.rSquared === 1 && tResult.sumSquaresResiduals === 0,
  'LSR for three points on a line evaluates correctly');

  var tSinglePoint = [{x: 1, y: 1 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tSinglePoint, false);
  ok(!isFinite(tResult.slope) && !isFinite(tResult.intercept) &&
      !isFinite(tResult.rSquared) && !isFinite(tResult.sumSquaresResiduals),
  'LSR of single point produces NaNs');

  var tVerticalLine = [{x: 1, y: 1 }, {x: 1, y: 2 }, {x: 1, y: 3 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tVerticalLine, false);
  ok(!isFinite(tResult.slope) && !isFinite(tResult.intercept) &&
      !isFinite(tResult.rSquared) && !isFinite(tResult.sumSquaresResiduals),
  'LSR of vertical line produces NaNs');

  var tHorizontalLine = [{x: 0, y: 1 }, {x: 1, y: 2 }, {x: 1, y: 0 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tHorizontalLine, false);
  ok(tResult.slope === 0 && tResult.intercept === 1 && tResult.rSquared === 0 && tResult.sumSquaresResiduals === 2,
  'LSR of three points (0,1), (1,2), (1,0): slope = %@, intercept = %@, r2 = %@, sumSquaresResiduals = %@'.loc(
      tResult.slope, tResult.intercept, tResult.rSquared, tResult.sumSquaresResiduals
  ));

  tHorizontalLine = [{x: 0, y: 1 }, {x: 1.5, y: 2 }, {x: 1.5, y: 0 }, {x: 3, y: 1 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tHorizontalLine, false);
  ok(tResult.slope === 0 && tResult.intercept === 1 && tResult.rSquared === 0 && tResult.sumSquaresResiduals === 2,
  'LSR of four points (0,1), (1.5,2), (1.5,0), (3,1): slope = %@, intercept = %@, r2 = %@, sumSquaresResiduals = %@'.loc(
      tResult.slope, tResult.intercept, tResult.rSquared, tResult.sumSquaresResiduals
  ));

});<commit_msg>Fix failing unit test due to fix of [#134873071]<commit_after>// ==========================================================================
//
//  Author:   wfinzer
//
//  Copyright (c) 2016 by The Concord Consortium, Inc. All rights reserved.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// ==========================================================================
sc_require('utilities/math_utilities');

module("DG.Utilities", {
  setup: function() {
    window.DG = window.DG || {};
  },
  teardown: function() {
  }
});

test("Tests leastSquaresLinearRegression", function() {
  var tResult;

  var tThreeOnALine = [{x: 0, y: 0 },{x: 1, y: 1 },{x: 2, y: 2 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tThreeOnALine, false);
  ok(tResult.slope === 1 && tResult.intercept === 0 && tResult.rSquared === 1 && tResult.sumSquaresResiduals === 0,
  'LSR for three points on a line evaluates correctly');

  var tSinglePoint = [{x: 1, y: 1 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tSinglePoint, false);
  ok((tResult.slope === null) && (tResult.intercept === null) &&
      (tResult.rSquared === null) && (tResult.sumSquaresResiduals === null),
  'LSR of single point produces Nulls');

  var tVerticalLine = [{x: 1, y: 1 }, {x: 1, y: 2 }, {x: 1, y: 3 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tVerticalLine, false);
  ok(!isFinite(tResult.slope) && !isFinite(tResult.intercept) &&
      !isFinite(tResult.rSquared) && !isFinite(tResult.sumSquaresResiduals),
  'LSR of vertical line produces NaNs');

  var tHorizontalLine = [{x: 0, y: 1 }, {x: 1, y: 2 }, {x: 1, y: 0 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tHorizontalLine, false);
  ok(tResult.slope === 0 && tResult.intercept === 1 && tResult.rSquared === 0 && tResult.sumSquaresResiduals === 2,
  'LSR of three points (0,1), (1,2), (1,0): slope = %@, intercept = %@, r2 = %@, sumSquaresResiduals = %@'.loc(
      tResult.slope, tResult.intercept, tResult.rSquared, tResult.sumSquaresResiduals
  ));

  tHorizontalLine = [{x: 0, y: 1 }, {x: 1.5, y: 2 }, {x: 1.5, y: 0 }, {x: 3, y: 1 }];
  tResult = DG.MathUtilities.leastSquaresLinearRegression( tHorizontalLine, false);
  ok(tResult.slope === 0 && tResult.intercept === 1 && tResult.rSquared === 0 && tResult.sumSquaresResiduals === 2,
  'LSR of four points (0,1), (1.5,2), (1.5,0), (3,1): slope = %@, intercept = %@, r2 = %@, sumSquaresResiduals = %@'.loc(
      tResult.slope, tResult.intercept, tResult.rSquared, tResult.sumSquaresResiduals
  ));

});<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015-2016 Actor LLC. <https://actor.im>
 */

import React, { Component, PropTypes } from 'react';
import { Container } from 'flux/utils';
import classnames from 'classnames';
import ActorClient from '../../utils/ActorClient';
import { escapeWithEmoji } from '../../utils/EmojiUtils'
import confirm from '../../utils/confirm'
import SharedContainer from '../../utils/SharedContainer';
import { FormattedMessage } from 'react-intl';

import MyProfileActions from '../../actions/MyProfileActionCreators';
import CreateGroupActionCreators from '../../actions/CreateGroupActionCreators';
import LoginActionCreators from '../../actions/LoginActionCreators';
import HelpActionCreators from '../../actions/HelpActionCreators';
import AddContactActionCreators from '../../actions/AddContactActionCreators';
import PreferencesActionCreators from '../../actions/PreferencesActionCreators';

import MyProfileStore from '../../stores/MyProfileStore';
import CreateGroupStore from '../../stores/CreateGroupStore';
import AddContactStore from '../../stores/AddContactStore';
import PreferencesStore from '../../stores/PreferencesStore';

import SvgIcon from '../common/SvgIcon.react';
import AvatarItem from '../common/AvatarItem.react';
import CreateGroupModal from '../modals/CreateGroup';
import MyProfileModal from '../modals/MyProfile.react';
import AddContactModal from '../modals/AddContact.react';
import PreferencesModal from '../modals/Preferences.react';

class HeaderSection extends Component {
  constructor(props) {
    super(props);

    this.openHelp = this.openHelp.bind(this);
    this.openTwitter = this.openTwitter.bind(this);
    this.openFacebook = this.openFacebook.bind(this);
    this.openHomePage = this.openHomePage.bind(this);
  }

  static getStores() {
    return [MyProfileStore, CreateGroupStore, AddContactStore, PreferencesStore];
  }

  static calculateState() {
    return {
      profile: MyProfileStore.getProfile(),
      isMyProfileOpen: MyProfileStore.isModalOpen(),
      isAddContactsOpen: AddContactStore.isOpen(),
      isCreateGroupOpen: CreateGroupStore.isModalOpen(),
      isPreferencesOpen: PreferencesStore.isOpen()
    }
  }

  static contextTypes = {
    intl: PropTypes.object
  };

  componentWillMount() {
    this.setState({isOpened: false});
  }

  toggleHeaderMenu = () => {
    const { isOpened } = this.state;

    if (!isOpened) {
      this.setState({isOpened: true});
      document.addEventListener('click', this.closeHeaderMenu, false);
    } else {
      this.closeHeaderMenu();
    }
  };

  closeHeaderMenu = () => {
    this.setState({isOpened: false});
    document.removeEventListener('click', this.closeHeaderMenu, false);
  };

  openMyProfile = () => MyProfileActions.show();
  openCreateGroup = () => CreateGroupActionCreators.open();
  openAddContactModal = () => AddContactActionCreators.open();
  onSettingsOpen = () => PreferencesActionCreators.show();

  openHelp(event) {
    HelpActionCreators.open()
  }

  openTwitter(event) {
    const { twitter } = SharedContainer.get();

    event.preventDefault();
    if (ActorClient.isElectron()) {
      ActorClient.handleLinkClick(event);
    } else {
      window.open(`https://twitter.com/${twitter}`, '_blank');
    }
  }

  openFacebook(event) {
    const { facebook } = SharedContainer.get();

    event.preventDefault();
    if (ActorClient.isElectron()) {
      ActorClient.handleLinkClick(event);
    } else {
      window.open(`https://facebook.com/${facebook}`, '_blank');
    }
  }

  openHomePage(event) {
    const { homePage } = SharedContainer.get();

    event.preventDefault();
    if (ActorClient.isElectron()) {
      ActorClient.handleLinkClick(event);
    } else {
      window.open(homePage, '_blank');
    }
  }

  setLogout = () => {
    const { intl } = this.context;
    confirm(intl.messages['modal.confirm.logout']).then(
      () => LoginActionCreators.setLoggedOut(),
      () => {}
    );
  };

  renderTwitterLink() {
    const { twitter } = SharedContainer.get();
    if (!twitter) return null;

    return (

        <a href={`https://twitter.com/${twitter}`} onClick={this.openTwitter}>
          <SvgIcon className="icon icon--dropdown sidebar__header__twitter" glyph="twitter" />
          <FormattedMessage id="menu.twitter"/>

    );
  }

  renderFacebookLink() {
    const { facebook } = SharedContainer.get();
    if (!facebook) return null;

    return (

        <a href={`https://facebook.com/${facebook}`} onClick={this.openFacebook}>
          <SvgIcon className="icon icon--dropdown sidebar__header__facebook" glyph="facebook" />
          <FormattedMessage id="menu.facebook"/>

    );
  }

  renderHomeLink() {
    const { homePage } = SharedContainer.get();
    if (!homePage) return null;

    return (

          public
          <FormattedMessage id="menu.homePage"/>

    );
  }

  renderHelpLink() {
    const { helpPhone } = SharedContainer.get();
    if (!helpPhone) return null;

    if (/@/.test(helpPhone)) {
      return (

          <a href={`mailto:${helpPhone}`}>
            help
            <FormattedMessage id="menu.helpAndFeedback"/>

      );
    } else {
      return (

          help
          <FormattedMessage id="menu.helpAndFeedback"/>

      );
    }
  }

  render() {
    const { profile, isOpened, isMyProfileOpen, isCreateGroupOpen, isAddContactsOpen, isPreferencesOpen } = this.state;

    if (!profile) return null;

    const headerClass = classnames('sidebar__header', 'sidebar__header--clickable', {
      'sidebar__header--opened': isOpened
    });
    const menuClass = classnames('dropdown', {
      'dropdown--opened': isOpened
    });

    return (

          <AvatarItem image={profile.avatar}
                      placeholder={profile.placeholder}
                      size="tiny"
                      title={profile.name} />

              arrow_drop_down

                edit
                <FormattedMessage id="menu.editProfile"/>

                person_add
                <FormattedMessage id="menu.addToContacts"/>

                group_add
                <FormattedMessage id="menu.createGroup"/>

                settings
                <FormattedMessage id="menu.preferences"/>

              {this.renderHelpLink()}
              {this.renderTwitterLink()}
              {this.renderFacebookLink()}
              {this.renderHomeLink()}

                <FormattedMessage id="menu.signOut"/>

        {/* Modals */}
        {/* TODO: Move all modals to other place */}
        {isMyProfileOpen ? <MyProfileModal/> : null}
        {isCreateGroupOpen ? <CreateGroupModal/> : null}
        {isAddContactsOpen ? <AddContactModal/> : null}
        {isPreferencesOpen ? <PreferencesModal/> : null}

    );

  }
}

export default Container.create(HeaderSection);
<commit_msg>fix(web): remove unused variable<commit_after>/*
 * Copyright (C) 2015-2016 Actor LLC. <https://actor.im>
 */

import React, { Component, PropTypes } from 'react';
import { Container } from 'flux/utils';
import classnames from 'classnames';
import ActorClient from '../../utils/ActorClient';
import { escapeWithEmoji } from '../../utils/EmojiUtils'
import confirm from '../../utils/confirm'
import SharedContainer from '../../utils/SharedContainer';
import { FormattedMessage } from 'react-intl';

import MyProfileActions from '../../actions/MyProfileActionCreators';
import CreateGroupActionCreators from '../../actions/CreateGroupActionCreators';
import LoginActionCreators from '../../actions/LoginActionCreators';
import HelpActionCreators from '../../actions/HelpActionCreators';
import AddContactActionCreators from '../../actions/AddContactActionCreators';
import PreferencesActionCreators from '../../actions/PreferencesActionCreators';

import MyProfileStore from '../../stores/MyProfileStore';
import CreateGroupStore from '../../stores/CreateGroupStore';
import AddContactStore from '../../stores/AddContactStore';
import PreferencesStore from '../../stores/PreferencesStore';

import SvgIcon from '../common/SvgIcon.react';
import AvatarItem from '../common/AvatarItem.react';
import CreateGroupModal from '../modals/CreateGroup';
import MyProfileModal from '../modals/MyProfile.react';
import AddContactModal from '../modals/AddContact.react';
import PreferencesModal from '../modals/Preferences.react';

class HeaderSection extends Component {
  constructor(props) {
    super(props);

    this.openHelp = this.openHelp.bind(this);
    this.openTwitter = this.openTwitter.bind(this);
    this.openFacebook = this.openFacebook.bind(this);
    this.openHomePage = this.openHomePage.bind(this);
  }

  static getStores() {
    return [MyProfileStore, CreateGroupStore, AddContactStore, PreferencesStore];
  }

  static calculateState() {
    return {
      profile: MyProfileStore.getProfile(),
      isMyProfileOpen: MyProfileStore.isModalOpen(),
      isAddContactsOpen: AddContactStore.isOpen(),
      isCreateGroupOpen: CreateGroupStore.isModalOpen(),
      isPreferencesOpen: PreferencesStore.isOpen()
    }
  }

  static contextTypes = {
    intl: PropTypes.object
  };

  componentWillMount() {
    this.setState({isOpened: false});
  }

  toggleHeaderMenu = () => {
    const { isOpened } = this.state;

    if (!isOpened) {
      this.setState({isOpened: true});
      document.addEventListener('click', this.closeHeaderMenu, false);
    } else {
      this.closeHeaderMenu();
    }
  };

  closeHeaderMenu = () => {
    this.setState({isOpened: false});
    document.removeEventListener('click', this.closeHeaderMenu, false);
  };

  openMyProfile = () => MyProfileActions.show();
  openCreateGroup = () => CreateGroupActionCreators.open();
  openAddContactModal = () => AddContactActionCreators.open();
  onSettingsOpen = () => PreferencesActionCreators.show();

  openHelp() {
    HelpActionCreators.open()
  }

  openTwitter(event) {
    const { twitter } = SharedContainer.get();

    event.preventDefault();
    if (ActorClient.isElectron()) {
      ActorClient.handleLinkClick(event);
    } else {
      window.open(`https://twitter.com/${twitter}`, '_blank');
    }
  }

  openFacebook(event) {
    const { facebook } = SharedContainer.get();

    event.preventDefault();
    if (ActorClient.isElectron()) {
      ActorClient.handleLinkClick(event);
    } else {
      window.open(`https://facebook.com/${facebook}`, '_blank');
    }
  }

  openHomePage(event) {
    const { homePage } = SharedContainer.get();

    event.preventDefault();
    if (ActorClient.isElectron()) {
      ActorClient.handleLinkClick(event);
    } else {
      window.open(homePage, '_blank');
    }
  }

  setLogout = () => {
    const { intl } = this.context;
    confirm(intl.messages['modal.confirm.logout']).then(
      () => LoginActionCreators.setLoggedOut(),
      () => {}
    );
  };

  renderTwitterLink() {
    const { twitter } = SharedContainer.get();
    if (!twitter) return null;

    return (

        <a href={`https://twitter.com/${twitter}`} onClick={this.openTwitter}>
          <SvgIcon className="icon icon--dropdown sidebar__header__twitter" glyph="twitter" />
          <FormattedMessage id="menu.twitter"/>

    );
  }

  renderFacebookLink() {
    const { facebook } = SharedContainer.get();
    if (!facebook) return null;

    return (

        <a href={`https://facebook.com/${facebook}`} onClick={this.openFacebook}>
          <SvgIcon className="icon icon--dropdown sidebar__header__facebook" glyph="facebook" />
          <FormattedMessage id="menu.facebook"/>

    );
  }

  renderHomeLink() {
    const { homePage } = SharedContainer.get();
    if (!homePage) return null;

    return (

          public
          <FormattedMessage id="menu.homePage"/>

    );
  }

  renderHelpLink() {
    const { helpPhone } = SharedContainer.get();
    if (!helpPhone) return null;

    if (/@/.test(helpPhone)) {
      return (

          <a href={`mailto:${helpPhone}`}>
            help
            <FormattedMessage id="menu.helpAndFeedback"/>

      );
    } else {
      return (

          help
          <FormattedMessage id="menu.helpAndFeedback"/>

      );
    }
  }

  render() {
    const { profile, isOpened, isMyProfileOpen, isCreateGroupOpen, isAddContactsOpen, isPreferencesOpen } = this.state;

    if (!profile) return null;

    const headerClass = classnames('sidebar__header', 'sidebar__header--clickable', {
      'sidebar__header--opened': isOpened
    });
    const menuClass = classnames('dropdown', {
      'dropdown--opened': isOpened
    });

    return (

          <AvatarItem image={profile.avatar}
                      placeholder={profile.placeholder}
                      size="tiny"
                      title={profile.name} />

              arrow_drop_down

                edit
                <FormattedMessage id="menu.editProfile"/>

                person_add
                <FormattedMessage id="menu.addToContacts"/>

                group_add
                <FormattedMessage id="menu.createGroup"/>

                settings
                <FormattedMessage id="menu.preferences"/>

              {this.renderHelpLink()}
              {this.renderTwitterLink()}
              {this.renderFacebookLink()}
              {this.renderHomeLink()}

                <FormattedMessage id="menu.signOut"/>

        {/* Modals */}
        {/* TODO: Move all modals to other place */}
        {isMyProfileOpen ? <MyProfileModal/> : null}
        {isCreateGroupOpen ? <CreateGroupModal/> : null}
        {isAddContactsOpen ? <AddContactModal/> : null}
        {isPreferencesOpen ? <PreferencesModal/> : null}

    );

  }
}

export default Container.create(HeaderSection);
<|endoftext|>


<commit_before>/**
 * Show confirm popup, when user close tab with non-synchronized actions.
 *
 * @param {Syncable|Client} client Observed Client instance
 *                                 or object with `sync` property.
 * @param {String} [warning] The text of the warning.
 *
 * @return {Function} Unbind confirm listener.
 *
 * @example
 * import confirm from 'logux-status/confirm'
 * confirm(client, 'Post does not saved to server. Are you sure to leave?')
 */
function confirm (client, warning) {
  var sync = client.sync

  warning = warning || 'Some data was not saved to server. ' +
                       'Are you sure to leave?'

  function listen (e) {
    if (typeof e === 'undefined') e = window.event
    if (e) e.returnValue = warning
    return warning
  }

  return sync.on('state', function () {
    if (sync.state === 'wait' || sync.state === 'sending') {
      window.addEventListener('beforeunload', listen, false)
    } else {
      window.removeEventListener('beforeunload', listen, false)
    }
  })
}

module.exports = confirm
<commit_msg>Remove default value for addEventListener<commit_after>/**
 * Show confirm popup, when user close tab with non-synchronized actions.
 *
 * @param {Syncable|Client} client Observed Client instance
 *                                 or object with `sync` property.
 * @param {String} [warning] The text of the warning.
 *
 * @return {Function} Unbind confirm listener.
 *
 * @example
 * import confirm from 'logux-status/confirm'
 * confirm(client, 'Post does not saved to server. Are you sure to leave?')
 */
function confirm (client, warning) {
  var sync = client.sync

  warning = warning || 'Some data was not saved to server. ' +
                       'Are you sure to leave?'

  function listen (e) {
    if (typeof e === 'undefined') e = window.event
    if (e) e.returnValue = warning
    return warning
  }

  return sync.on('state', function () {
    if (sync.state === 'wait' || sync.state === 'sending') {
      window.addEventListener('beforeunload', listen)
    } else {
      window.removeEventListener('beforeunload', listen)
    }
  })
}

module.exports = confirm
<|endoftext|>


<commit_before>import traverseSchema from './traverseSchema'
import object from './validation/types/object'
import reference from './validation/types/reference'
import array from './validation/types/array'
import slug from './validation/types/slug'
import file from './validation/types/file'
import image from './validation/types/image'
import block from './validation/types/block'
import common from './validation/types/common'
import rootType from './validation/types/rootType'

const typeVisitors = {
  array,
  object,
  slug,
  file,
  image,
  block,
  document: object,
  reference: reference
}

const NOOP_VISITOR = schemaDef => ({
  ...schemaDef,
  _problems: []
})

function combine(...visitors) {
  return (schemaType, visitorContext) => {
    return visitors.reduce(
      (result, visitor) => {
        const res = visitor(result, visitorContext)
        return {
          ...res,
          _problems: result._problems.concat(res._problems)
        }
      },
      {...schemaType, _problems: []}
    )
  }
}

// Future improvements:
// - Provide an easy way to determine if schema has problems of a certain class (e.g. errors)
// Clean up the api
export default function validateSchema(schemaTypes) {
  return traverseSchema(schemaTypes, (schemaDef, visitorContext) => {
    const typeVisitor = (schemaDef.type && typeVisitors[schemaDef.type]) || NOOP_VISITOR
    if (visitorContext.isRoot) {
      return combine(rootType, common, typeVisitor)(schemaDef, visitorContext)
    }
    return combine(common, typeVisitor)(schemaDef, visitorContext)
  })
}
<commit_msg>[schema] Allow problems from external schema creators to flow through (#1140)<commit_after>import traverseSchema from './traverseSchema'
import object from './validation/types/object'
import reference from './validation/types/reference'
import array from './validation/types/array'
import slug from './validation/types/slug'
import file from './validation/types/file'
import image from './validation/types/image'
import block from './validation/types/block'
import common from './validation/types/common'
import rootType from './validation/types/rootType'

const typeVisitors = {
  array,
  object,
  slug,
  file,
  image,
  block,
  document: object,
  reference: reference
}

const NOOP_VISITOR = schemaDef => ({
  ...schemaDef,
  _problems: []
})

function combine(...visitors) {
  return (schemaType, visitorContext) => {
    return visitors.reduce(
      (result, visitor) => {
        const res = visitor(result, visitorContext)
        return {
          ...res,
          _problems: result._problems.concat(res._problems)
        }
      },
      {_problems: [], ...schemaType}
    )
  }
}

// Future improvements:
// - Provide an easy way to determine if schema has problems of a certain class (e.g. errors)
// Clean up the api
export default function validateSchema(schemaTypes) {
  return traverseSchema(schemaTypes, (schemaDef, visitorContext) => {
    const typeVisitor = (schemaDef.type && typeVisitors[schemaDef.type]) || NOOP_VISITOR
    if (visitorContext.isRoot) {
      return combine(rootType, common, typeVisitor)(schemaDef, visitorContext)
    }
    return combine(common, typeVisitor)(schemaDef, visitorContext)
  })
}
<|endoftext|>


<commit_before>module.exports = {
  singleQuote: true,
  trailingComma: 'es5',
  arrowParens: 'always',
};
<commit_msg>chore: update prettier configuration<commit_after>module.exports = { singleQuote: true };
<|endoftext|>


<commit_before>import spawnAsync from '@exponent/spawn-async';
import git from 'git-promise';

import CI, { Rocker, Kubernetes as K8S, Log, Github } from 'ci';

export default {
  config: {
    name: '📚 Docs',
    shortname: 'docs',
    description: 'Docs Build/Deploy',
    branches: 'master',
    allowPRs: true,
  },
  steps: (branch, tag, pr) => {
    if (tag) {
      // all we need to do when there's a tag is deploy
      return [deploy(branch, tag, pr), updateSearchIndex(branch, tag, pr)];
    }
    const steps = [build(branch, tag, pr), CI.waitStep(), deploy(branch, tag, pr)];
    if (!pr) {
      steps.push(CI.blockStep(':shipit: Deploy to Production?'), tagRelease);
    }
    return steps;
  },
};

const build = (branch, tag, pr) => ({
  name: `:hammer: Build`,
  agents: {
    queue: 'builder',
  },
  async command() {
    let environment;
    if (tag && !pr) {
      environment = 'production';
    } else if (pr) {
      environment = `docs-pr-${pr}`;
    } else {
      environment = 'staging';
    }

    const imageName = `gcr.io/exponentjs/exponent-docs-v2-${environment}`;
    const imageTag = `${process.env.BUILDKITE_COMMIT}`;

    Log.collapsed(':hammer: Building Docs...');

    await Rocker.build({
      rockerfile: './deploy/docker/deploy.Rockerfile',
      context: '.',
      vars: {
        ImageName: imageName,
        ImageTag: imageTag,
        DocsVersion: `v${require('./package.json').version}`,
      },
      options: {
        pull: true,
        push: true,
      },
    });
  },
});

const deploy = (branch, tag, pr) => ({
  name: `:rocket: Deploy to ${tag && !pr ? 'Production' : pr ? 'Dev' : 'Staging'}`,
  concurrency: 1,
  concurrency_group: `docs/${tag && !pr ? 'prod' : pr ? `pr-${pr}` : 'staging'}/deploy`,
  async command() {
    if (!pr && branch !== 'master') {
      return;
    }
    const isProduction = tag && !pr;

    let environment;
    if (tag && !pr) {
      environment = 'production';
    } else if (pr) {
      environment = `docs-pr-${pr}`;
    } else {
      environment = 'staging';
    }

    const imageName = `gcr.io/exponentjs/exponent-docs-v2-${environment}`;
    const imageTag = `${process.env.BUILDKITE_COMMIT}`;

    Log.collapsed(':gcloud: Deploy to K8s...');

    let ingressHostname;
    if (isProduction) {
      ingressHostname = 'docs.getexponent.com';
    } else if (pr) {
      ingressHostname = `${environment}.pr.exp.host`;
    } else {
      ingressHostname = 'staging.docs.getexponent.com';
    }

    Github.performDeployment(
      {
        projectName: 'docs',
        environment,
        deploymentUrl: `https://${ingressHostname}`,
        deploymentType: 'k8s',
        prNumber: pr,
      },
      // deployment function
      async () => {
        await K8S.deployHelmChart({
          chartPath: './deploy/charts/docs',
          namespace: environment,
          releaseName: makeVersionName(),
          values: {
            image: {
              repository: imageName,
              tag: imageTag,
            },
            replicaCount: environment === 'production' ? 2 : 1, // PRS // Staging
            ingress: [
              {
                host: ingressHostname,
              },
            ],
          },
        });
      },
      // on error
      () => {
        process.exit(1);
      }
    );

    // VAULT_ADDR: process.env.VAULT_ADDR,
    // VAULT_TOKEN: process.env.VAULT_TOKEN,
  },
});

const updateSearchIndex = (branch, tag) => ({
  name: `:feelsgood: Update Search Index`,
  async command() {
    if (branch !== 'master' && !tag) {
      return;
    }

    Log.collapsed(':open_mouth: Updating search index...');

    await spawnAsync('node', ['scripts/update-search-index.js'], {
      stdio: 'inherit',
    });
  },
});

const tagRelease = {
  name: ':git: Tag Release',
  async command() {
    Log.collapsed(':git: Tagging Release...'); // Build tag name
    const tag = `docs/release-${await makeVersionName()}`;
    await git(`tag ${tag}`);
    Log.collapsed(':github: Pushing Release...');
    await git(`push origin ${tag}`); // upload more steps
    global.currentPipeline.upload(global.currentPipeline.steps(tag, tag, null));
  },
};

function pad(n) {
  return n < 10 ? `0${n}` : `${n}`;
}

async function makeVersionName() {
  const hash = (await git(`rev-parse --short=12 ${process.env.BUILDKITE_COMMIT}`)).trim();
  const today = new Date();
  return `${today.getFullYear()}-${pad(today.getMonth() + 1)}-${pad(today.getDate())}-${hash}`;
}
<commit_msg>[ci] Properly report errors during deployment<commit_after>import spawnAsync from '@exponent/spawn-async';
import git from 'git-promise';

import CI, { Rocker, Kubernetes as K8S, Log, Github } from 'ci';

export default {
  config: {
    name: '📚 Docs',
    shortname: 'docs',
    description: 'Docs Build/Deploy',
    branches: 'master',
    allowPRs: true,
  },
  steps: (branch, tag, pr) => {
    if (tag) {
      // all we need to do when there's a tag is deploy
      return [deploy(branch, tag, pr), updateSearchIndex(branch, tag, pr)];
    }
    const steps = [build(branch, tag, pr), CI.waitStep(), deploy(branch, tag, pr)];
    if (!pr) {
      steps.push(CI.blockStep(':shipit: Deploy to Production?'), tagRelease);
    }
    return steps;
  },
};

const build = (branch, tag, pr) => ({
  name: `:hammer: Build`,
  agents: {
    queue: 'builder',
  },
  async command() {
    let environment;
    if (tag && !pr) {
      environment = 'production';
    } else if (pr) {
      environment = `docs-pr-${pr}`;
    } else {
      environment = 'staging';
    }

    const imageName = `gcr.io/exponentjs/exponent-docs-v2-${environment}`;
    const imageTag = `${process.env.BUILDKITE_COMMIT}`;

    Log.collapsed(':hammer: Building Docs...');

    await Rocker.build({
      rockerfile: './deploy/docker/deploy.Rockerfile',
      context: '.',
      vars: {
        ImageName: imageName,
        ImageTag: imageTag,
        DocsVersion: `v${require('./package.json').version}`,
      },
      options: {
        pull: true,
        push: true,
      },
    });
  },
});

const deploy = (branch, tag, pr) => ({
  name: `:rocket: Deploy to ${tag && !pr ? 'Production' : pr ? 'Dev' : 'Staging'}`,
  concurrency: 1,
  concurrency_group: `docs/${tag && !pr ? 'prod' : pr ? `pr-${pr}` : 'staging'}/deploy`,
  async command() {
    if (!pr && branch !== 'master') {
      return;
    }
    const isProduction = tag && !pr;

    let environment;
    if (tag && !pr) {
      environment = 'production';
    } else if (pr) {
      environment = `docs-pr-${pr}`;
    } else {
      environment = 'staging';
    }

    const imageName = `gcr.io/exponentjs/exponent-docs-v2-${environment}`;
    const imageTag = `${process.env.BUILDKITE_COMMIT}`;

    Log.collapsed(':gcloud: Deploy to K8s...');

    let ingressHostname;
    if (isProduction) {
      ingressHostname = 'docs.getexponent.com';
    } else if (pr) {
      ingressHostname = `${environment}.pr.exp.host`;
    } else {
      ingressHostname = 'staging.docs.getexponent.com';
    }

    Github.performDeployment(
      {
        projectName: 'docs',
        environment,
        deploymentUrl: `https://${ingressHostname}`,
        deploymentType: 'k8s',
        prNumber: pr,
      },
      // deployment function
      async () => {
        await K8S.deployHelmChart({
          chartPath: './deploy/charts/docs',
          namespace: environment,
          releaseName: makeVersionName(),
          values: {
            image: {
              repository: imageName,
              tag: imageTag,
            },
            replicaCount: environment === 'production' ? 2 : 1, // PRS // Staging
            ingress: [
              {
                host: ingressHostname,
              },
            ],
          },
        });
      },
      // on error
      e => {
        console.error('Error during deployment: ', e);
        process.exit(1);
      }
    );

    // VAULT_ADDR: process.env.VAULT_ADDR,
    // VAULT_TOKEN: process.env.VAULT_TOKEN,
  },
});

const updateSearchIndex = (branch, tag) => ({
  name: `:feelsgood: Update Search Index`,
  async command() {
    if (branch !== 'master' && !tag) {
      return;
    }

    Log.collapsed(':open_mouth: Updating search index...');

    await spawnAsync('node', ['scripts/update-search-index.js'], {
      stdio: 'inherit',
    });
  },
});

const tagRelease = {
  name: ':git: Tag Release',
  async command() {
    Log.collapsed(':git: Tagging Release...'); // Build tag name
    const tag = `docs/release-${await makeVersionName()}`;
    await git(`tag ${tag}`);
    Log.collapsed(':github: Pushing Release...');
    await git(`push origin ${tag}`); // upload more steps
    global.currentPipeline.upload(global.currentPipeline.steps(tag, tag, null));
  },
};

function pad(n) {
  return n < 10 ? `0${n}` : `${n}`;
}

async function makeVersionName() {
  const hash = (await git(`rev-parse --short=12 ${process.env.BUILDKITE_COMMIT}`)).trim();
  const today = new Date();
  return `${today.getFullYear()}-${pad(today.getMonth() + 1)}-${pad(today.getDate())}-${hash}`;
}
<|endoftext|>


<commit_before>(function () {
    var _console = window.console;
    var _methods = {
        log: window.console.log,
        error: window.console.error,
        info: window.console.info,
        debug: window.console.debug,
        clear: window.console.clear,
    };
    var $body = document.body;

    function append (message) {
        $body.append(message);
    }

    function clear () {
        $body.innerHtml = "";
        _methods.clear.call(_console);
    };

    function message (text, color, $message) {
        $message = document.createElement('span');
        $message.style.color = color || '#000000';
        $message.innerText = text;
        return $message;
    }

    function write (key, color) {
        return function () {
            Function.prototype.apply.call(_methods[key], _console, arguments);
            append(message(Array.prototype.slice.call(arguments).join(' '), color));
        };
    }

    window.console.clear = clear;
    window.console.error = write('error', '#ff0000');
    window.console.log = write('log');
    window.console.info = write('info');
    window.console.debug = write('debug');

    function errorHandler (e) {
        e.preventDefault();
        console.error(e.message);
        return true;
    }

    if (window.attachEvent) {
        window.attachEvent('onerror', errorHandler);
    }
    else {
        window.addEventListener('error', errorHandler, true);
    }
}) ();
<commit_msg>Fix to append when document body is ready<commit_after>(function () {
    var _console = window.console;
    var _methods = {
        log: window.console.log,
        error: window.console.error,
        info: window.console.info,
        debug: window.console.debug,
        clear: window.console.clear,
    };

    function append (message) {
        if (document.body) {
            document.body.append(message);
        }
        else {
            setTimeout(append, 100, message);
        }
    }

    function clear () {
        if (document.body) {
            document.body.innerHtml = null;
        }
        _methods.clear.call(_console);
    };

    function message (text, color, $message) {
        $message = document.createElement('span');
        $message.style.color = color || '#000000';
        $message.innerText = text;
        return $message;
    }

    function write (key, color) {
        return function () {
            Function.prototype.apply.call(_methods[key], _console, arguments);
            append(message(Array.prototype.slice.call(arguments).join(' '), color));
        };
    }

    window.console.clear = clear;
    window.console.error = write('error', '#ff0000');
    window.console.log = write('log');
    window.console.info = write('info');
    window.console.debug = write('debug');

    function errorHandler (e) {
        e.preventDefault();
        console.error(e.message);
        return true;
    }

    if (window.attachEvent) {
        window.attachEvent('onerror', errorHandler);
    }
    else {
        window.addEventListener('error', errorHandler, true);
    }
}) ();
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('options', function() {

  var OptionsPage = options.OptionsPage;

  //////////////////////////////////////////////////////////////////////////////
  // ContentSettings class:

  /**
   * Encapsulated handling of content settings page.
   * @constructor
   */
  function ContentSettings() {
    this.activeNavTab = null;
    OptionsPage.call(this, 'content', templateData.contentSettingsPageTabTitle,
                     'content-settings-page');
  }

  cr.addSingletonGetter(ContentSettings);

  ContentSettings.prototype = {
    __proto__: OptionsPage.prototype,

    initializePage: function() {
      OptionsPage.prototype.initializePage.call(this);

      chrome.send('getContentFilterSettings');

      var exceptionsButtons =
          this.pageDiv.querySelectorAll('.exceptions-list-button');
      for (var i = 0; i < exceptionsButtons.length; i++) {
        exceptionsButtons[i].onclick = function(event) {
          var page = ContentSettingsExceptionsArea.getInstance();
          page.showList(
              event.target.getAttribute('contentType'));
          OptionsPage.navigateToPage('contentExceptions');
          // Add on the proper hash for the content type, and store that in the
          // history so back/forward and tab restore works.
          var hash = event.target.getAttribute('contentType');
          window.history.replaceState({pageName: page.name}, page.title,
                                      '/' + page.name + "#" + hash);
        };
      }

      var manageHandlersButton = $('manage-handlers-button');
      if (manageHandlersButton) {
        manageHandlersButton.onclick = function(event) {
          OptionsPage.navigateToPage('handlers');
        };
      }

      var manageIntentsButton = $('manage-intents-button');
      if (manageIntentsButton) {
        manageIntentsButton.onclick = function(event) {
          OptionsPage.navigateToPage('intents');
        };
      }

      // Cookies filter page ---------------------------------------------------
      $('show-cookies-button').onclick = function(event) {
        chrome.send('coreOptionsUserMetricsAction', ['Options_ShowCookies']);
        OptionsPage.navigateToPage('cookies');
      };

      if (!templateData.enable_click_to_play)
        $('click_to_play').hidden = true;

      if (!templateData.enable_web_intents && $('intent-section'))
        $('intent-section').hidden = true;
    },
  };

  ContentSettings.updateHandlersEnabledRadios = function(enabled) {
    var selector = '#content-settings-page input[type=radio][value=' +
        (enabled ? 'allow' : 'block') + '].handler-radio';
    document.querySelector(selector).checked = true;
  };

  /**
   * Sets the values for all the content settings radios.
   * @param {Object} dict A mapping from radio groups to the checked value for
   *     that group.
   */
  ContentSettings.setContentFilterSettingsValue = function(dict) {
    for (var group in dict) {
      var radio = document.querySelector('input[type=radio][name=' + group +
                                         '][value=' + dict[group]['value'] +
                                         ']');
      if (radio)
        radio.checked = true;
      var radios = document.querySelectorAll('input[type=radio][name=' +
                                             group + ']');
      for (var i = 0, len = radios.length; i < len; i++) {
        var managed = dict[group]['managed'];
        radios[i].disabled = managed;
        radios[i].controlledBy = managed ? 'policy': null;
      }
    }
    OptionsPage.updateManagedBannerVisibility();
  };

  /**
   * Initializes an exceptions list.
   * @param {string} type The content type that we are setting exceptions for.
   * @param {Array} list An array of pairs, where the first element of each pair
   *     is the filter string, and the second is the setting (allow/block).
   */
  ContentSettings.setExceptions = function(type, list) {
    var exceptionsList =
        document.querySelector('div[contentType=' + type + ']' +
                               ' list[mode=normal]');
    exceptionsList.setExceptions(list);
  };

  ContentSettings.setHandlers = function(list) {
    $('handlers-list').setHandlers(list);
  };

  ContentSettings.setIgnoredHandlers = function(list) {
    $('ignored-handlers-list').setHandlers(list);
  };

  ContentSettings.setOTRExceptions = function(type, list) {
    var exceptionsList =
        document.querySelector('div[contentType=' + type + ']' +
                               ' list[mode=otr]');

    exceptionsList.parentNode.hidden = false;
    exceptionsList.setExceptions(list);
  };

  /**
   * The browser's response to a request to check the validity of a given URL
   * pattern.
   * @param {string} type The content type.
   * @param {string} mode The browser mode.
   * @param {string} pattern The pattern.
   * @param {bool} valid Whether said pattern is valid in the context of
   *     a content exception setting.
   */
  ContentSettings.patternValidityCheckComplete =
      function(type, mode, pattern, valid) {
    var exceptionsList =
        document.querySelector('div[contentType=' + type + '] ' +
                               'list[mode=' + mode + ']');
    exceptionsList.patternValidityCheckComplete(pattern, valid);
  };

  // Export
  return {
    ContentSettings: ContentSettings
  };

});
<commit_msg>Revert 100784 - Prefs: fix Javascript error when content settings are updated while settings page not visible.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('options', function() {

  var OptionsPage = options.OptionsPage;

  //////////////////////////////////////////////////////////////////////////////
  // ContentSettings class:

  /**
   * Encapsulated handling of content settings page.
   * @constructor
   */
  function ContentSettings() {
    this.activeNavTab = null;
    OptionsPage.call(this, 'content', templateData.contentSettingsPageTabTitle,
                     'content-settings-page');
  }

  cr.addSingletonGetter(ContentSettings);

  ContentSettings.prototype = {
    __proto__: OptionsPage.prototype,

    initializePage: function() {
      OptionsPage.prototype.initializePage.call(this);

      chrome.send('getContentFilterSettings');

      var exceptionsButtons =
          this.pageDiv.querySelectorAll('.exceptions-list-button');
      for (var i = 0; i < exceptionsButtons.length; i++) {
        exceptionsButtons[i].onclick = function(event) {
          var page = ContentSettingsExceptionsArea.getInstance();
          page.showList(
              event.target.getAttribute('contentType'));
          OptionsPage.navigateToPage('contentExceptions');
          // Add on the proper hash for the content type, and store that in the
          // history so back/forward and tab restore works.
          var hash = event.target.getAttribute('contentType');
          window.history.replaceState({pageName: page.name}, page.title,
                                      '/' + page.name + "#" + hash);
        };
      }

      var manageHandlersButton = $('manage-handlers-button');
      if (manageHandlersButton) {
        manageHandlersButton.onclick = function(event) {
          OptionsPage.navigateToPage('handlers');
        };
      }

      var manageIntentsButton = $('manage-intents-button');
      if (manageIntentsButton) {
        manageIntentsButton.onclick = function(event) {
          OptionsPage.navigateToPage('intents');
        };
      }

      // Cookies filter page ---------------------------------------------------
      $('show-cookies-button').onclick = function(event) {
        chrome.send('coreOptionsUserMetricsAction', ['Options_ShowCookies']);
        OptionsPage.navigateToPage('cookies');
      };

      if (!templateData.enable_click_to_play)
        $('click_to_play').hidden = true;

      if (!templateData.enable_web_intents && $('intent-section'))
        $('intent-section').hidden = true;
    },
  };

  ContentSettings.updateHandlersEnabledRadios = function(enabled) {
    var selector = '#content-settings-page input[type=radio][value=' +
        (enabled ? 'allow' : 'block') + '].handler-radio';
    document.querySelector(selector).checked = true;
  };

  /**
   * Sets the values for all the content settings radios.
   * @param {Object} dict A mapping from radio groups to the checked value for
   *     that group.
   */
  ContentSettings.setContentFilterSettingsValue = function(dict) {
    for (var group in dict) {
      document.querySelector('input[type=radio][name=' + group + '][value=' +
                             dict[group]['value'] + ']').checked = true;
      var radios = document.querySelectorAll('input[type=radio][name=' +
                                             group + ']');
      for (var i = 0, len = radios.length; i < len; i++) {
        var managed = dict[group]['managed'];
        radios[i].disabled = managed;
        radios[i].controlledBy = managed ? 'policy': null;
      }
    }
    OptionsPage.updateManagedBannerVisibility();
  };

  /**
   * Initializes an exceptions list.
   * @param {string} type The content type that we are setting exceptions for.
   * @param {Array} list An array of pairs, where the first element of each pair
   *     is the filter string, and the second is the setting (allow/block).
   */
  ContentSettings.setExceptions = function(type, list) {
    var exceptionsList =
        document.querySelector('div[contentType=' + type + ']' +
                               ' list[mode=normal]');
    exceptionsList.setExceptions(list);
  };

  ContentSettings.setHandlers = function(list) {
    $('handlers-list').setHandlers(list);
  };

  ContentSettings.setIgnoredHandlers = function(list) {
    $('ignored-handlers-list').setHandlers(list);
  };

  ContentSettings.setOTRExceptions = function(type, list) {
    var exceptionsList =
        document.querySelector('div[contentType=' + type + ']' +
                               ' list[mode=otr]');

    exceptionsList.parentNode.hidden = false;
    exceptionsList.setExceptions(list);
  };

  /**
   * The browser's response to a request to check the validity of a given URL
   * pattern.
   * @param {string} type The content type.
   * @param {string} mode The browser mode.
   * @param {string} pattern The pattern.
   * @param {bool} valid Whether said pattern is valid in the context of
   *     a content exception setting.
   */
  ContentSettings.patternValidityCheckComplete =
      function(type, mode, pattern, valid) {
    var exceptionsList =
        document.querySelector('div[contentType=' + type + '] ' +
                               'list[mode=' + mode + ']');
    exceptionsList.patternValidityCheckComplete(pattern, valid);
  };

  // Export
  return {
    ContentSettings: ContentSettings
  };

});
<|endoftext|>


<commit_before>var memoize = function (fn, results) {
    var memo = [0, 1];

    // closure
    return function compute(n) {
        var current = memo[n];

        // avoid false truthy test by ensuring type if a number
        // instead of !current as it could be 0|1
        if (typeof current !== 'number') {
            current = fn(compute, n);
            memo[n] = results[results.length] = current;
        }

        return current;
    };
};

var cb = function(fn, n) {
    var results = fn(n - 1) + fn( n - 2 );
    return results;
};

var sequence = [];
var printSequence = memoize(cb, sequence);
printSequence(10);

console.log(sequence);
<commit_msg>Converted to OO implementation<commit_after>'use strict';

var Fibonacci = function Fibonacci() {
    if (!(this instanceof Fibonacci)) {
        return new Fibonacci();
    }

    this.memo = null;
};

/**
 * Resets the memo before each run
 */
Fibonacci.prototype.reset = function reset() {
    this.memo = [0, 1];
};

/**
 * Generates a sequence of fibonacci numbers
 * computed to nth upper bound.
 *
 * @return void
 */
Fibonacci.prototype.generate = function generate(n) {
    this.reset();

    var self = this;
    var idx = 0;

    return run.call(this, n);
};

/**
 * Returns the sequence of Fibonacci numbers computed
 * to nth bound.
 *
 * @return void
 */
Fibonacci.prototype.getSequence = function getSequence() {
    return this.memo;
};

/*** Private Methods ***/
var compute = function(fn, n) {
    var results = fn(n - 1) + fn( n - 2 );
    return results;
};

var run = function run(n) {
    var current = this.memo[n];
    if (typeof(current) !== 'number') {
        current = compute(run.bind(this), n);
        this.memo[n] = current;
    }

    return current;
};

var fib = new Fibonacci();
var max = fib.generate(10);
console.log('sequence: ', fib.getSequence());
console.log('max: ', max);

// var memoize = function (fn, results) {
//     var memo = [0, 1];

//     // closure
//     return function compute(n) {
//         var current = memo[n];

//         // avoid false truthy test by ensuring type if a number
//         // instead of !current as it could be 0|1
//         if (typeof current !== 'number') {
//             current = fn(compute, n);
//             memo[n] = results[results.length] = current;
//         }

//         return current;
//     };
// };

// var compute = function(fn, n) {
//     var results = fn(n - 1) + fn( n - 2 );
//     return results;
// };

// var sequence = [];
// var printSequence = memoize(compute, sequence);
// printSequence(10);
// console.log(sequence);
<|endoftext|>