<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Query } from 'react-apollo';

import exploreContentsQuery from 'react/components/ExploreContents/queries/exploreContents';

import ErrorAlert from 'react/components/UI/ErrorAlert';
import BlocksLoadingIndicator from 'react/components/UI/BlocksLoadingIndicator';
import Grid from 'react/components/UI/Grid';
import Cell from 'react/components/Cell';

export default class ExploreContents extends PureComponent {
  static propTypes = {
    type: PropTypes.string,
    sort: PropTypes.oneOf(['UPDATED_AT', 'RANDOM']).isRequired,
    fetchPolicy: PropTypes.oneOf(['cache-first', 'network-only']).isRequired,
    seed: PropTypes.number.isRequired,
  }

  static defaultProps = {
    type: null,
  }

  state = {
    page: 1,
    per: 12,
    hasMore: true,
    q: null,
  }

  resetQuery = (query) => {
    const q = query === '' ? null : query;
    this.setState({ q, page: 1, hasMore: true });
  }

  loadMore = fetchMore => () => {
    const { page, per } = this.state;

    fetchMore({
      variables: { page: page + 1, per },
      updateQuery: (prevResult, { fetchMoreResult }) => ({
        contents: [
          ...prevResult.contents,
          ...fetchMoreResult.contents,
        ],
      }),
    }).then(({ errors, data }) => {
      const { contents: { length } } = data;
      const hasMore = !errors && length > 0 && length >= per;

      this.setState({
        page: page + 1,
        hasMore,
      });
    });
  }

  render() {
    const { per, hasMore, q } = this.state;
    const {
      type, sort, fetchPolicy, seed,
    } = this.props;

    return (
      <Query
        query={exploreContentsQuery}
        variables={{
          type, per, sort, q, seed,
        }}
        fetchPolicy={fetchPolicy}
      >
        {({
          loading, error, data, fetchMore,
        }) => {
          if (error) {
            return (
              <ErrorAlert>
                {error.message}
              </ErrorAlert>
            );
          }

          if (!data.contents) {
            return <BlocksLoadingIndicator />;
          }

          const { contents } = data;

          return (

              {loading &&
                <BlocksLoadingIndicator />
              }

              {!loading && contents.length > 0 &&
                <Grid
                  pageStart={1}
                  threshold={800}
                  initialLoad={false}
                  loader={<BlocksLoadingIndicator key="loading" />}
                  hasMore={contents.length >= per && hasMore}
                  loadMore={this.loadMore(fetchMore)}
                >
                  {contents.map(blokk => (
                    <Cell.Konnectable
                      key={`${blokk.__typename}_${blokk.id}`}
                      konnectable={blokk}
                      context={contents}
                    />
                  ))}
                </Grid>
              }

          );
        }}
      </Query>
    );
  }
}
<commit_msg>Do not render /explore contents server side<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Query } from 'react-apollo';

import exploreContentsQuery from 'react/components/ExploreContents/queries/exploreContents';

import ErrorAlert from 'react/components/UI/ErrorAlert';
import BlocksLoadingIndicator from 'react/components/UI/BlocksLoadingIndicator';
import Grid from 'react/components/UI/Grid';
import Cell from 'react/components/Cell';

export default class ExploreContents extends PureComponent {
  static propTypes = {
    type: PropTypes.string,
    sort: PropTypes.oneOf(['UPDATED_AT', 'RANDOM']).isRequired,
    fetchPolicy: PropTypes.oneOf(['cache-first', 'network-only']).isRequired,
    seed: PropTypes.number.isRequired,
  }

  static defaultProps = {
    type: null,
  }

  state = {
    page: 1,
    per: 12,
    hasMore: true,
    q: null,
  }

  resetQuery = (query) => {
    const q = query === '' ? null : query;
    this.setState({ q, page: 1, hasMore: true });
  }

  loadMore = fetchMore => () => {
    const { page, per } = this.state;

    fetchMore({
      variables: { page: page + 1, per },
      updateQuery: (prevResult, { fetchMoreResult }) => ({
        contents: [
          ...prevResult.contents,
          ...fetchMoreResult.contents,
        ],
      }),
    }).then(({ errors, data }) => {
      const { contents: { length } } = data;
      const hasMore = !errors && length > 0 && length >= per;

      this.setState({
        page: page + 1,
        hasMore,
      });
    });
  }

  render() {
    const { per, hasMore, q } = this.state;
    const {
      type, sort, fetchPolicy, seed,
    } = this.props;

    return (
      <Query
        query={exploreContentsQuery}
        variables={{
          type, per, sort, q, seed,
        }}
        fetchPolicy={fetchPolicy}
        ssr={false}
      >
        {({
          loading, error, data, fetchMore,
        }) => {
          if (error) {
            return (
              <ErrorAlert>
                {error.message}
              </ErrorAlert>
            );
          }

          if (!data.contents) {
            return <BlocksLoadingIndicator />;
          }

          const { contents } = data;

          return (

              {loading &&
                <BlocksLoadingIndicator />
              }

              {!loading && contents.length > 0 &&
                <Grid
                  pageStart={1}
                  threshold={800}
                  initialLoad={false}
                  loader={<BlocksLoadingIndicator key="loading" />}
                  hasMore={contents.length >= per && hasMore}
                  loadMore={this.loadMore(fetchMore)}
                >
                  {contents.map(blokk => (
                    <Cell.Konnectable
                      key={`${blokk.__typename}_${blokk.id}`}
                      konnectable={blokk}
                      context={contents}
                    />
                  ))}
                </Grid>
              }

          );
        }}
      </Query>
    );
  }
}
<|endoftext|>


<commit_before>/**
 * csslike - Lexer
 * Copyright (c) 2011, Christopher Jeffrey. (MIT Licensed)
 */

/**
 * States:
 *  inside
 *    refers to the "inside" of rules and at rules.
 *    rules and at-rules are becoming more and more
 *    syntactically similar every day - they can now
 *    contain both properties and/or rules.
 *  at_rule
 *    the "header" of an at-rule.
 *  single_string
 *    a single quoted string.
 *  double_string
 *    a double quoted string.
 *  comment
 *    a multiline comment.
 *  value
 *    a rule's or at-rule's property's value.
 */

var lex = function(css) {
  css = css.replace(/\r\n/g, '\n')
           .replace(/\r/g, '\n');

  var i = 0
    , l = css.length
    , ch
    , buff = ''
    , key
    , line = 1
    , offset = 0
    , tokens = []
    , stack = [];

  var state = function() {
    return stack[stack.length-1];
  };

  for (; i < l; i++) {
    ch = css[i];
    offset++;

    switch (ch) {
      case '\\':
        buff += ch;
        buff += css[++i];
        break;
      case '\n':
        offset = 0;
        line++;
        ; // FALL-THROUGH
      case '\t':
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          default:
            break;
        }
        ; // FALL-THROUGH
      case ' ':
        // need this to get at-rule
        // names, store them in `key`
        if (state() === 'at_rule' && !key) {
          key = buff;
          buff = '';
        }
        buff += ch;
        break;
      case '{':
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          case 'at_rule':
            tokens.push({
              type: 'nested_at',
              name: key,
              params: buff.trim(),
              line: line
            });
            key = '';
            buff = '';
            stack.pop();
            stack.push('inside');
            break;
          case 'value':
            // we were inside a
            // selector instead
            // of a property like
            // we originally thought
            stack.pop();
            buff = key + ':' + buff;
            key = '';
            ; // FALL-THROUGH
          case 'inside':
          default:
            tokens.push({
              type: 'rule',
              selector: buff.trim(),
              line: line
            });
            buff = '';
            stack.push('inside');
            break;
        }
        break;
      case '}':
        switch (state()) {
          case 'value':
            tokens.push({
              type: 'property',
              key: key.trim(),
              val: buff.trim(),
              line: line
            });
            key = '';
            buff = '';
            stack.pop();
            // in case someone omitted
            // the semicolon at the end
            if (state() === 'inside') {
              ; // FALL-THROUGH
            } else {
              break; // do we need this?
            }
          case 'inside':
            tokens.push({
              type: 'end',
              line: line
            });
            buff = '';
            break;
        }
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          default:
            stack.pop();
            break;
        }
        break;
      case ':':
        switch (state()) {
          case 'inside':
            // at this point were
            // either inside a selector
            // or a property, we dont
            // really know. well assume
            // its a property for now,
            // and if we hit a curly
            // brace later, we can
            // change the state token
            // to a rule
            key = buff;
            buff = '';
            stack.push('value');
            break;
          default:
            buff += ch;
            break;
        }
        break;
      case ';':
        switch (state()) {
          case 'value':
            // a useless semicolon
            if (!key) break;
            tokens.push({
              type: 'property',
              key: key.trim(),
              val: buff.trim(),
              line: line
            });
            key = '';
            buff = '';
            stack.pop();
            break;
          case 'at_rule':
            tokens.push({
              type: 'at',
              name: key,
              params: buff.trim(),
              line: line
            });
            key = '';
            buff = '';
            stack.pop();
            break;
          default:
            buff += ch;
            break;
        }
        break;
      case '/':
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          default:
            if (css[i+1] === '*') {
              i++;
              stack.push('comment');
            } else {
              buff += ch;
            }
            break;
        }
        break;
      case '*':
        switch (state()) {
          case 'comment':
            if (css[i+1] === '/') {
              i++;
              tokens.push({
                type: 'comment',
                text: buff,
                line: line
              });
              buff = '';
              stack.pop();
            } else {
              buff += ch;
            }
            break;
          default:
            buff += ch;
            break;
        }
        break;
      case '@':
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          default:
            buff = '';
            buff += ch;
            stack.push('at_rule');
            break;
        }
        break;
      case '"':
      case '\'':
        switch (state()) {
          case 'comment':
            break;
          case 'single_string':
            if (ch === '\'') {
              stack.pop();
            }
            break;
          case 'double_string':
            if (ch === '"') {
              stack.pop();
            }
            break;
          default:
            stack.push(ch === '"'
              ? 'double_string'
              : 'single_string');
            break;
        }
        buff += ch;
        break;
      default:
        if (ch < ' ') {
          throw new
            Error('Control character found.'
                  + '\nLine: ' + line
                  + '\nOffset: ' + offset);
        }
        buff += ch;
        break;
    }
  }

  return tokens;
};

/**
 * Expose
 */

module.exports = lex;
<commit_msg>reorganize string tokenization, add assertions, remove whitespace<commit_after>/**
 * csslike - Lexer
 * Copyright (c) 2011, Christopher Jeffrey. (MIT Licensed)
 */

var assert = require('assert').ok;

/**
 * States:
 *  inside
 *    refers to the "inside" of rules and at rules.
 *    rules and at-rules are becoming more and more
 *    syntactically similar every day - they can now
 *    contain both properties and/or rules.
 *  at_rule
 *    the "header" of an at-rule.
 *  single_string
 *    a single quoted string.
 *  double_string
 *    a double quoted string.
 *  comment
 *    a multiline comment.
 *  value
 *    a rule's or at-rule's property's value.
 */

var lexer = function(css) {
  css = css.replace(/\r\n|\r/g, '\n');

  var i = 0
    , l = css.length
    , ch
    , buff = ''
    , key
    , line = 1
    , offset = 0
    , tokens = []
    , stack = [];

  var state = function() {
    return stack[stack.length-1];
  };

  for (; i < l; i++) {
    ch = css[i];
    offset++;

    switch (ch) {
      case '\\':
        buff += ch;
        buff += css[++i];
        break;
      case '\n':
        offset = 0;
        line++;
        ; // FALL-THROUGH
      case '\t':
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          default:
            break;
        }
        ; // FALL-THROUGH
      case ' ':
        // need this to get at-rule
        // names, store them in `key`
        if (state() === 'at_rule' && !key) {
          key = buff;
          buff = '';
        }
        buff += ch;
        break;
      case '{':
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          case 'at_rule':
            tokens.push({
              type: 'nested_at',
              name: key,
              params: buff.trim(),
              line: line
            });
            key = '';
            buff = '';
            stack.pop();
            stack.push('inside');
            break;
          case 'value':
            // we were inside a
            // selector instead
            // of a property like
            // we originally thought
            stack.pop();
            buff = key + ':' + buff;
            key = '';
            ; // FALL-THROUGH
          case 'inside':
          default:
            tokens.push({
              type: 'rule',
              selector: buff.trim(),
              line: line
            });
            buff = '';
            stack.push('inside');
            break;
        }
        break;
      case '}':
        switch (state()) {
          case 'value':
            tokens.push({
              type: 'property',
              key: key.trim(),
              val: buff.trim(),
              line: line
            });
            key = '';
            buff = '';
            stack.pop();
            // in case someone omitted
            // the semicolon at the end
            if (state() === 'inside') {
              ; // FALL-THROUGH
            } else {
              //break; // do we need this?
              assert(('bad state', 0));
            }
          case 'inside':
            tokens.push({
              type: 'end',
              line: line
            });
            buff = '';
            break;
        }
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          default:
            stack.pop();
            break;
        }
        break;
      case ':':
        switch (state()) {
          case 'inside':
            // at this point were
            // either inside a selector
            // or a property, we dont
            // really know. well assume
            // its a property for now,
            // and if we hit a curly
            // brace later, we can
            // change the state token
            // to a rule
            key = buff;
            buff = '';
            stack.push('value');
            break;
          default:
            buff += ch;
            break;
        }
        break;
      case ';':
        switch (state()) {
          case 'value':
            // a useless semicolon
            if (!key) break;
            tokens.push({
              type: 'property',
              key: key.trim(),
              val: buff.trim(),
              line: line
            });
            key = '';
            buff = '';
            stack.pop();
            break;
          case 'at_rule':
            tokens.push({
              type: 'at',
              name: key,
              params: buff.trim(),
              line: line
            });
            key = '';
            buff = '';
            stack.pop();
            break;
          default:
            buff += ch;
            break;
        }
        break;
      case '/':
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          default:
            if (css[i+1] === '*') {
              i++;
              stack.push('comment');
            } else {
              buff += ch;
            }
            break;
        }
        break;
      case '*':
        switch (state()) {
          case 'comment':
            if (css[i+1] === '/') {
              i++;
              tokens.push({
                type: 'comment',
                text: buff,
                line: line
              });
              buff = '';
              stack.pop();
            } else {
              buff += ch;
            }
            break;
          default:
            buff += ch;
            break;
        }
        break;
      case '@':
        switch (state()) {
          case 'single_string':
          case 'double_string':
          case 'comment':
            buff += ch;
            break;
          default:
            assert(buff.trim() === '');
            buff = '';
            buff += ch;
            stack.push('at_rule');
            break;
        }
        break;
      case '"':
        switch (state()) {
          case 'comment':
          case 'single_string':
            break;
          case 'double_string':
            stack.pop();
            break;
          default:
            stack.push('double_string');
            break;
        }
        buff += ch;
        break;
      case '\'':
        switch (state()) {
          case 'comment':
          case 'double_string':
            break;
          case 'single_string':
            stack.pop();
            break;
          default:
            stack.push('single_string');
            break;
        }
        buff += ch;
        break;
      default:
        if (ch < ' ') {
          throw new
            Error('Control character found.'
                  + '\nLine: ' + line
                  + '\nOffset: ' + offset);
        }
        buff += ch;
        break;
    }
  }

  return tokens;
};

/**
 * Expose
 */

module.exports = lexer;
<|endoftext|>


<commit_before>// Code generated by coz. DO NOT EDIT.
/**
 * Convert nested object to flatten or expand.
 * @module objnest
 * @version 5.1.0
 */

'use strict'

const create = require('./create')
const Objnest = require('./objnest')

const lib = create()

Object.assign(lib, create, {
  create,
  Objnest
})

module.exports = lib

exports.create = create
exports.expand = lib.expand
exports.flatten = lib.flatten
<commit_msg>increment version<commit_after>// Code generated by coz. DO NOT EDIT.
/**
 * Convert nested object to flatten or expand.
 * @module objnest
 * @version 5.1.1
 */

'use strict'

const create = require('./create')
const Objnest = require('./objnest')

const lib = create()

Object.assign(lib, create, {
  create,
  Objnest
})

module.exports = lib

exports.create = create
exports.expand = lib.expand
exports.flatten = lib.flatten
<|endoftext|>


<commit_before>// Import modules:
var gulp = require('gulp')
,   pkg = require('./package.json')
,   less = require('gulp-less')
,   rename = require('gulp-rename')
,   concat = require('gulp-concat')
,   jshint = require('gulp-jshint')
,   header = require('gulp-header')
,   gutils = require('gulp-util')
,   replace = require('gulp-replace')
,   minifyCSS = require('gulp-minify-css')
,   uglify = require('gulp-uglify')
,   jshint = require('gulp-jshint')
,   header = require('gulp-header')
,   footer = require('gulp-footer');

// Define values for file headers:
var chui = ['ChUI-Android.css','ChUI-iOS.css','ChUI-Win.css','ChUI.js']
,   osNames = ['Android','iOS','Windows']
,   osTypes = ['android','ios','win'];

// Define header for ChUI files:
var chuiHeader = ['/*',
  '    pO\\',
  '   6  /\\',
  '     /OO\\',
  '    /OOOO\\',
  '   /OOOOOO\\',
  '  (OOOOOOOO)',
  '   \\:~==~:/',
  '',
  '<%= pkg.title %>',
  '<%= chuiName %>',
  'Copyright ' + gutils.date("yyyy") + ' Sourcebits www.sourcebits.com',
  'License: <%= pkg.licences[0].type %>',
  'Version: <%= pkg.version %>',
  '*/\n'].join('\n');

// Define header for minfied ChUI files:
var chuiHeaderMin = ['/*',
  '<%= pkg.title %>',
  '<%= chuiName %>',
  'Copyright ' + gutils.date("yyyy") + ' Sourcebits www.sourcebits.com',
  'License: <%= pkg.licences[0].type %>',
  'Version: <%= pkg.version %>',
  '*/\n'].join('\n');

// Define header for examples and demos:
var htmlHeader = ['<!DOCTYPE html>',
'<html lang="en"<%= langDir %>>',
'<head>',
'  <meta charset="utf-8">',
'  <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">',
'  <meta name="apple-mobile-web-app-capable" content="yes">',
'  <meta name="mobile-web-app-capable" content="yes">',
'  <meta name="msapplication-tap-highlight" content="no">',
'  <title>ChocolateChip-UI <%= osName %></title>',
'  <link rel="stylesheet" href="../chui/chui-<%= osType %>-<%= pkg.version %>.css">',
'  <script src="<%= pkg.jquery.url %>"></script>',
'  <script src="../chui/chui-<%= pkg.version %>.js"></script>'].join('\n') + '\n';

// Process, minify and output LESS:
gulp.task('less', function () {
  osTypes.forEach(function(ctx, idx) {
    gulp.src('src/themes/' + ctx + '/main.less')
      .pipe(less())
      .pipe(rename('chui-' + ctx + '-' + pkg.version + '.css'))
      .pipe(header(chuiHeader, { pkg : pkg, chuiName: chui[idx] }))
      .pipe(gulp.dest(pkg.projectPath + 'chui/')).pipe(minifyCSS({}))
      .pipe(header(chuiHeaderMin, { pkg : pkg, chuiName: chui[idx] }))
      .pipe(rename('chui-' + ctx + '-' + pkg.version + '.min.css'))
      .pipe(gulp.dest(pkg.projectPath + './chui/'));;
  });
});

// Concat, minify and output JavaScript:
gulp.task('js', function () {
  var chuijs_start = [
    '\(function\(\$\) {',
    '  \'use strict\';'
  ].join('\n');
  var chuijs_end = '\n\}\)\(window\.jQuery\);';

  gulp.src([
    'src/chui/utils.js',
    'src/chui/events.js',
    'src/chui/detectors.js',
    'src/chui/browsers.js',
    'src/chui/gestures.js',
    'src/chui/desktop.js',
    'src/chui/layout.js',
    'src/chui/pubsub.js',
    'src/chui/navigation.js',
    'src/chui/buttons.js',
    'src/chui/blockui.js',
    'src/chui/center.js',
    'src/chui/busy.js',
    'src/chui/popup.js',
    'src/chui/popover.js',
    'src/chui/segmented.js',
    'src/chui/togglePanel.js',
    'src/chui/paging.js',
    'src/chui/deletableList.js',
    'src/chui/selectList.js',
    'src/chui/sheet.js',
    'src/chui/slideout.js',
    'src/chui/stepper.js',
    'src/chui/switch.js',
    'src/chui/scroll.js',
    'src/chui/tabbar.js',
    'src/chui/templates.js',
    'src/chui/search.js',
    'src/chui/carousel.js',
    'src/chui/range.js'
  ])
    .pipe(concat("chui-" + pkg.version + ".js"))
    .pipe(replace(/\(function\(\$\) {\n^.*\'use strict\';/img, ''))
    .pipe(replace(/\}\)\(window\.jQuery\);/img, ''))
    .pipe(replace(/\n\n\n/img, ''))
    .pipe(replace(/\n\n/img, '\n'))
    .pipe(header(chuijs_start))
    .pipe(footer(chuijs_end))
    .pipe(header(chuiHeader, { pkg : pkg, chuiName: chui[3] }))
    .pipe(gulp.dest(pkg.projectPath + 'chui/'))
    .pipe(uglify())
    .pipe(header(chuiHeaderMin, { pkg : pkg, chuiName: chui[3] }))
    .pipe(rename("chui-" + pkg.version + ".min.js"))
    .pipe(gulp.dest(pkg.projectPath + 'chui/'));;
});

// Create examples & demos (ltr or rtl):
gulp.task('examples', function() {
  var langDir = '';
  var rtl = gutils.env.dir === 'rtl';
  var dir = 'ltr';
  var prefix = '';
  if (rtl) {
    prefix = 'rtl-';
    dir = 'rtl';
    langDir =  ' dir="rtl"';
    // Copy out rtl images:
    gulp.src('src/rtl-images/**/*')
      .pipe(gulp.dest('rtl-images/'));
    // Copy out regular images & data:`
    gulp.run('copy');
  }
  osTypes.forEach(function(ctx, idx) {
    gulp.src('src/' + prefix + 'examples/**/*')
      .pipe(header(htmlHeader, { pkg : pkg, osType : osTypes[idx], osName : osNames[idx], dir : prefix[dir], langDir : langDir }))
      .pipe(gulp.dest(prefix + 'examples-' + ctx + '/'));
    gulp.src('src/' + prefix + 'demo/*.html')
      .pipe(header(htmlHeader, { pkg : pkg, osType : osTypes[idx], osName : osNames[idx], dir : prefix[dir], langDir : langDir }))
      .pipe(rename(prefix + 'demo-' + ctx + '.html'))
      .pipe(gulp.dest(prefix + 'demo/'));
  });
});

// Copy out media:
gulp.task('copy', function() {
  gulp.src('src/images/**/*')
    .pipe(gulp.dest('images/'));
  gulp.src('src/data/**/*')
    .pipe(gulp.dest('data/'));
});

// JSHint:
gulp.task('jshint', function() {
  gulp.src("chui-" + pkg.version + ".js")
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
});

/* Define default task:
To build, just enter gulp in terminal.
To build right-to-left examples, use:

  gulp --dir rtl

*/
gulp.task('default', ['less','js','jshint','copy','examples']);

gulp.task('chui', ['less','js','jshint']);

// Watch LESS files and generate CSS:
gulp.task('watch', function() {
  gulp.watch('src/themes/**/*.less', ['less']);
});<commit_msg>projectpath for eg. & media<commit_after>// Import modules:
var gulp = require('gulp')
,   pkg = require('./package.json')
,   less = require('gulp-less')
,   rename = require('gulp-rename')
,   concat = require('gulp-concat')
,   jshint = require('gulp-jshint')
,   header = require('gulp-header')
,   gutils = require('gulp-util')
,   replace = require('gulp-replace')
,   minifyCSS = require('gulp-minify-css')
,   uglify = require('gulp-uglify')
,   jshint = require('gulp-jshint')
,   header = require('gulp-header')
,   footer = require('gulp-footer');

//Add Trailing slash to projectPath if not exists.
pkg.projectPath = pkg.projectPath.replace(/\/?$/, '/');

// Define values for file headers:
var chui = ['ChUI-Android.css','ChUI-iOS.css','ChUI-Win.css','ChUI.js']
,   osNames = ['Android','iOS','Windows']
,   osTypes = ['android','ios','win'];

// Define header for ChUI files:
var chuiHeader = ['/*',
  '    pO\\',
  '   6  /\\',
  '     /OO\\',
  '    /OOOO\\',
  '   /OOOOOO\\',
  '  (OOOOOOOO)',
  '   \\:~==~:/',
  '',
  '<%= pkg.title %>',
  '<%= chuiName %>',
  'Copyright ' + gutils.date("yyyy") + ' Sourcebits www.sourcebits.com',
  'License: <%= pkg.licences[0].type %>',
  'Version: <%= pkg.version %>',
  '*/\n'].join('\n');

// Define header for minfied ChUI files:
var chuiHeaderMin = ['/*',
  '<%= pkg.title %>',
  '<%= chuiName %>',
  'Copyright ' + gutils.date("yyyy") + ' Sourcebits www.sourcebits.com',
  'License: <%= pkg.licences[0].type %>',
  'Version: <%= pkg.version %>',
  '*/\n'].join('\n');

// Define header for examples and demos:
var htmlHeader = ['<!DOCTYPE html>',
'<html lang="en"<%= langDir %>>',
'<head>',
'  <meta charset="utf-8">',
'  <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">',
'  <meta name="apple-mobile-web-app-capable" content="yes">',
'  <meta name="mobile-web-app-capable" content="yes">',
'  <meta name="msapplication-tap-highlight" content="no">',
'  <title>ChocolateChip-UI <%= osName %></title>',
'  <link rel="stylesheet" href="../chui/chui-<%= osType %>-<%= pkg.version %>.css">',
'  <script src="<%= pkg.jquery.url %>"></script>',
'  <script src="../chui/chui-<%= pkg.version %>.js"></script>'].join('\n') + '\n';

// Process, minify and output LESS:
gulp.task('less', function () {
  osTypes.forEach(function(ctx, idx) {
    gulp.src('src/themes/' + ctx + '/main.less')
      .pipe(less())
      .pipe(rename('chui-' + ctx + '-' + pkg.version + '.css'))
      .pipe(header(chuiHeader, { pkg : pkg, chuiName: chui[idx] }))
      .pipe(gulp.dest(pkg.projectPath + 'chui/')).pipe(minifyCSS({}))
      .pipe(header(chuiHeaderMin, { pkg : pkg, chuiName: chui[idx] }))
      .pipe(rename('chui-' + ctx + '-' + pkg.version + '.min.css'))
      .pipe(gulp.dest(pkg.projectPath + './chui/'));;
  });
});

// Concat, minify and output JavaScript:
gulp.task('js', function () {
  var chuijs_start = [
    '\(function\(\$\) {',
    '  \'use strict\';'
  ].join('\n');
  var chuijs_end = '\n\}\)\(window\.jQuery\);';

  gulp.src([
    'src/chui/utils.js',
    'src/chui/events.js',
    'src/chui/detectors.js',
    'src/chui/browsers.js',
    'src/chui/gestures.js',
    'src/chui/desktop.js',
    'src/chui/layout.js',
    'src/chui/pubsub.js',
    'src/chui/navigation.js',
    'src/chui/buttons.js',
    'src/chui/blockui.js',
    'src/chui/center.js',
    'src/chui/busy.js',
    'src/chui/popup.js',
    'src/chui/popover.js',
    'src/chui/segmented.js',
    'src/chui/togglePanel.js',
    'src/chui/paging.js',
    'src/chui/deletableList.js',
    'src/chui/selectList.js',
    'src/chui/sheet.js',
    'src/chui/slideout.js',
    'src/chui/stepper.js',
    'src/chui/switch.js',
    'src/chui/scroll.js',
    'src/chui/tabbar.js',
    'src/chui/templates.js',
    'src/chui/search.js',
    'src/chui/carousel.js',
    'src/chui/range.js'
  ])
    .pipe(concat("chui-" + pkg.version + ".js"))
    .pipe(replace(/\(function\(\$\) {\n^.*\'use strict\';/img, ''))
    .pipe(replace(/\}\)\(window\.jQuery\);/img, ''))
    .pipe(replace(/\n\n\n/img, ''))
    .pipe(replace(/\n\n/img, '\n'))
    .pipe(header(chuijs_start))
    .pipe(footer(chuijs_end))
    .pipe(header(chuiHeader, { pkg : pkg, chuiName: chui[3] }))
    .pipe(gulp.dest(pkg.projectPath + 'chui/'))
    .pipe(uglify())
    .pipe(header(chuiHeaderMin, { pkg : pkg, chuiName: chui[3] }))
    .pipe(rename("chui-" + pkg.version + ".min.js"))
    .pipe(gulp.dest(pkg.projectPath + 'chui/'));;
});

// Create examples & demos (ltr or rtl):
gulp.task('examples', function() {
  var langDir = '';
  var rtl = gutils.env.dir === 'rtl';
  var dir = 'ltr';
  var prefix = '';
  if (rtl) {
    prefix = 'rtl-';
    dir = 'rtl';
    langDir =  ' dir="rtl"';
    // Copy out rtl images:
    gulp.src('src/rtl-images/**/*')
      .pipe(gulp.dest(pkg.projectPath +'rtl-images/'));
    // Copy out regular images & data:`
    gulp.run('copy');
  }
  osTypes.forEach(function(ctx, idx) {
    gulp.src('src/' + prefix + 'examples/**/*')
      .pipe(header(htmlHeader, { pkg : pkg, osType : osTypes[idx], osName : osNames[idx], dir : prefix[dir], langDir : langDir }))
      .pipe(gulp.dest(pkg.projectPath + prefix + 'examples-' + ctx + '/'));
    gulp.src('src/' + prefix + 'demo/*.html')
      .pipe(header(htmlHeader, { pkg : pkg, osType : osTypes[idx], osName : osNames[idx], dir : prefix[dir], langDir : langDir }))
      .pipe(rename(prefix + 'demo-' + ctx + '.html'))
      .pipe(gulp.dest(pkg.projectPath + prefix + 'demo/'));
  });
});

// Copy out media:
gulp.task('copy', function() {
  gulp.src('src/images/**/*')
    .pipe(gulp.dest(pkg.projectPath + 'images/'));
  gulp.src('src/data/**/*')
    .pipe(gulp.dest(pkg.projectPath + 'data/'));
});

// JSHint:
gulp.task('jshint', function() {
  gulp.src("chui-" + pkg.version + ".js")
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
});

/* Define default task:
To build, just enter gulp in terminal.
To build right-to-left examples, use:

  gulp --dir rtl

*/
gulp.task('default', ['less','js','jshint','copy','examples']);

gulp.task('chui', ['less','js','jshint']);

// Watch LESS files and generate CSS:
gulp.task('watch', function() {
  gulp.watch('src/themes/**/*.less', ['less']);
});<|endoftext|>


<commit_before>'use strict';

//hello :D

//module imports
const format = require('string-template');

//local imports
const constants = require('./constants');
const utils = require('./utils');

const FormeBaseInput = require('./baseInput');
const FormeInputError = require('./errors').FormeInputError;

const InputProcessHandler = require('./handlers/input/inputProcessHandler');
const InputValidateHandler = require('./handlers/input/inputValidateHandler');

const {FormeConfigurableMethod} = require('./configurable');

//main class
class FormeInput extends FormeBaseInput {
    constructor(form, page, name) {
        super('input', form, page, name);

        this._special = false;
        this._convert = false;
        this._template = null;
    }

    //private configuration methods
    _buildConfigurableMethods() {
        return Object.assign(super._buildConfigurableMethods(), {
            //input.next()
            next: new FormeConfigurableMethod('next'),

            //input.prev()
            prev: new FormeConfigurableMethod('prev'),

            //input.reset()
            reset: new FormeConfigurableMethod('reset'),

            //input.rerun()
            rerun: new FormeConfigurableMethod('rerun'),
        });
    }

    //private methods
    _processWithValue(value, promise) {
        //allow for manual processing on this!
        const state = this._createState(arguments.length >= 2?value:this._form._getInputNameValue(this._name));

        //process handlers are synchronous only, so if we ask for a promise, we should wrap it!
        if (promise) {
            //wrap in a promise!
            return new Promise((resolve, reject) => {
                try {
                    this._processAllWithState(state);
                }
                catch(err) {
                    reject(err);
                }

                //done!
                resolve(state.value);
            });
        } else {
            //no promises :D
            this._processAllWithState(state);

            return state.value;
        }
    }

    _processAllWithState(state) {
        if (this._processHandlers.length) {
            const oldValue = state.value;

            try {
                for (let handler of this._processHandlers) {
                    this._executeProcessHandler(handler, state);
                }

                //save state change
                if (state.value !== oldValue) {
                    this._form._setInputNameValue(this._name, state.value);
                }
            }
            catch(err) {
                //catch error, but still save state change
                if (state.value !== oldValue) {
                    this._form._setInputNameValue(this._name, state.value);
                }

                //pass error on!
                throw err;
            }
        }
    }

    //private next methods
    _nextExecuteHandler(handlers, index) {
        const handler = handlers[index];

        return new Promise((resolve, reject) => {
            //what type of handler is it?
            const state = this._createState(this._form._getInputNameValue(this._name));
            const oldValue = state.value;

            return this._executeHandlerByType(handler, state)
            .then(() => {
                //update value if state changed
                if (state.value !== oldValue) {
                    this._form._setInputNameValue(this._name, state.value);
                }

                //next
                resolve();
            })
            .catch(err => {
                //extract error string from catch
                let error = err.message || '';

                //update value if state changed
                if (state.value !== oldValue) {
                    this._form._setInputNameValue(this._name, state.value);
                }

                //use handler specified error instead
                if (handler.error !== null) {
                    error = handler.error;
                }

                //apply inline template vars
                error = format(error,{
                    name: this._name,
                    label: this._label,
                });

                //add error to container
                this.error(error);

                //stop further execution
                reject();
            });
        })
        .then(() => {
            //continue iteration
            if (++index < handlers.length) {
                return this._nextExecuteHandler(handlers, index);
            }
        })

        //valid :D
        .then(() => this._valid())

        //invalid :(
        .catch(err => {
            //unhandled error
            this._form._catchError(err);

            //call base _invalid execution
            return this._invalid();
        });
    }

    //private execute methods
    _executeHandlerByType(handler, state) {
        //decide which type of handler we are...handling!
        if (handler instanceof InputProcessHandler) {
            return this._executeProcessHandler(handler, state);
        } else if (handler instanceof InputValidateHandler) {
            return this._executeValidateHandler(handler, state);
        } else {
            return Promise.reject(this._createError(`unknown execution handler '${handler}'`, this));
        }
    }

    _executeProcessHandler(handler, state) {
        return new Promise((resolve, reject) => {
            //iterate over all handlers
            try {
                handler.execute(this, state);
            } catch(err) {
                //pass error into the promise chain
                reject(err);
            }

            //success
            resolve();
        });
    }

    _executeValidateHandler(handler, state) {
        return handler.execute(this, state);
    }

    _executeInvalidHandler(handler) {
        return handler.call(this, this._form, this);
    }

    _executeValidHandler(handler) {
        return handler.call(this, this._form, this);
    }

    _executeSuccessHandler(handler) {
        //should be overridden
        return handler.call(this, this._form, this);
    }

    _executeFailHandler(handler) {
        //should be overridden
        return handler.call(this, this._form, this);
    }

    _executeSubmitHandler(handler) {
        //should be overridden
        return handler.call(this, this._form, this);
    }

    _executeDoneHandler(handler) {
        return handler.call(this, this._form, this);
    }

    //private create methods
    _createError(message) {
        return new FormeInputError(message);
    }

    _createState(value) {
        return {
            require: false,
            value: value,
        };
    }

    //private methods
    _calculateType() {
        if (this._type !== null) {
            //overridden by user
            return this._type;
        } else {
            //pick defaults
            if (this._hidden) {
                return 'hidden';
            } else {
                //check for types based on actions
                if (this._actionTriggers !== null) {
                    for(let action of this._actionTriggers) {
                        //special actions
                        if (action.special) {
                            switch(action.action) {
                                case constants.actions.prev:
                                case constants.actions.next:
                                case constants.actions.reset:
                                    return 'button';
                                case constants.actions.rerun:
                                case constants.actions.submit:
                                    return 'submit';
                            }
                        }
                    }
                }

                //standard types
                if (this._checked !== null) {
                    //checkbox
                    return 'checkbox';
                } else {
                    //is it secured (override always)
                    if (this._secure) {
                        return 'password';
                    } else {
                        //lookup type based on handlers
                        let type = 'text';//default to 'text'

                        //iterate all handlers and apply their html5 input types (handlers later in the chain take precedence)
                        for (let handler of this._executeHandlers) {
                            //check to see if handler sets type
                            let handlerType = handler.htmlInputType;
                            if (handlerType !== null) {
                                type = handlerType;
                            }
                        }

                        //not found, return default
                        return type;
                    }
                }
            }
        }
    }

    //templating
    templateVars() {
        //do the check here, when calling this it will always eventually have to check (Even if extended FormeInput) because we need these base values by calling super.templateVars()!
        if (this.callingActiveMethod('templateVars')) {
            //build component vars ( if we have any)
            return (this._component?this._component.templateVars():Promise.resolve(null))

            //now build input vars
            .then(componentVars => {
                const errors = this._form._request._fetchInputErrors(this._name).map(error => error.error);
                const type = this._calculateType();
                const alias = this._outputName;
                const required = !this._form._unrequire && this._required;

                //build input class names
                const classNames = [];
                const stateClassNames = [];

                //input or button
                if (type === 'button' || type === 'submit') {
                    if (this._form._buttonClassNames.length) {
                        for (let className of this._form._buttonClassNames) {
                            classNames.push(className);
                        }
                    }
                } else {
                    if (this._form._inputClassNames.length) {
                        for (let className of this._form._inputClassNames) {
                            classNames.push(className);
                        }
                    }
                }

                //error (state)
                if (errors.length && this._form._errorClassNames.length) {
                    for (let className of this._form._errorClassNames) {
                        classNames.push(className);
                        stateClassNames.push(className)
                    }
                }

                //required (state)
                if (required && this._form._requiredClassNames.length) {
                    for (let className of this._form._requiredClassNames) {
                        classNames.push(className);
                        stateClassNames.push(className)
                    }
                }

                //input custom defined via input.className()
                if (this._classNames.length) {
                    for (let className of this._classNames) {
                        classNames.push(className);
                    }
                }

                //build the vars (remembering to merge the component vars)
                return Object.assign({
                    id: this._id !== null ? this._id : `__forme_auto_id__${this._name}`,
                    name: this._name,
                    alias: alias,
                    className: classNames.join(' '),
                    stateClassName: stateClassNames.join(' '),
                    icon: this._icon,
                    data: Object.assign({}, ...this._data.map(data => ({['data-' + data.name]: data.value}))),
                    label: this._label,
                    help: this._help,
                    type: type,
                    component: null,//will get overridden by this._component.templateVars()
                    placeholder: this._placeholder,
                    required: required,
                    readonly: this._readonly,
                    value: this._form._request._values[this._name],
                    checked: (this._form._request._pageFirst && this._checked) || (!this._form._request._pageFirst && ((type === 'checkbox' && this._form._request._values[this._name] !== null) || (type !== 'checkbox' && this._form._request._values[this._name] !== null))),
                    errors: errors && errors.length ? errors : null,
                    options: this._options,
                    context: this._context,

                    //input template vars (dont populate these yet because we might cause an infinite loop on user code. )
                    template: null,
                    rendered: null,
                }, componentVars);
            })

            //we have a complete vars object for this input
            .then(vars => {
                //does the input have a template
                if (!this._template) {
                    //no template so chain em!
                    return vars;
                } else {
                    //let the driver render the template!
                    return utils.promise.result(this._form._driver.renderInputTemplate(this._form, this, this._template, vars))
                    .then(rendered => {
                        //done, so lets dump details into rendered
                        vars.template = this._template;
                        vars.rendered = rendered || null;

                        //chain
                        return vars;
                    });
                }
            });
        }
    }

    //state
    value() {
        //we need to override this to check for different calling pattern
        //todo: modify this so we have value() and getValue();
        if (arguments.length === 0) {
            //get value, let the form decide where from
            return this._form._getInputNameValue(this._name);

        } else if (arguments.length === 1) {
            if (!this._form._isStarted() || this._form._isBuilding()) {
                //set the default value (e.g. the form is still building)
                return super.value(...arguments);
            } else {
                //set runtime value (e.g. modify submitted value)
                this._form._setInputNameValue(this._name, arguments[0]);
            }

            //chain
            return this;
        }
    }

    error(error) {
        //shortcut to add a message (container handles input piping)
        if (this.callingActiveMethod('error')) {
            return this._form.error(this._name, error);
        }
    }
}

//expose module
module.exports = FormeInput;<commit_msg>tweak<commit_after>'use strict';

//hello :D

//module imports
const format = require('string-template');

//local imports
const constants = require('./constants');
const utils = require('./utils');

const FormeBaseInput = require('./baseInput');
const FormeInputError = require('./errors').FormeInputError;

const InputProcessHandler = require('./handlers/input/inputProcessHandler');
const InputValidateHandler = require('./handlers/input/inputValidateHandler');

const {FormeConfigurableMethod} = require('./configurable');

//main class
class FormeInput extends FormeBaseInput {
    constructor(form, page, name) {
        super('input', form, page, name);

        this._special = false;
        this._convert = false;
        this._template = null;
    }

    //private configuration methods
    _buildConfigurableMethods() {
        return Object.assign(super._buildConfigurableMethods(), {
            //input.next()
            next: new FormeConfigurableMethod('next'),

            //input.prev()
            prev: new FormeConfigurableMethod('prev'),

            //input.reset()
            reset: new FormeConfigurableMethod('reset'),

            //input.rerun()
            rerun: new FormeConfigurableMethod('rerun'),
        });
    }

    //private methods
    _processWithValue(value, promise) {
        //allow for manual processing on this!
        const state = this._createState(arguments.length >= 2?value:this._form._getInputNameValue(this._name));

        //process handlers are synchronous only, so if we ask for a promise, we should wrap it!
        if (promise) {
            //wrap in a promise!
            return new Promise((resolve, reject) => {
                try {
                    this._processAllWithState(state);
                }
                catch(err) {
                    reject(err);
                }

                //done!
                resolve(state.value);
            });
        } else {
            //no promises :D
            this._processAllWithState(state);

            return state.value;
        }
    }

    _processAllWithState(state) {
        if (this._processHandlers.length) {
            const oldValue = state.value;

            try {
                for (let handler of this._processHandlers) {
                    this._executeProcessHandler(handler, state);
                }

                //save state change
                if (state.value !== oldValue) {
                    this._form._setInputNameValue(this._name, state.value);
                }
            }
            catch(err) {
                //catch error, but still save state change
                if (state.value !== oldValue) {
                    this._form._setInputNameValue(this._name, state.value);
                }

                //pass error on!
                throw err;
            }
        }
    }

    //private next methods
    _nextExecuteHandler(handlers, index) {
        const handler = handlers[index];

        return new Promise((resolve, reject) => {
            //what type of handler is it?
            const state = this._createState(this._form._getInputNameValue(this._name));
            const oldValue = state.value;

            return this._executeHandlerByType(handler, state)
            .then(() => {
                //update value if state changed
                if (state.value !== oldValue) {
                    this._form._setInputNameValue(this._name, state.value);
                }

                //next
                resolve();
            })
            .catch(err => {
                //extract error string from catch
                let error = err.message || '';

                //update value if state changed
                if (state.value !== oldValue) {
                    this._form._setInputNameValue(this._name, state.value);
                }

                //use handler specified error instead
                if (handler.error !== null) {
                    error = handler.error;
                }

                //apply inline template vars
                error = format(error,{
                    name: this._name,
                    label: this._label,
                });

                //add error to container
                this.error(error);

                //stop further execution
                reject();
            });
        })
        .then(() => {
            //continue iteration
            if (++index < handlers.length) {
                return this._nextExecuteHandler(handlers, index);
            }
        })

        //valid :D
        .then(() => this._valid())

        //invalid :(
        .catch(err => {
            //unhandled error
            this._form._catchError(err);

            //call base _invalid execution
            return this._invalid();
        });
    }

    //private execute methods
    _executeHandlerByType(handler, state) {
        //decide which type of handler we are...handling!
        if (handler instanceof InputProcessHandler) {
            return this._executeProcessHandler(handler, state);
        } else if (handler instanceof InputValidateHandler) {
            return this._executeValidateHandler(handler, state);
        } else {
            return Promise.reject(this._createError(`unknown execution handler '${handler}'`, this));
        }
    }

    _executeProcessHandler(handler, state) {
        return new Promise((resolve, reject) => {
            //iterate over all handlers
            try {
                handler.execute(this, state);
            } catch(err) {
                //pass error into the promise chain
                reject(err);
            }

            //success
            resolve();
        });
    }

    _executeValidateHandler(handler, state) {
        return handler.execute(this, state);
    }

    _executeInvalidHandler(handler) {
        return handler.call(this, this._form, this);
    }

    _executeValidHandler(handler) {
        return handler.call(this, this._form, this);
    }

    _executeSuccessHandler(handler) {
        //should be overridden
        return handler.call(this, this._form, this);
    }

    _executeFailHandler(handler) {
        //should be overridden
        return handler.call(this, this._form, this);
    }

    _executeSubmitHandler(handler) {
        //should be overridden
        return handler.call(this, this._form, this);
    }

    _executeDoneHandler(handler) {
        return handler.call(this, this._form, this);
    }

    //private create methods
    _createError(message) {
        return new FormeInputError(message);
    }

    _createState(value) {
        return {
            require: false,
            value: value,
        };
    }

    //private methods
    _calculateType() {
        if (this._type !== null) {
            //overridden by user
            return this._type;
        } else {
            //pick defaults
            if (this._hidden) {
                return 'hidden';
            } else {
                //check for types based on actions
                if (this._actionTriggers !== null) {
                    for(let action of this._actionTriggers) {
                        //special actions
                        if (action.special) {
                            switch(action.action) {
                                case constants.actions.prev:
                                case constants.actions.next:
                                case constants.actions.reset:
                                    return 'button';
                                case constants.actions.rerun:
                                case constants.actions.submit:
                                    return 'submit';
                            }
                        }
                    }
                }

                //standard types
                if (this._checked !== null) {
                    //checkbox
                    return 'checkbox';
                } else {
                    //is it secured (override always)
                    if (this._secure) {
                        return 'password';
                    } else {
                        //lookup type based on handlers
                        let type = 'text';//default to 'text'

                        //iterate all handlers and apply their html5 input types (handlers later in the chain take precedence)
                        for (let handler of this._executeHandlers) {
                            //check to see if handler sets type
                            let handlerType = handler.htmlInputType;
                            if (handlerType !== null) {
                                type = handlerType;
                            }
                        }

                        //not found, return default
                        return type;
                    }
                }
            }
        }
    }

    //templating
    templateVars() {
        //do the check here, when calling this it will always eventually have to check (Even if extended FormeInput) because we need these base values by calling super.templateVars()!
        if (this.callingActiveMethod('templateVars')) {
            //build component vars ( if we have any)
            return (this._component?this._component.templateVars():Promise.resolve(null))

            //now build input vars
            .then(componentVars => {
                const errors = this._form._request._fetchInputErrors(this._name).map(error => error.error);
                const type = this._calculateType();
                const alias = this._outputName;
                const required = !this._form._unrequire && this._required;

                //build input class names
                const classNames = [];
                const stateClassNames = [];

                //input or button
                if (type === 'button' || type === 'submit') {
                    if (this._form._buttonClassNames.length) {
                        for (let className of this._form._buttonClassNames) {
                            classNames.push(className);
                        }
                    }
                } else {
                    if (this._form._inputClassNames.length) {
                        for (let className of this._form._inputClassNames) {
                            classNames.push(className);
                        }
                    }
                }

                //error (state)
                if (errors.length && this._form._errorClassNames.length) {
                    for (let className of this._form._errorClassNames) {
                        classNames.push(className);
                        stateClassNames.push(className)
                    }
                }

                //required (state)
                if (required && this._form._requiredClassNames.length) {
                    for (let className of this._form._requiredClassNames) {
                        classNames.push(className);
                        stateClassNames.push(className)
                    }
                }

                //input custom defined via input.className()
                if (this._classNames.length) {
                    for (let className of this._classNames) {
                        classNames.push(className);
                    }
                }

                //build the vars (remembering to merge the component vars)
                return Object.assign({
                    id: this._id !== null ? this._id : `__forme_auto_id__${this._name}`,
                    name: this._name,
                    alias: alias,
                    className: classNames.join(' '),
                    stateClassName: stateClassNames.join(' '),
                    icon: this._icon,
                    data: Object.assign({}, ...this._data.map(data => ({['data-' + data.name]: data.value}))),
                    label: this._label,
                    help: this._help,
                    type: type,
                    component: null,//will get overridden by this._component.templateVars()
                    placeholder: this._placeholder,
                    required: required,
                    readonly: this._readonly,
                    value: this._form._request._values[this._name],
                    checked: (this._form._request._pageFirst && this._checked) || (!this._form._request._pageFirst && ((type === 'checkbox' && this._form._request._values[this._name] !== null) || (type !== 'checkbox' && this._form._request._values[this._name] !== null))),
                    errors: errors && errors.length ? errors : null,
                    options: this._options,
                    context: this._context,

                    //input template vars (dont populate these yet because we might cause an infinite loop on user code. )
                    rendered: null,//null indicates that there was no template!
                }, componentVars);
            })

            //we have a complete vars object for this input
            .then(vars => {
                //does the input have a template
                if (!this._template) {
                    //no template so chain em!
                    return vars;
                } else {
                    //let the driver render the template!
                    return utils.promise.result(this._form._driver.renderInputTemplate(this._form, this, this._template, vars))
                    .then(rendered => {
                        //done, so lets dump details into rendered
                        vars.rendered = rendered || '';

                        //chain
                        return vars;
                    });
                }
            });
        }
    }

    //state
    value() {
        //we need to override this to check for different calling pattern
        //todo: modify this so we have value() and getValue();
        if (arguments.length === 0) {
            //get value, let the form decide where from
            return this._form._getInputNameValue(this._name);

        } else if (arguments.length === 1) {
            if (!this._form._isStarted() || this._form._isBuilding()) {
                //set the default value (e.g. the form is still building)
                return super.value(...arguments);
            } else {
                //set runtime value (e.g. modify submitted value)
                this._form._setInputNameValue(this._name, arguments[0]);
            }

            //chain
            return this;
        }
    }

    error(error) {
        //shortcut to add a message (container handles input piping)
        if (this.callingActiveMethod('error')) {
            return this._form.error(this._name, error);
        }
    }
}

//expose module
module.exports = FormeInput;<|endoftext|>


<commit_before>// @flow

import { MEDIA_TYPE, type MediaType } from '../base/media/constants';
import { isLocalParticipantModerator } from '../base/participants/functions';

import { MEDIA_TYPE_TO_WHITELIST_STORE_KEY, MEDIA_TYPE_TO_PENDING_STORE_KEY } from './constants';

/**
 * Returns this feature's root state.
 *
 * @param {Object} state - Global state.
 * @returns {Object} Feature state.
 */
const getState = state => state['features/av-moderation'];

/**
 * We use to construct once the empty array so we can keep the same instance between calls
 * of getParticipantsAskingToAudioUnmute.
 *
 * @type {*[]}
 */
const EMPTY_ARRAY = [];

/**
 * Returns whether moderation is enabled per media type.
 *
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @param {Object} state - Global state.
 * @returns {null|boolean|*}
 */
export const isEnabledFromState = (mediaType: MediaType, state: Object) =>
    (mediaType === MEDIA_TYPE.AUDIO
        ? getState(state)?.audioModerationEnabled
        : getState(state)?.videoModerationEnabled) === true;

/**
 * Returns whether moderation is enabled per media type.
 *
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @returns {null|boolean|*}
 */
export const isEnabled = (mediaType: MediaType) => (state: Object) => isEnabledFromState(mediaType, state);

/**
 * Returns whether moderation is supported by the backend.
 *
 * @returns {null|boolean}
 */
export const isSupported = () => (state: Object) => {
    const { conference } = state['features/base/conference'];

    return conference ? conference.isAVModerationSupported() : false;
};

/**
 * Returns whether local participant is approved to unmute a media type.
 *
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @param {Object} state - Global state.
 * @returns {boolean}
 */
export const isLocalParticipantApprovedFromState = (mediaType: MediaType, state: Object) => {
    const approved = (mediaType === MEDIA_TYPE.AUDIO
        ? getState(state).audioUnmuteApproved
        : getState(state).videoUnmuteApproved) === true;

    return approved || isLocalParticipantModerator(state);
};

/**
 * Returns whether local participant is approved to unmute a media type.
 *
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @returns {null|boolean|*}
 */
export const isLocalParticipantApproved = (mediaType: MediaType) =>
    (state: Object) =>
        isLocalParticipantApprovedFromState(mediaType, state);

/**
 * Returns a selector creator which determines if the participant is approved or not for a media type.
 *
 * @param {string} id - The participant id.
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @returns {boolean}
 */
export const isParticipantApproved = (id: string, mediaType: MediaType) => (state: Object) => {
    const storeKey = MEDIA_TYPE_TO_WHITELIST_STORE_KEY[mediaType];

    return Boolean(getState(state)[storeKey][id]);
};

/**
 * Returns a selector creator which determines if the participant is pending or not for a media type.
 *
 * @param {Participant} participant - The participant.
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @returns {boolean}
 */
export const isParticipantPending = (participant: Object, mediaType: MediaType) => (state: Object) => {
    const storeKey = MEDIA_TYPE_TO_PENDING_STORE_KEY[mediaType];
    const arr = getState(state)[storeKey];

    return Boolean(arr.find(pending => pending.id === participant.id));
};

/**
 * Selector which returns a list with all the participants asking to audio unmute.
 * This is visible ony for the moderator.
 *
 * @param {Object} state - The global state.
 * @returns {Array<Object>}
 */
export const getParticipantsAskingToAudioUnmute = (state: Object) => {
    if (isLocalParticipantModerator(state)) {
        return getState(state).pendingAudio;
    }

    return EMPTY_ARRAY;
};

/**
 * Returns true if a special notification can be displayed when a participant
 * tries to unmute.
 *
 * @param {MediaType} mediaType - 'audio' or 'video' media type.
 * @param {Object} state - The global state.
 * @returns {boolean}
 */
export const shouldShowModeratedNotification = (mediaType: MediaType, state: Object) =>
    isEnabledFromState(mediaType, state)
    && !isLocalParticipantApprovedFromState(mediaType, state);
<commit_msg>fix(av-moderation) mark as unsupported while in a breakout room<commit_after>// @flow

import { MEDIA_TYPE, type MediaType } from '../base/media/constants';
import { isLocalParticipantModerator } from '../base/participants/functions';
import { isInBreakoutRoom } from '../breakout-rooms/functions';

import { MEDIA_TYPE_TO_WHITELIST_STORE_KEY, MEDIA_TYPE_TO_PENDING_STORE_KEY } from './constants';

/**
 * Returns this feature's root state.
 *
 * @param {Object} state - Global state.
 * @returns {Object} Feature state.
 */
const getState = state => state['features/av-moderation'];

/**
 * We use to construct once the empty array so we can keep the same instance between calls
 * of getParticipantsAskingToAudioUnmute.
 *
 * @type {*[]}
 */
const EMPTY_ARRAY = [];

/**
 * Returns whether moderation is enabled per media type.
 *
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @param {Object} state - Global state.
 * @returns {null|boolean|*}
 */
export const isEnabledFromState = (mediaType: MediaType, state: Object) =>
    (mediaType === MEDIA_TYPE.AUDIO
        ? getState(state)?.audioModerationEnabled
        : getState(state)?.videoModerationEnabled) === true;

/**
 * Returns whether moderation is enabled per media type.
 *
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @returns {null|boolean|*}
 */
export const isEnabled = (mediaType: MediaType) => (state: Object) => isEnabledFromState(mediaType, state);

/**
 * Returns whether moderation is supported by the backend.
 *
 * @returns {null|boolean}
 */
export const isSupported = () => (state: Object) => {
    const { conference } = state['features/base/conference'];

    return Boolean(!isInBreakoutRoom(state) && conference?.isAVModerationSupported());
};

/**
 * Returns whether local participant is approved to unmute a media type.
 *
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @param {Object} state - Global state.
 * @returns {boolean}
 */
export const isLocalParticipantApprovedFromState = (mediaType: MediaType, state: Object) => {
    const approved = (mediaType === MEDIA_TYPE.AUDIO
        ? getState(state).audioUnmuteApproved
        : getState(state).videoUnmuteApproved) === true;

    return approved || isLocalParticipantModerator(state);
};

/**
 * Returns whether local participant is approved to unmute a media type.
 *
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @returns {null|boolean|*}
 */
export const isLocalParticipantApproved = (mediaType: MediaType) =>
    (state: Object) =>
        isLocalParticipantApprovedFromState(mediaType, state);

/**
 * Returns a selector creator which determines if the participant is approved or not for a media type.
 *
 * @param {string} id - The participant id.
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @returns {boolean}
 */
export const isParticipantApproved = (id: string, mediaType: MediaType) => (state: Object) => {
    const storeKey = MEDIA_TYPE_TO_WHITELIST_STORE_KEY[mediaType];

    return Boolean(getState(state)[storeKey][id]);
};

/**
 * Returns a selector creator which determines if the participant is pending or not for a media type.
 *
 * @param {Participant} participant - The participant.
 * @param {MEDIA_TYPE} mediaType - The media type to check.
 * @returns {boolean}
 */
export const isParticipantPending = (participant: Object, mediaType: MediaType) => (state: Object) => {
    const storeKey = MEDIA_TYPE_TO_PENDING_STORE_KEY[mediaType];
    const arr = getState(state)[storeKey];

    return Boolean(arr.find(pending => pending.id === participant.id));
};

/**
 * Selector which returns a list with all the participants asking to audio unmute.
 * This is visible ony for the moderator.
 *
 * @param {Object} state - The global state.
 * @returns {Array<Object>}
 */
export const getParticipantsAskingToAudioUnmute = (state: Object) => {
    if (isLocalParticipantModerator(state)) {
        return getState(state).pendingAudio;
    }

    return EMPTY_ARRAY;
};

/**
 * Returns true if a special notification can be displayed when a participant
 * tries to unmute.
 *
 * @param {MediaType} mediaType - 'audio' or 'video' media type.
 * @param {Object} state - The global state.
 * @returns {boolean}
 */
export const shouldShowModeratedNotification = (mediaType: MediaType, state: Object) =>
    isEnabledFromState(mediaType, state)
    && !isLocalParticipantApprovedFromState(mediaType, state);
<|endoftext|>


<commit_before>'use strict';

var util = require('util');
var Memcached = require('memcached');
var debug = require('debug')('loopback:connector:memcached');
var Connector = require('loopback-connector').Connector;
var NAME = 'memcached';
var client = null;

// TODO: Clean up! This is probably
// not needed
var hashMe = function(key) {
  return key;
};

/**
 * Constructor for Memcached connector
 * @param {Object} settings The settings object
 * @param {DataSource} dataSource The data source
 * instance
 * @constructo
 */
var MemcachedDB = function(dataSource) {
  if (!(this instanceof MemcachedDB)) {
    return new MemcachedDB(dataSource);
  }

  Connector.call(this, NAME, dataSource.settings);

  this.debug = dataSource.settings.debug || debug.enabled;
  this.dataSource = dataSource;

  if (this.debug) {
    debug('Settings %j', dataSource.settings);
  }
};

util.inherits(MemcachedDB, Connector);

MemcachedDB.prototype.connect = function(fn) {
  if (client) {
    if (typeof fn === 'function') {
      process.nextTick(fn);
    }
  }

  client = new Memcached(this.dataSource.settings.hosts, this.dataSource.settings.options, fn);

  client.on('issue', function onIsse(e) {
    if (this.debug) {
      debug('Issue!', e);
    }
  }.bind(this))
  .on('failure', function onFailure(e) {
    if (this.debug) {
      debug('Failure!', e);
    }
  }.bind(this))
  .on('reconnecting', function onReconnecting(i) {
    if (this.debug) {
      debug('reconnecting...', i);
    }
  }.bind(this))
  .on('reconnected', function onReconnected(i) {
    if (this.debug) {
      debug('reconnected!', i);
    }
  }.bind(this))
  .on('remove', function(i) {
    if (this.debug) {
      debug('Removed server from consistent hashing', i);
    }
  }.bind(this));
};

MemcachedDB.prototype.getTypes = function onGetTypes() {
  return ['db', 'nosql', 'memcached'];
};

MemcachedDB.prototype.end = function onEnd() {
  client.end.apply(client, arguments);
};

MemcachedDB.prototype.cachedump = function onCacheDump() {
  client.cachedump.apply(client, arguments);
};

MemcachedDB.prototype.items = function onItems() {
  client.items.apply(client, arguments);
};

MemcachedDB.prototype.slabs = function onSlabs() {
  client.slabs.apply(client, arguments);
};

MemcachedDB.prototype.settings = function onSettings() {
  client.settings.apply(client, arguments);
};

MemcachedDB.prototype.version = function onVersion() {
  client.version.apply(client, arguments);
};

MemcachedDB.prototype.stats = function onStats() {
  client.stats.apply(client, arguments);
};

MemcachedDB.prototype.flush = function onFlush() {
  client.flush.apply(client, arguments);
};

MemcachedDB.prototype.del = function onDel() {
  client.del.apply(client, arguments);
};

MemcachedDB.prototype.decr = function onDecr() {
  client.decr.apply(client, arguments);
};

MemcachedDB.prototype.incr = function onIncr() {
  client.incr.apply(client, arguments);
};

MemcachedDB.prototype.append = function onAppend() {
  client.append.apply(client, arguments);
};

MemcachedDB.prototype.replace = function onReplace() {
  client.replace.apply(client, arguments);
};

MemcachedDB.prototype.add = function onAdd() {
  client.add.apply(client, arguments);
};

MemcachedDB.prototype.get = function onGet() {
  client.get.apply(client, arguments);
};

MemcachedDB.prototype.gets = function onGets() {
  client.gets.apply(client, arguments);
};

MemcachedDB.prototype.set = function onSet() {
  client.set.apply(client, arguments);
};

MemcachedDB.prototype.touch = function onTouch() {
  client.touch.apply(client, arguments);
};

MemcachedDB.prototype.format = function onFormat(data) {
  return (typeof(data) === 'object') ? JSON.stringify(data) : data;
};

/**
CRUD Ops isn't really needed, but seeing how it could
work with Memcached.
*/
MemcachedDB.prototype.exists = function onExists(model, id, callback) {
  console.log('exists', model, id, callback)
  this.get(id, function(e, item) {
    callback(e, !!(!e && item));
  });
};

MemcachedDB.prototype.find = function(model, id, callback) {
  console.log('find', arguments);
  this.get(id, function(e, item) {
    console.log('find', e, item);
    callback(e, item);
  });
};

MemcachedDB.prototype.all = function(model, filter, callback) {
  if (filter) {
    this.find(model, filter.where, callback);
    return;
  }

  process.nextTick(function() {
    callback(new Error('Nothing found!'));
  });
};

// Add or update
MemcachedDB.prototype.save = function onSave(model, data, callback) {
  this.set(data.id, this.format(data), 100, callback);
};

// Add or update
MemcachedDB.prototype.create = function onCreate(model, data, callback) {
  this.set(data.id, this.format(data), 100, callback);
};

// Add or update
MemcachedDB.prototype.updateOrCreate = function onUpdateOrCreate(model, data, callback) {
  this.create(model, data, callback);
};

// Get a count on # of items in cache
MemcachedDB.prototype.count = function onCount(model, callback, where) {
  this.stats(function(e, res) {
    callback(e, res[0].curr_items);
  });
};

MemcachedDB.prototype.destroy = function onDestroy(model, id, callback) {
  this.del(id, function(e, res) {
    callback(e, res);
  });
};

// destroy all items
MemcachedDB.prototype.destroyAll = function onDestroyAll(model, data, callback) {
  if (data && data.id) {
    return this.destroy(model, data.id, callback);
  }

  this.flush(function(e, res) {
    callback(e, res);
  });
};

/**
 * Initialize the MongoDB connector for the given data source
 * @param {DataSource} dataSource The data source instance
 * @param {Function} [callback] The callback function
 */
exports.initialize = function initializeDataSource(dataSource, fn) {
  var settings = dataSource.settings;
  dataSource.connector = new MemcachedDB(dataSource);
  dataSource.connector.connect(fn)
};<commit_msg>Updated API<commit_after>'use strict';

var util = require('util');
var Memcached = require('memcached');
var debug = require('debug')('loopback:connector:memcached');
var Connector = require('loopback-connector').Connector;
var NAME = 'memcached';
var client = null;

// TODO: Clean up! This is probably
// not needed
var hashMe = function(key) {
  return key;
};

/**
 * Constructor for Memcached connector
 * @param {Object} settings The settings object
 * @param {DataSource} dataSource The data source
 * instance
 * @constructo
 */
var MemcachedDB = function(dataSource) {
  if (!(this instanceof MemcachedDB)) {
    return new MemcachedDB(dataSource);
  }

  Connector.call(this, NAME, dataSource.settings);

  this.debug = dataSource.settings.debug || debug.enabled;
  this.dataSource = dataSource;

  if (this.debug) {
    debug('Settings %j', dataSource.settings);
  }
};

util.inherits(MemcachedDB, Connector);

MemcachedDB.prototype.connect = function(fn) {
  if (client) {
    if (typeof fn === 'function') {
      process.nextTick(fn);
    }
  }

  client = new Memcached(this.dataSource.settings.hosts, this.dataSource.settings.options, fn);

  client.on('issue', function onIsse(e) {
    if (this.debug) {
      debug('Issue!', e);
    }
  }.bind(this))
  .on('failure', function onFailure(e) {
    if (this.debug) {
      debug('Failure!', e);
    }
  }.bind(this))
  .on('reconnecting', function onReconnecting(i) {
    if (this.debug) {
      debug('reconnecting...', i);
    }
  }.bind(this))
  .on('reconnected', function onReconnected(i) {
    if (this.debug) {
      debug('reconnected!', i);
    }
  }.bind(this))
  .on('remove', function(i) {
    if (this.debug) {
      debug('Removed server from consistent hashing', i);
    }
  }.bind(this));
};

MemcachedDB.prototype.getTypes = function onGetTypes() {
  return ['db', 'nosql', 'memcached'];
};

MemcachedDB.prototype.end = function onEnd() {
  client.end.apply(client, arguments);
};

MemcachedDB.prototype.cachedump = function onCacheDump() {
  client.cachedump.apply(client, arguments);
};

MemcachedDB.prototype.items = function onItems() {
  client.items.apply(client, arguments);
};

MemcachedDB.prototype.slabs = function onSlabs() {
  client.slabs.apply(client, arguments);
};

MemcachedDB.prototype.settings = function onSettings() {
  client.settings.apply(client, arguments);
};

MemcachedDB.prototype.version = function onVersion() {
  client.version.apply(client, arguments);
};

MemcachedDB.prototype.stats = function onStats() {
  client.stats.apply(client, arguments);
};

MemcachedDB.prototype.flush = function onFlush() {
  client.flush.apply(client, arguments);
};

MemcachedDB.prototype.del = function onDel() {
  client.del.apply(client, arguments);
};

MemcachedDB.prototype.decr = function onDecr() {
  client.decr.apply(client, arguments);
};

MemcachedDB.prototype.incr = function onIncr() {
  client.incr.apply(client, arguments);
};

MemcachedDB.prototype.append = function onAppend() {
  client.append.apply(client, arguments);
};

MemcachedDB.prototype.replace = function onReplace() {
  client.replace.apply(client, arguments);
};

MemcachedDB.prototype.add = function onAdd() {
  client.add.apply(client, arguments);
};

MemcachedDB.prototype.get = function onGet() {
  client.get.apply(client, arguments);
};

MemcachedDB.prototype.gets = function onGets() {
  client.gets.apply(client, arguments);
};

MemcachedDB.prototype.set = function onSet() {
  client.set.apply(client, arguments);
};

MemcachedDB.prototype.touch = function onTouch() {
  client.touch.apply(client, arguments);
};

MemcachedDB.prototype.format = function onFormat(data) {
  return (typeof(data) === 'object') ? JSON.stringify(data) : data;
};

/**
CRUD Ops isn't really needed, but seeing how it could
work with Memcached.
*/
MemcachedDB.prototype.exists = function onExists(model, id, callback) {
  console.log('exists', model, id, callback)
  this.get(id, function(e, item) {
    callback(e, !!(!e && item));
  });
};

MemcachedDB.prototype.find = function(model, id, callback) {
  console.log('find', arguments);
  this.get(id, function(e, item) {
    console.log('find', e, item);
    callback(e, item);
  });
};

MemcachedDB.prototype.all = function(model, filter, callback) {
  if (filter) {
    this.find(model, filter.where, callback);
    return;
  }

  process.nextTick(function() {
    callback(new Error('Nothing found!'));
  });
};

// Add or update
MemcachedDB.prototype.save = function onSave(model, data, callback) {
  this.set(data.id, this.format(data), 100, callback);
};

// Add or update
MemcachedDB.prototype.create = function onCreate(model, data, callback) {
  this.set(data.id, this.format(data), 100, callback);
};

// Add or update
MemcachedDB.prototype.updateOrCreate = function onUpdateOrCreate(model, data, callback) {
  this.create(model, data, callback);
};

// Get a count on # of items in cache
MemcachedDB.prototype.count = function onCount(model, callback, where) {
  this.stats(function(e, res) {
    callback(e, (!e && res && res.length) ? res[0].curr_items : null);
  });
};

MemcachedDB.prototype.destroy = function onDestroy(model, id, callback) {
  this.del(id, function(e, res) {
    callback(e, res);
  });
};

// destroy all items
MemcachedDB.prototype.destroyAll = function onDestroyAll(model, data, callback) {
  if (data && data.id) {
    return this.destroy(model, data.id, callback);
  }

  this.flush(function(e, res) {
    callback(e, res);
  });
};

/**
 * Initialize the MemcachedDB connector for the given data source
 * @param {DataSource} dataSource The data source instance
 * @param {Function} [callback] The callback function
 */
exports.initialize = function initializeDataSource(dataSource, fn) {
  var settings = dataSource.settings;
  dataSource.connector = new MemcachedDB(dataSource);
  dataSource.connector.connect(fn)
};<|endoftext|>


<commit_before>'use strict';

// modules
var path = require('path');
var assemble = require('fabricator-assemble');
var browserSync = require('browser-sync');
var csso = require('gulp-csso');
var del = require('del');
var gutil = require('gulp-util');
var gulpif = require('gulp-if');
var imagemin = require('gulp-imagemin');
var prefix = require('gulp-autoprefixer');
var rename = require('gulp-rename');
var replace = require('gulp-replace');
var reload = browserSync.reload;
var runSequence = require('run-sequence');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var webpack = require('webpack');
var gulp = require('gulp');
var ghPages = require('gulp-gh-pages');
var gulpFilter = require('gulp-filter');
var gulpDebug = require('gulp-debug');
var pkg = require('./package.json');

// configuration
var config = {
	pkg: pkg,
	path: {
		styles: {
			toolkit: './src/styles/'
		}
	},
	src: {
		scripts: {
			fabricator: './docs/demo/assets/fabricator/scripts/fabricator.js'
		},
		styles: {
			fabricator: './docs/demo/assets/fabricator/styles/fabricator.scss',
			toolkit: './src/styles/toolkit.scss'
		},
		images: './src/img/**/*'
	},
	demo: '.demo',
	distBower: '.dist-bower',
	dist: 'dist'
};

/**
 *
 *
 *
 *  DEMO TASKS
 *
 *
 *
 */

// webpack
var demoWebpackConfig   = require('./webpack.demo.config')(config);
var demoWebpackCompiler = webpack(demoWebpackConfig);

gulp.task('demo', function(cb) {
	runSequence('demo:clean',['demo:styles', 'demo:scripts', 'demo:images', 'demo:assemble'], cb)
});

// clean
gulp.task('demo:clean', function (cb) {
	del([config.demo], cb);
});

// styles
gulp.task('demo:styles:fabricator', function () {
	gulp.src(config.src.styles.fabricator)
		.pipe(sourcemaps.init())
		.pipe(sass().on('error', sass.logError))
		.pipe(prefix('last 1 version'))
		.pipe(rename('f.css'))
		.pipe(sourcemaps.write())
		.pipe(gulp.dest(path.join(config.demo , '/assets/fabricator/styles')))
		.pipe(reload({stream:true}));
});

gulp.task('demo:styles:toolkit', function () {
	gulp.src(config.src.styles.toolkit)
		.pipe(sourcemaps.init())
		.pipe(sass().on('error', sass.logError))
		.pipe(prefix('last 1 version'))
		.pipe(sourcemaps.write())
		.pipe(gulp.dest(path.join(config.demo , '/assets/toolkit/styles')))
		.pipe(reload({stream:true}));
});

gulp.task('demo:styles', ['demo:styles:fabricator', 'demo:styles:toolkit']);

// scripts
gulp.task('demo:scripts', function (done) {
	demoWebpackCompiler.run(function (error, result) {
		if (error) {
			gutil.log(gutil.colors.red(error));
		}
		result = result.toJson();
		if (result.errors.length) {
			result.errors.forEach(function (error) {
				gutil.log(gutil.colors.red(error));
			});
		}
		done();
	});
});

// images
gulp.task('demo:images', ['demo:favicon'], function () {
	return gulp.src(config.src.images)
		.pipe(imagemin())
		.pipe(gulp.dest(path.join(config.demo , '/assets/toolkit/img')));
});

gulp.task('demo:favicon', function () {
	return gulp.src('./docs/demo/favicon.ico')
		.pipe(gulp.dest(config.demo));
});

// assemble
gulp.task('demo:assemble', function (done) {
	assemble({
		layouts: 'docs/demo/views/layouts/*',
		layoutIncludes: 'docs/demo/views/layouts/includes/*',
		views: ['docs/demo/views/**/*','!docs/demo/views/+(layouts)/**'],
		materials: 'docs/demo/materials/**/*',
		data: 'docs/demo/data/**/*.{json,yml}',
		docs: 'docs/**/*.md',
		logErrors: true,
		dest: config.demo
	});
	done();
});

// server
gulp.task('demo:serve', function () {

	browserSync({
		server: {
			baseDir: config.demo
		},
		notify: false,
		logPrefix: 'FABRICATOR'
	});

	/**
	 * Because webpackCompiler.watch() isn't being used
	 * manually remove the changed file path from the cache
	 */
	function webpackCache(e) {
		var keys = Object.keys(demoWebpackConfig.cache);
		var key, matchedKey;
		for (var keyIndex = 0; keyIndex < keys.length; keyIndex++) {
			key = keys[keyIndex];
			if (key.indexOf(e.path) !== -1) {
				matchedKey = key;
				break;
			}
		}
		if (matchedKey) {
			delete demoWebpackConfig.cache[matchedKey];
		}
	}

	gulp.task('demo:assemble:watch', ['demo:assemble'], reload);
	gulp.watch('docs/{demo,guides}/**/*.{html,md,json,yml}', ['demo:assemble:watch']);

	gulp.task('demo:styles:fabricator:watch', ['demo:styles:fabricator']);
	gulp.watch('docs/demo/assets/fabricator/styles/**/*.scss', ['demo:styles:fabricator:watch']);

	gulp.task('demo:styles:toolkit:watch', ['demo:styles:toolkit']);
	gulp.watch('src/styles/**/*.scss', ['demo:styles:toolkit:watch']);

	gulp.task('demo:scripts:watch', ['demo:scripts'], reload);
	gulp.watch('docs/demo/assets/fabricator/scripts/**/*.js', ['demo:scripts:watch']).on('change', webpackCache);

	gulp.task('demo:images:watch', ['demo:images'], reload);
	gulp.watch(config.src.images, ['demo:images:watch']);

});

gulp.task('demo:deploy', ['demo'],  function() {
  return gulp.src(path.join(config.demo , '/**/*'))
    .pipe(ghPages({remoteUrl: 'https://github.com/zalando/brand-solutions-dress-code.git'}));
});

/**
 *
 *
 *
 *  DISTRIBUTION TASKS
 *
 *
 *
 */

gulp.task('dist', function (cb) {
	runSequence('dist:clean',['dist:styles', 'dist:styles:src', 'dist:images'], cb);
});

gulp.task('dist:clean', function (cb) {
	del([config.dist], cb);
});

gulp.task('dist:styles', function () {
	return gulp.src(config.src.styles.toolkit)
		.pipe(sass().on('error', sass.logError))
		.pipe(sourcemaps.init())
		.pipe(prefix('last 1 version'))
		.pipe(sourcemaps.write())
		.pipe(rename(pkg.name + '.css'))
		.pipe(gulp.dest(path.join(config.dist, 'css')))
		 // minified
		.pipe(rename(pkg.name + '.min.css'))
		.pipe(csso())
		.pipe(gulp.dest(path.join(config.dist, 'css')));
});

gulp.task('dist:styles:src', function () {
	return gulp.src(path.join(config.path.styles.toolkit, '/**/*'))
		.pipe(gulp.dest(path.join(config.dist, 'sass')));
});

gulp.task('dist:images', function () {
	return gulp.src(config.src.images)
		.pipe(imagemin())
		.pipe(gulp.dest(path.join(config.dist, '/img')));
});

gulp.task('dist:bower:clean', function (cb) {
	del([config.distBower], cb);
});

gulp.task('dist:bower', ['dist:bower:clean','dist'], function () {
	var bowerReadmeFilter = gulpFilter(['BOWER-README.md'], { restore: true });
    var importFilter = gulpFilter(['**/sass/_import.scss','**/sass/_base.scss'], { restore: true })

    return gulp.src([
		path.join(config.dist, '/**/*'),
		'bower.json',
		'LICENSE',
		'docs/BOWER-README.md',
		'.editorconfig'
	])
    .pipe(bowerReadmeFilter)
    .pipe(rename('README.md'))
	.pipe(gulp.dest(config.distBower))
    .pipe(bowerReadmeFilter.restore)
	.pipe(importFilter)
	.pipe(replace(/@import "..\/..\/node_modules\/(.*)"/g, function (match, p1) {
		if(p1.indexOf('breakpoint-sass') > -1) {
			return '@import "../../compass-breakpoint/stylesheets/breakpoint"';
		}else{
			return '@import "../../' + p1 + '"';
		}
	}))
    .pipe(importFilter.restore)
	.pipe(gulp.dest(config.distBower));
});

gulp.task('dist:bower:deploy', ['dist:bower'], function () {
	return gulp.src(path.join(config.distBower , '/**/*'))
		.pipe(ghPages({
			cacheDir: '.publish-bower',
			branch: 'master',
			remoteUrl: 'git@github.com:zalando/brand-solutions-dress-code-bower'
		}));
});

/**
 *
 *
 *
 * DEFAULT TASK
 *
 *
 *
 */
gulp.task('default', function () {
	// run demo
	runSequence('demo', function () {
		gulp.start('demo:serve');
	});
});
<commit_msg>fix(gulp): exclude BOWER-README when build static website<commit_after>'use strict';

// modules
var path = require('path');
var assemble = require('fabricator-assemble');
var browserSync = require('browser-sync');
var csso = require('gulp-csso');
var del = require('del');
var gutil = require('gulp-util');
var gulpif = require('gulp-if');
var imagemin = require('gulp-imagemin');
var prefix = require('gulp-autoprefixer');
var rename = require('gulp-rename');
var replace = require('gulp-replace');
var reload = browserSync.reload;
var runSequence = require('run-sequence');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var webpack = require('webpack');
var gulp = require('gulp');
var ghPages = require('gulp-gh-pages');
var gulpFilter = require('gulp-filter');
var gulpDebug = require('gulp-debug');
var pkg = require('./package.json');

// configuration
var config = {
	pkg: pkg,
	path: {
		styles: {
			toolkit: './src/styles/'
		}
	},
	src: {
		scripts: {
			fabricator: './docs/demo/assets/fabricator/scripts/fabricator.js'
		},
		styles: {
			fabricator: './docs/demo/assets/fabricator/styles/fabricator.scss',
			toolkit: './src/styles/toolkit.scss'
		},
		images: './src/img/**/*'
	},
	demo: '.demo',
	distBower: '.dist-bower',
	dist: 'dist'
};

/**
 *
 *
 *
 *  DEMO TASKS
 *
 *
 *
 */

// webpack
var demoWebpackConfig   = require('./webpack.demo.config')(config);
var demoWebpackCompiler = webpack(demoWebpackConfig);

gulp.task('demo', function(cb) {
	runSequence('demo:clean',['demo:styles', 'demo:scripts', 'demo:images', 'demo:assemble'], cb)
});

// clean
gulp.task('demo:clean', function (cb) {
	del([config.demo], cb);
});

// styles
gulp.task('demo:styles:fabricator', function () {
	gulp.src(config.src.styles.fabricator)
		.pipe(sourcemaps.init())
		.pipe(sass().on('error', sass.logError))
		.pipe(prefix('last 1 version'))
		.pipe(rename('f.css'))
		.pipe(sourcemaps.write())
		.pipe(gulp.dest(path.join(config.demo , '/assets/fabricator/styles')))
		.pipe(reload({stream:true}));
});

gulp.task('demo:styles:toolkit', function () {
	gulp.src(config.src.styles.toolkit)
		.pipe(sourcemaps.init())
		.pipe(sass().on('error', sass.logError))
		.pipe(prefix('last 1 version'))
		.pipe(sourcemaps.write())
		.pipe(gulp.dest(path.join(config.demo , '/assets/toolkit/styles')))
		.pipe(reload({stream:true}));
});

gulp.task('demo:styles', ['demo:styles:fabricator', 'demo:styles:toolkit']);

// scripts
gulp.task('demo:scripts', function (done) {
	demoWebpackCompiler.run(function (error, result) {
		if (error) {
			gutil.log(gutil.colors.red(error));
		}
		result = result.toJson();
		if (result.errors.length) {
			result.errors.forEach(function (error) {
				gutil.log(gutil.colors.red(error));
			});
		}
		done();
	});
});

// images
gulp.task('demo:images', ['demo:favicon'], function () {
	return gulp.src(config.src.images)
		.pipe(imagemin())
		.pipe(gulp.dest(path.join(config.demo , '/assets/toolkit/img')));
});

gulp.task('demo:favicon', function () {
	return gulp.src('./docs/demo/favicon.ico')
		.pipe(gulp.dest(config.demo));
});

// assemble
gulp.task('demo:assemble', function (done) {
	assemble({
		layouts: 'docs/demo/views/layouts/*',
		layoutIncludes: 'docs/demo/views/layouts/includes/*',
		views: ['docs/demo/views/**/*','!docs/demo/views/+(layouts)/**'],
		materials: 'docs/demo/materials/**/*',
		data: 'docs/demo/data/**/*.{json,yml}',
		docs: ['docs/**/*.md', '!docs/BOWER-README.md'],
		logErrors: true,
		dest: config.demo
	});
	done();
});

// server
gulp.task('demo:serve', function () {

	browserSync({
		server: {
			baseDir: config.demo
		},
		notify: false,
		logPrefix: 'FABRICATOR'
	});

	/**
	 * Because webpackCompiler.watch() isn't being used
	 * manually remove the changed file path from the cache
	 */
	function webpackCache(e) {
		var keys = Object.keys(demoWebpackConfig.cache);
		var key, matchedKey;
		for (var keyIndex = 0; keyIndex < keys.length; keyIndex++) {
			key = keys[keyIndex];
			if (key.indexOf(e.path) !== -1) {
				matchedKey = key;
				break;
			}
		}
		if (matchedKey) {
			delete demoWebpackConfig.cache[matchedKey];
		}
	}

	gulp.task('demo:assemble:watch', ['demo:assemble'], reload);
	gulp.watch('docs/{demo,guides}/**/*.{html,md,json,yml}', ['demo:assemble:watch']);

	gulp.task('demo:styles:fabricator:watch', ['demo:styles:fabricator']);
	gulp.watch('docs/demo/assets/fabricator/styles/**/*.scss', ['demo:styles:fabricator:watch']);

	gulp.task('demo:styles:toolkit:watch', ['demo:styles:toolkit']);
	gulp.watch('src/styles/**/*.scss', ['demo:styles:toolkit:watch']);

	gulp.task('demo:scripts:watch', ['demo:scripts'], reload);
	gulp.watch('docs/demo/assets/fabricator/scripts/**/*.js', ['demo:scripts:watch']).on('change', webpackCache);

	gulp.task('demo:images:watch', ['demo:images'], reload);
	gulp.watch(config.src.images, ['demo:images:watch']);

});

gulp.task('demo:deploy', ['demo'],  function() {
  return gulp.src(path.join(config.demo , '/**/*'))
    .pipe(ghPages({remoteUrl: 'https://github.com/zalando/brand-solutions-dress-code.git'}));
});

/**
 *
 *
 *
 *  DISTRIBUTION TASKS
 *
 *
 *
 */

gulp.task('dist', function (cb) {
	runSequence('dist:clean',['dist:styles', 'dist:styles:src', 'dist:images'], cb);
});

gulp.task('dist:clean', function (cb) {
	del([config.dist], cb);
});

gulp.task('dist:styles', function () {
	return gulp.src(config.src.styles.toolkit)
		.pipe(sass().on('error', sass.logError))
		.pipe(sourcemaps.init())
		.pipe(prefix('last 1 version'))
		.pipe(sourcemaps.write())
		.pipe(rename(pkg.name + '.css'))
		.pipe(gulp.dest(path.join(config.dist, 'css')))
		 // minified
		.pipe(rename(pkg.name + '.min.css'))
		.pipe(csso())
		.pipe(gulp.dest(path.join(config.dist, 'css')));
});

gulp.task('dist:styles:src', function () {
	return gulp.src(path.join(config.path.styles.toolkit, '/**/*'))
		.pipe(gulp.dest(path.join(config.dist, 'sass')));
});

gulp.task('dist:images', function () {
	return gulp.src(config.src.images)
		.pipe(imagemin())
		.pipe(gulp.dest(path.join(config.dist, '/img')));
});

gulp.task('dist:bower:clean', function (cb) {
	del([config.distBower], cb);
});

gulp.task('dist:bower', ['dist:bower:clean','dist'], function () {
	var bowerReadmeFilter = gulpFilter(['BOWER-README.md'], { restore: true });
    var importFilter = gulpFilter(['**/sass/_import.scss','**/sass/_base.scss'], { restore: true })

    return gulp.src([
		path.join(config.dist, '/**/*'),
		'bower.json',
		'LICENSE',
		'docs/BOWER-README.md',
		'.editorconfig'
	])
    .pipe(bowerReadmeFilter)
    .pipe(rename('README.md'))
	.pipe(gulp.dest(config.distBower))
    .pipe(bowerReadmeFilter.restore)
	.pipe(importFilter)
	.pipe(replace(/@import "..\/..\/node_modules\/(.*)"/g, function (match, p1) {
		if(p1.indexOf('breakpoint-sass') > -1) {
			return '@import "../../compass-breakpoint/stylesheets/breakpoint"';
		}else{
			return '@import "../../' + p1 + '"';
		}
	}))
    .pipe(importFilter.restore)
	.pipe(gulp.dest(config.distBower));
});

gulp.task('dist:bower:deploy', ['dist:bower'], function () {
	return gulp.src(path.join(config.distBower , '/**/*'))
		.pipe(ghPages({
			cacheDir: '.publish-bower',
			branch: 'master',
			remoteUrl: 'git@github.com:zalando/brand-solutions-dress-code-bower'
		}));
});

/**
 *
 *
 *
 * DEFAULT TASK
 *
 *
 *
 */
gulp.task('default', function () {
	// run demo
	runSequence('demo', function () {
		gulp.start('demo:serve');
	});
});
<|endoftext|>


<commit_before><commit_msg>Lists interface.<commit_after>'use strict';

module.exports = Lists;

function Lists () {
	//
};

Lists.prototype.getAll = () => {
	//
};

Lists.prototype.getDetails = () => {
	//
};

Lists.prototype.addList = () => {
	//
};

Lists.prototype.updateList = () => {
	//
};

Lists.prototype.removeList = () => {
	//
};

Lists.prototype.getActiveSubscribers = () => {
	//
};

Lists.prototype.getBouncedSubscribers = () => {
	//
};
<|endoftext|>