<commit_before>/**
 * use sass
 */

var path = require('path');
var url = require('url');

fis.config.set('project.exclude', [
    '**/_*.scss',
    '*/node_modules/**',
    'Makefile',
    'build.sh',
    'README.md',
    'trigger.js',
    'changelog/**'
]);

fis.config.set('modules.parser.scss', 'sass'); //启用fis-parser-sass插件
fis.config.set('roadmap.ext.scss', 'css'); //scss文件编译后产出为css文件
fis.config.set('framework', '{%FRAMEWORK%}');
fis.config.set('roadmap.domain', '{%DOMAIN%}');
fis.config.set('macro', {
    'namespace': '{%FRAMEWORK%}',
    'class-warning': 'bs-callout bs-callout-warning',
    'class-danger': 'bs-callout bs-callout-danger',
    'class-info': 'bs-callout bs-callout-info'
});

fis.config.set('roadmap.path', [{
    reg: '*\.min\.(?:js|css)$',
    useOptimizer: false,
    release: '/static/${framework}/$&'
}, {
    reg: '**/_Sidebar.md',
    isNav: true
}, {
    reg: '**.md'
}, {
    reg: '/pages/${framework}/document.html',
    release: '/document.html',
    isDocumentPage: true
}, {
    // pages下的所有结构移至根目录
    reg: new RegExp('^\\/pages\\/' + fis.config.get('framework') + '\\/(.*\\.html)$'),
    release: '/$1'
}, {
    // 所有pages/,static/,widget/下的结构都相同，为./[repo-name]/[dirs/files]
    reg: new RegExp('^\\/(.*)\\/' + fis.config.get('framework') + '\\/(.*)$'),
    release: '/$1/$2'
}, {
    reg: 'lib/**'
}, {
    reg: 'map.json'
}, {
    reg: '**',
    // release: '/static/${framework}/$&'
    release: '/obsolete/$&'
}]);

fis.config.set('settings.parser.sass', {
    'include_paths': [__dirname, path.join(__dirname, 'lib', 'bootstrap', 'stylesheets')]
});

// 获取导航需要编译加`-c`或者`-u`，因为我偷懒了，没有处理缓存
var gLinks = {};
var gNavRef = [];
fis.config.set('roadmap.ext.md', 'html');

fis.config.set('modules.parser.md', [function(content, file, conf) {
        var include_reg = /||$)/ig;
        var processed = [];

        function _process(content, file) {
            processed[file.realpath] = true;
            return content.replace(include_reg, function(all, $1) {
                if ($1) {
                    var f = fis.file(path.join(file.dirname, $1));
                    if (processed.indexOf(f.realpath) == -1) {
                        return _process(f.getContent(), f);
                    }
                    return f.getContent();
                }
                return all;
            });
        }
        return _process(content, file);
    },
    function(content, file, conf) {
        var marked = require('marked');
        var renderer = new marked.Renderer();
        var navs = [];
        var links = [];

        renderer.heading = function(text, level) {
            var link = {};
            link.text = text;
            link.level = level;
            var escapedText = text;

            links.push(link);

            if (level != 1) level += 1;
            return '<h' + level + ' class="' + (level == 1 ? 'page-header' : '') +
                (level == 3 ? '" id="' + text : '') +
                '">' +
                text + '</h' + level + '>';
        };

        renderer.link = function(href, title, text) {
            if (file.isNav) {
                var info = url.parse(href);
                if (!~navs.indexOf(info.pathname)) {
                    //check file exist?
                    var refFile = fis.file(file.dirname + '/' + info.pathname + '.md');
                    gNavRef.push(refFile.toString());
                    navs.push(info.pathname);
                }
                return;
            }

            var out = '<a href="' + href + '"';

            if (href.indexOf('#') != -1 && href.indexOf('http') != 0) {
                out = '' + text + '';
            return out;
        };

        marked.setOptions({
            renderer: renderer,
            highlight: function(code) {
                return require('highlight.js').highlightAuto(code).value;
            },
            langPrefix: 'hljs lang-',
            gfm: true,
            tables: true,
            breaks: false,
            pedantic: false,
            sanitize: false,
            smartLists: true,
            smartypants: false
        });

        content = marked(content);

        gLinks[file.realpath] = links;

        if (file.isNav) {
            return navs.map(function(path) {
                return '

';
            }).join('\n');
        }
        return content;
    }
]);

function getLinksHtml(links) {
    var ret = '';
    var flag = false;
    var levels = [];
    links.forEach(function(link) {
        if (link.level == 1) {
            if (flag) {
                ret += '

';
            }
            flag = true;
            ret += '
' + link.text + '
';
        } else if (link.level == 2) {
            ret += '
' + link.text + '';
        }
    });
    ret += '

';
    return ret;
}

fis.config.set('modules.postpackager', [function(ret, settings, conf, opt) {
    fis.util.map(ret.src, function(subpath, file) {
        if (file.isDocumentPage) {
            var useLinks = [];
            fis.util.map(gLinks, function(realpath, links) {
                if (gNavRef.indexOf(realpath) != -1) {
                    useLinks = useLinks.concat(links);
                }
            });
            console.log(useLinks);
            file.setContent(file.getContent().replace('<document_links>', getLinksHtml(useLinks)));
            gLinks = []; //reset
        }
        if (file.isHtmlLike) {
            var macro = fis.config.get('macro');
            var content = file.getContent();
            fis.util.map(macro, function(key, value) {
                content = content.replace(new RegExp('<#' + key + '#>', 'g'), function(all) {
                    return value;
                });
            });
            file.setContent(content);
        }
    });
},
'simple' //pack
]);

fis.config.set('settings.postpackager.simple.autoCombine', true);
fis.config.set('settings.postpackager.simple.autoReflow', true);
<commit_msg>无关文件不再排除<commit_after>/**
 * use sass
 */

var path = require('path');
var url = require('url');

fis.config.set('project.exclude', [
    '**/_*.scss',
    '*/node_modules/**',
    'Makefile',
    'build.sh',
    'README.md',
    'trigger.js',
    'changelog/**'
]);

fis.config.set('modules.parser.scss', 'sass'); //启用fis-parser-sass插件
fis.config.set('roadmap.ext.scss', 'css'); //scss文件编译后产出为css文件
fis.config.set('framework', '{%FRAMEWORK%}');
fis.config.set('roadmap.domain', '{%DOMAIN%}');
fis.config.set('macro', {
    'namespace': '{%FRAMEWORK%}',
    'class-warning': 'bs-callout bs-callout-warning',
    'class-danger': 'bs-callout bs-callout-danger',
    'class-info': 'bs-callout bs-callout-info'
});

fis.config.set('roadmap.path', [{
    reg: '*\.min\.(?:js|css)$',
    useOptimizer: false,
    release: '/static/${framework}/$&'
}, {
    reg: '**/_Sidebar.md',
    isNav: true
}, {
    reg: '**.md'
}, {
    reg: '/pages/${framework}/document.html',
    release: '/document.html',
    isDocumentPage: true
}, {
    // pages下的所有结构移至根目录
    reg: new RegExp('^\\/pages\\/' + fis.config.get('framework') + '\\/(.*\\.html)$'),
    release: '/$1'
}, {
    // 所有pages/,static/,widget/下的结构都相同，为./[repo-name]/[dirs/files]
    reg: new RegExp('^\\/(.*)\\/' + fis.config.get('framework') + '\\/(.*)$'),
    release: '/$1/$2'
}, {
    reg: 'lib/**'
}, {
    reg: 'map.json'
}, {
    reg: '**',
    release: '/static/${framework}/$&'
    // release: '/static/$&'
}]);

fis.config.set('settings.parser.sass', {
    'include_paths': [__dirname, path.join(__dirname, 'lib', 'bootstrap', 'stylesheets')]
});

// 获取导航需要编译加`-c`或者`-u`，因为我偷懒了，没有处理缓存
var gLinks = {};
var gNavRef = [];
fis.config.set('roadmap.ext.md', 'html');

fis.config.set('modules.parser.md', [function(content, file, conf) {
        var include_reg = /||$)/ig;
        var processed = [];

        function _process(content, file) {
            processed[file.realpath] = true;
            return content.replace(include_reg, function(all, $1) {
                if ($1) {
                    var f = fis.file(path.join(file.dirname, $1));
                    if (processed.indexOf(f.realpath) == -1) {
                        return _process(f.getContent(), f);
                    }
                    return f.getContent();
                }
                return all;
            });
        }
        return _process(content, file);
    },
    function(content, file, conf) {
        var marked = require('marked');
        var renderer = new marked.Renderer();
        var navs = [];
        var links = [];

        renderer.heading = function(text, level) {
            var link = {};
            link.text = text;
            link.level = level;
            var escapedText = text;

            links.push(link);

            if (level != 1) level += 1;
            return '<h' + level + ' class="' + (level == 1 ? 'page-header' : '') +
                (level == 3 ? '" id="' + text : '') +
                '">' +
                text + '</h' + level + '>';
        };

        renderer.link = function(href, title, text) {
            if (file.isNav) {
                var info = url.parse(href);
                if (!~navs.indexOf(info.pathname)) {
                    //check file exist?
                    var refFile = fis.file(file.dirname + '/' + info.pathname + '.md');
                    gNavRef.push(refFile.toString());
                    navs.push(info.pathname);
                }
                return;
            }

            var out = '<a href="' + href + '"';

            if (href.indexOf('#') != -1 && href.indexOf('http') != 0) {
                out = '' + text + '';
            return out;
        };

        marked.setOptions({
            renderer: renderer,
            highlight: function(code) {
                return require('highlight.js').highlightAuto(code).value;
            },
            langPrefix: 'hljs lang-',
            gfm: true,
            tables: true,
            breaks: false,
            pedantic: false,
            sanitize: false,
            smartLists: true,
            smartypants: false
        });

        content = marked(content);

        gLinks[file.realpath] = links;

        if (file.isNav) {
            return navs.map(function(path) {
                return '

';
            }).join('\n');
        }
        return content;
    }
]);

function getLinksHtml(links) {
    var ret = '';
    var flag = false;
    var levels = [];
    links.forEach(function(link) {
        if (link.level == 1) {
            if (flag) {
                ret += '

';
            }
            flag = true;
            ret += '
' + link.text + '
';
        } else if (link.level == 2) {
            ret += '
' + link.text + '';
        }
    });
    ret += '

';
    return ret;
}

fis.config.set('modules.postpackager', [function(ret, settings, conf, opt) {
    fis.util.map(ret.src, function(subpath, file) {
        if (file.isDocumentPage) {
            var useLinks = [];
            fis.util.map(gLinks, function(realpath, links) {
                if (gNavRef.indexOf(realpath) != -1) {
                    useLinks = useLinks.concat(links);
                }
            });
            console.log(useLinks);
            file.setContent(file.getContent().replace('<document_links>', getLinksHtml(useLinks)));
            gLinks = []; //reset
        }
        if (file.isHtmlLike) {
            var macro = fis.config.get('macro');
            var content = file.getContent();
            fis.util.map(macro, function(key, value) {
                content = content.replace(new RegExp('<#' + key + '#>', 'g'), function(all) {
                    return value;
                });
            });
            file.setContent(content);
        }
    });
},
'simple' //pack
]);

fis.config.set('settings.postpackager.simple.autoCombine', true);
fis.config.set('settings.postpackager.simple.autoReflow', true);
<|endoftext|>


<commit_before>var Engine = require('engine-components/Engine');
var ValueEngineUnit = require('value/ValueEngineUnit');
var ChangesEngineUnit = require('changes/ChangesEngineUnit');

var engine = Engine();
engine.addEngineUnit(new ValueEngineUnit());

module.exports = require('engine-components/LiveResource');<commit_msg>Had forgotten to add changes engine unit to the engine<commit_after>var Engine = require('engine-components/Engine');
var ValueEngineUnit = require('value/ValueEngineUnit');
var ChangesEngineUnit = require('changes/ChangesEngineUnit');

var engine = Engine();
engine.addEngineUnit(new ValueEngineUnit());
engine.addEngineUnit(new ChangesEngineUnit());

module.exports = require('engine-components/LiveResource');<|endoftext|>


<commit_before>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Timer so that other modules can run timing related code through the simulation's requestAnimationFrame.
 * Note: this is not specific to the running screen, it is global across all screens.
 *
 * @author Sam Reid
 */
define( function() {
  'use strict';
  var listeners = [];
  var listenersDefensiveCopy = []; // separated out to prevent garbage collection issues
  return {

    //Trigger a step event, called by Sim.js in the animation loop
    step: function( dt ) {
      var length = listeners.length;
      var i;

      // to safely allow listeners to remove themselves while being called (as is explicitly done in setTimeout), we make a copy of the array.
      // we don't use slice(), since that would cause garbage collection issues.
      for ( i = 0; i < length; i++ ) {
        listenersDefensiveCopy[i] = listeners[i];
      }
      for ( i = 0; i < length; i++ ) {
        listenersDefensiveCopy[i]( dt );
      }
      listenersDefensiveCopy.length = 0;
    },

    //Add a listener to be called back once after the specified time (in milliseconds)
    setTimeout: function( listener, timeout ) {
      var elapsed = 0;
      var timer = this;
      var callback = function( dt ) {
        elapsed += dt;

        //Convert seconds to ms and see if item has timed out
        if ( elapsed * 1000 >= timeout ) {
          listener();
          timer.removeStepListener( callback );
        }
      };
      this.addStepListener( callback );

      //Return the callback so it can be removed with removeStepListener
      return callback;
    },

    //Clear a scheduled timeout
    clearTimeout: function( timeoutID ) { this.removeStepListener( timeoutID ); },

    //Add a listener to be called at specified intervals (in milliseconds)
    setInterval: function( listener, interval ) {
      var elapsed = 0;
      var callback = function( dt ) {
        elapsed += dt;

        //Convert seconds to ms and see if item has timed out
        if ( elapsed * 1000 >= interval ) {
          listener();
          elapsed = elapsed - interval / 1000.0;//Save the leftover time so it won't accumulate
        }
      };
      this.addStepListener( callback );

      //Return the callback so it can be removed with removeStepListener
      return callback;
    },

    //Clear a scheduled interval
    clearInterval: function( intervalID ) { this.removeStepListener( intervalID ); },

    //Add a listener to be called back on every animationFrame with a dt value
    addStepListener: function( listener ) { listeners.push( listener ); },

    //Remove a step listener from being called back
    removeStepListener: function( listener ) {
      var index = listeners.indexOf( listener );
      if ( index !== -1 ) {
        listeners.splice( index, 1 );
      }
    }
  };
} );
<commit_msg>cleanArray usage<commit_after>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Timer so that other modules can run timing related code through the simulation's requestAnimationFrame.
 * Note: this is not specific to the running screen, it is global across all screens.
 *
 * @author Sam Reid
 */
define( function() {
  'use strict';

  var cleanArray = require( 'PHET_CORE/cleanArray' );

  var listeners = [];
  var listenersDefensiveCopy = []; // separated out to prevent garbage collection issues
  return {

    //Trigger a step event, called by Sim.js in the animation loop
    step: function( dt ) {
      var length = listeners.length;
      var i;

      // to safely allow listeners to remove themselves while being called (as is explicitly done in setTimeout), we make a copy of the array.
      // we don't use slice(), since that would cause garbage collection issues.
      for ( i = 0; i < length; i++ ) {
        listenersDefensiveCopy[i] = listeners[i];
      }
      for ( i = 0; i < length; i++ ) {
        listenersDefensiveCopy[i]( dt );
      }
      cleanArray( listenersDefensiveCopy );
    },

    //Add a listener to be called back once after the specified time (in milliseconds)
    setTimeout: function( listener, timeout ) {
      var elapsed = 0;
      var timer = this;
      var callback = function( dt ) {
        elapsed += dt;

        //Convert seconds to ms and see if item has timed out
        if ( elapsed * 1000 >= timeout ) {
          listener();
          timer.removeStepListener( callback );
        }
      };
      this.addStepListener( callback );

      //Return the callback so it can be removed with removeStepListener
      return callback;
    },

    //Clear a scheduled timeout
    clearTimeout: function( timeoutID ) { this.removeStepListener( timeoutID ); },

    //Add a listener to be called at specified intervals (in milliseconds)
    setInterval: function( listener, interval ) {
      var elapsed = 0;
      var callback = function( dt ) {
        elapsed += dt;

        //Convert seconds to ms and see if item has timed out
        if ( elapsed * 1000 >= interval ) {
          listener();
          elapsed = elapsed - interval / 1000.0;//Save the leftover time so it won't accumulate
        }
      };
      this.addStepListener( callback );

      //Return the callback so it can be removed with removeStepListener
      return callback;
    },

    //Clear a scheduled interval
    clearInterval: function( intervalID ) { this.removeStepListener( intervalID ); },

    //Add a listener to be called back on every animationFrame with a dt value
    addStepListener: function( listener ) { listeners.push( listener ); },

    //Remove a step listener from being called back
    removeStepListener: function( listener ) {
      var index = listeners.indexOf( listener );
      if ( index !== -1 ) {
        listeners.splice( index, 1 );
      }
    }
  };
} );
<|endoftext|>


<commit_before>'use strict';

var del = require('del');

var gulp = require('gulp-help')(require('gulp'));
var babel = require('gulp-babel');

// `gulp build`
// -----------------------------------------------------------------------------
gulp.task('build',
  'Compile everything.',
  ['scripts']
);

// `gulp scripts`
// -----------------------------------------------------------------------------
var scripts = {
  source: 'source/**/*.js',
  target: '.'
};

gulp.task('scripts',
  'Compile scripts to ES5.',
  ['scripts:clean'],
  function() {
    return gulp.src(scripts.source)
      .pipe(babel())
      .pipe(gulp.dest(scripts.target))
    ;
  }
);

gulp.task('scripts:clean', false, function(done) {
  del(scripts.target + '/*.{js,js.map}', done);
});

// `gulp clean`
// -----------------------------------------------------------------------------
gulp.task('clean',
  'Remove all built files.',
  ['scripts:clean']
);
<commit_msg>Fix `gulp clean`<commit_after>'use strict';

var del = require('del');

var gulp = require('gulp-help')(require('gulp'));
var babel = require('gulp-babel');

// `gulp build`
// -----------------------------------------------------------------------------
gulp.task('build',
  'Compile everything.',
  ['scripts']
);

// `gulp scripts`
// -----------------------------------------------------------------------------
var scripts = {
  source: 'source/**/*.js',
  target: '.'
};

gulp.task('scripts',
  'Compile scripts to ES5.',
  ['scripts:clean'],
  function() {
    return gulp.src(scripts.source)
      .pipe(babel())
      .pipe(gulp.dest(scripts.target))
    ;
  }
);

gulp.task('scripts:clean', false, function(done) {
  del([
    scripts.target + '/index.{js,js.map}'
  ], done);
});

// `gulp clean`
// -----------------------------------------------------------------------------
gulp.task('clean',
  'Remove all built files.',
  ['scripts:clean']
);
<|endoftext|>


<commit_before>'use strict';

var inherits = require('inherits');

var PropertiesActivator = require('../../PropertiesActivator');

var asyncCapableHelper = require('../../helper/AsyncCapableHelper'),
    ImplementationTypeHelper = require('../../helper/ImplementationTypeHelper');

var is = require('bpmn-js/lib/util/ModelUtil').is;

// bpmn properties
var processProps = require('../bpmn/parts/ProcessProps'),
    eventProps = require('../bpmn/parts/EventProps'),
    linkProps = require('../bpmn/parts/LinkProps'),
    documentationProps = require('../bpmn/parts/DocumentationProps'),
    idProps = require('../bpmn/parts/IdProps'),
    nameProps = require('../bpmn/parts/NameProps'),
    executableProps = require('../bpmn/parts/ExecutableProps');

// camunda properties
var serviceTaskDelegateProps = require('./parts/ServiceTaskDelegateProps'),
    userTaskProps = require('./parts/UserTaskProps'),
    asynchronousContinuationProps = require('./parts/AsynchronousContinuationProps'),
    callActivityProps = require('./parts/CallActivityProps'),
    multiInstanceProps = require('./parts/MultiInstanceLoopProps'),
    conditionalProps = require('./parts/ConditionalProps'),
    scriptProps = require('./parts/ScriptTaskProps'),
    formProps = require('./parts/FormProps'),
    startEventInitiator = require('./parts/StartEventInitiator'),
    variableMapping = require('./parts/VariableMappingProps'),
    versionTag = require('./parts/VersionTagProps');

var listenerProps = require('./parts/ListenerProps'),
    listenerDetails = require('./parts/ListenerDetailProps'),
    listenerFields = require('./parts/ListenerFieldInjectionProps');

var elementTemplateChooserProps = require('./element-templates/parts/ChooserProps'),
    elementTemplateCustomProps = require('./element-templates/parts/CustomProps');

// Input/Output
var inputOutput = require('./parts/InputOutputProps'),
    inputOutputParameter = require('./parts/InputOutputParameterProps');

// Connector
var connectorDetails = require('./parts/ConnectorDetailProps'),
    connectorInputOutput = require('./parts/ConnectorInputOutputProps'),
    connectorInputOutputParameter = require('./parts/ConnectorInputOutputParameterProps');

// properties
var properties = require('./parts/PropertiesProps');

// job configuration
var jobConfiguration = require('./parts/JobConfigurationProps');

// history time to live
var historyTimeToLive = require('./parts/HistoryTimeToLiveProps');

// candidate starter groups/users
var candidateStarter = require('./parts/CandidateStarterProps');

// tasklist
var tasklist = require('./parts/TasklistProps');

// external task configuration
var externalTaskConfiguration = require('./parts/ExternalTaskConfigurationProps');

// field injection
var fieldInjections = require('./parts/FieldInjectionProps');

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    eventDefinitionHelper = require('../../helper/EventDefinitionHelper'),
    implementationTypeHelper = require('../../helper/ImplementationTypeHelper');

// helpers ////////////////////////////////////////

var isExternalTaskPriorityEnabled = function(element) {
  var businessObject = getBusinessObject(element);

  // show only if element is a process, a participant ...
  if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
    return true;
  }

  var externalBo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element),
      isExternalTask = ImplementationTypeHelper.getImplementationType(externalBo) === 'external';

  // ... or an external task with selected external implementation type
  return !!ImplementationTypeHelper.isExternalCapable(externalBo) && isExternalTask;
};

var isJobConfigEnabled = function(element) {
  var businessObject = getBusinessObject(element);

  if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
    return true;
  }

  // async behavior
  var bo = getBusinessObject(element);
  if (asyncCapableHelper.isAsyncBefore(bo) || asyncCapableHelper.isAsyncAfter(bo)) {
    return true;
  }

  // timer definition
  if (is(element, 'bpmn:Event')) {
    return !!eventDefinitionHelper.getTimerEventDefinition(element);
  }

  return false;
};

var getInputOutputParameterLabel = function(param, translate) {

  if (is(param, 'camunda:InputParameter')) {
    return translate('Input Parameter');
  }

  if (is(param, 'camunda:OutputParameter')) {
    return translate('Output Parameter');
  }

  return '';
};

var getListenerLabel = function(param, translate) {

  if (is(param, 'camunda:ExecutionListener')) {
    return translate('Execution Listener');
  }

  if (is(param, 'camunda:TaskListener')) {
    return translate('Task Listener');
  }

  return '';
};

var PROCESS_KEY_HINT = 'This maps to the process definition key.';

function createGeneralTabGroups(element, bpmnFactory, elementRegistry, elementTemplates, translate) {

  // refer to target element for external labels
  element = element.labelTarget || element;

  var generalGroup = {
    id: 'general',
    label: translate('General'),
    entries: []
  };

  var idOptions;
  var processOptions;

  if (is(element, 'bpmn:Process')) {
    idOptions = { description: PROCESS_KEY_HINT };
  }

  if (is(element, 'bpmn:Participant')) {
    processOptions = { processIdDescription: PROCESS_KEY_HINT };
  }

  idProps(generalGroup, element, translate, idOptions);
  nameProps(generalGroup, element, translate);
  processProps(generalGroup, element, translate, processOptions);
  versionTag(generalGroup, element, translate);
  executableProps(generalGroup, element, translate);
  elementTemplateChooserProps(generalGroup, element, elementTemplates, translate);

  var customFieldsGroups = elementTemplateCustomProps(element, elementTemplates, bpmnFactory, translate);

  var detailsGroup = {
    id: 'details',
    label: translate('Details'),
    entries: []
  };
  serviceTaskDelegateProps(detailsGroup, element, bpmnFactory, translate);
  userTaskProps(detailsGroup, element, translate);
  scriptProps(detailsGroup, element, bpmnFactory, translate);
  linkProps(detailsGroup, element, translate);
  callActivityProps(detailsGroup, element, bpmnFactory, translate);
  eventProps(detailsGroup, element, bpmnFactory, elementRegistry, translate);
  conditionalProps(detailsGroup, element, bpmnFactory, translate);
  startEventInitiator(detailsGroup, element, translate); // this must be the last element of the details group!

  var multiInstanceGroup = {
    id: 'multiInstance',
    label: translate('Multi Instance'),
    entries: []
  };
  multiInstanceProps(multiInstanceGroup, element, bpmnFactory, translate);

  var asyncGroup = {
    id : 'async',
    label: translate('Asynchronous Continuations'),
    entries : []
  };
  asynchronousContinuationProps(asyncGroup, element, bpmnFactory, translate);

  var jobConfigurationGroup = {
    id : 'jobConfiguration',
    label : translate('Job Configuration'),
    entries : [],
    enabled: isJobConfigEnabled
  };
  jobConfiguration(jobConfigurationGroup, element, bpmnFactory, translate);

  var externalTaskGroup = {
    id : 'externalTaskConfiguration',
    label : translate('External Task Configuration'),
    entries : [],
    enabled: isExternalTaskPriorityEnabled
  };
  externalTaskConfiguration(externalTaskGroup, element, bpmnFactory, translate);

  var candidateStarterGroup = {
    id: 'candidateStarterConfiguration',
    label: translate('Candidate Starter Configuration'),
    entries: []
  };
  candidateStarter(candidateStarterGroup, element, bpmnFactory, translate);

  var historyTimeToLiveGroup = {
    id: 'historyConfiguration',
    label: translate('History Configuration'),
    entries: []
  };
  historyTimeToLive(historyTimeToLiveGroup, element, bpmnFactory, translate);

  var tasklistGroup = {
    id: 'tasklist',
    label: translate('Tasklist Configuration'),
    entries: []
  };
  tasklist(tasklistGroup, element, bpmnFactory, translate);

  var documentationGroup = {
    id: 'documentation',
    label: translate('Documentation'),
    entries: []
  };
  documentationProps(documentationGroup, element, bpmnFactory, translate);

  var groups = [];
  groups.push(generalGroup);
  customFieldsGroups.forEach(function(group) {
    groups.push(group);
  });
  groups.push(detailsGroup);
  groups.push(externalTaskGroup);
  groups.push(multiInstanceGroup);
  groups.push(asyncGroup);
  groups.push(jobConfigurationGroup);
  groups.push(candidateStarterGroup);
  groups.push(historyTimeToLiveGroup);
  groups.push(tasklistGroup);
  groups.push(documentationGroup);

  return groups;
}

function createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate) {
  var variablesGroup = {
    id : 'variables',
    label : translate('Variables'),
    entries: []
  };
  variableMapping(variablesGroup, element, bpmnFactory, translate);

  return [
    variablesGroup
  ];
}

function createFormsTabGroups(element, bpmnFactory, elementRegistry, translate) {
  var formGroup = {
    id : 'forms',
    label : translate('Forms'),
    entries: []
  };
  formProps(formGroup, element, bpmnFactory, translate);

  return [
    formGroup
  ];
}

function createListenersTabGroups(element, bpmnFactory, elementRegistry, translate) {

  var listenersGroup = {
    id : 'listeners',
    label: translate('Listeners'),
    entries: []
  };

  var options = listenerProps(listenersGroup, element, bpmnFactory, translate);

  var listenerDetailsGroup = {
    id: 'listener-details',
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedListener(element, node);
    },
    label: function(element, node) {
      var param = options.getSelectedListener(element, node);
      return getListenerLabel(param, translate);
    }
  };

  listenerDetails(listenerDetailsGroup, element, bpmnFactory, options, translate);

  var listenerFieldsGroup = {
    id: 'listener-fields',
    label: translate('Field Injection'),
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedListener(element, node);
    }
  };

  listenerFields(listenerFieldsGroup, element, bpmnFactory, options, translate);

  return [
    listenersGroup,
    listenerDetailsGroup,
    listenerFieldsGroup
  ];
}

function createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate) {

  var inputOutputGroup = {
    id: 'input-output',
    label: translate('Parameters'),
    entries: []
  };

  var options = inputOutput(inputOutputGroup, element, bpmnFactory, translate);

  var inputOutputParameterGroup = {
    id: 'input-output-parameter',
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedParameter(element, node);
    },
    label: function(element, node) {
      var param = options.getSelectedParameter(element, node);
      return getInputOutputParameterLabel(param, translate);
    }
  };

  inputOutputParameter(inputOutputParameterGroup, element, bpmnFactory, options, translate);

  return [
    inputOutputGroup,
    inputOutputParameterGroup
  ];
}

function createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate) {
  var connectorDetailsGroup = {
    id: 'connector-details',
    label: translate('Details'),
    entries: []
  };

  connectorDetails(connectorDetailsGroup, element, bpmnFactory, translate);

  var connectorInputOutputGroup = {
    id: 'connector-input-output',
    label: translate('Input/Output'),
    entries: []
  };

  var options = connectorInputOutput(connectorInputOutputGroup, element, bpmnFactory, translate);

  var connectorInputOutputParameterGroup = {
    id: 'connector-input-output-parameter',
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedParameter(element, node);
    },
    label: function(element, node) {
      var param = options.getSelectedParameter(element, node);
      return getInputOutputParameterLabel(param, translate);
    }
  };

  connectorInputOutputParameter(connectorInputOutputParameterGroup, element, bpmnFactory, options, translate);

  return [
    connectorDetailsGroup,
    connectorInputOutputGroup,
    connectorInputOutputParameterGroup
  ];
}

function createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate) {

  var fieldGroup = {
    id: 'field-injections-properties',
    label: translate('Field Injections'),
    entries: []
  };

  fieldInjections(fieldGroup, element, bpmnFactory, translate);

  return [
    fieldGroup
  ];
}

function createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate) {

  var propertiesGroup = {
    id : 'extensionElements-properties',
    label: translate('Properties'),
    entries: []
  };
  properties(propertiesGroup, element, bpmnFactory, translate);

  return [
    propertiesGroup
  ];
}

// Camunda Properties Provider /////////////////////////////////////

/**
 * A properties provider for Camunda related properties.
 *
 * @param {EventBus} eventBus
 * @param {BpmnFactory} bpmnFactory
 * @param {ElementRegistry} elementRegistry
 * @param {ElementTemplates} elementTemplates
 */
function CamundaPropertiesProvider(eventBus, bpmnFactory, elementRegistry, elementTemplates, translate) {

  PropertiesActivator.call(this, eventBus);

  this.getTabs = function(element) {

    var generalTab = {
      id: 'general',
      label: translate('General'),
      groups: createGeneralTabGroups(
        element, bpmnFactory,
        elementRegistry, elementTemplates, translate)
    };

    var variablesTab = {
      id: 'variables',
      label: translate('Variables'),
      groups: createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var formsTab = {
      id: 'forms',
      label: translate('Forms'),
      groups: createFormsTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var listenersTab = {
      id: 'listeners',
      label: translate('Listeners'),
      groups: createListenersTabGroups(element, bpmnFactory, elementRegistry, translate),
      enabled: function(element) {
        return !eventDefinitionHelper.getLinkEventDefinition(element)
          || (!is(element, 'bpmn:IntermediateThrowEvent')
          && eventDefinitionHelper.getLinkEventDefinition(element));
      }
    };

    var inputOutputTab = {
      id: 'input-output',
      label: translate('Input/Output'),
      groups: createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var connectorTab = {
      id: 'connector',
      label: translate('Connector'),
      groups: createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate),
      enabled: function(element) {
        var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element);
        return bo && implementationTypeHelper.getImplementationType(bo) === 'connector';
      }
    };

    var fieldInjectionsTab = {
      id: 'field-injections',
      label: translate('Field Injections'),
      groups: createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var extensionsTab = {
      id: 'extensionElements',
      label: translate('Extensions'),
      groups: createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate)
    };

    return [
      generalTab,
      variablesTab,
      connectorTab,
      formsTab,
      listenersTab,
      inputOutputTab,
      fieldInjectionsTab,
      extensionsTab
    ];
  };

}

CamundaPropertiesProvider.$inject = [
  'eventBus',
  'bpmnFactory',
  'elementRegistry',
  'elementTemplates',
  'translate'
];

inherits(CamundaPropertiesProvider, PropertiesActivator);

module.exports = CamundaPropertiesProvider;
<commit_msg>feat(usertask): add hint about task definition key<commit_after>'use strict';

var inherits = require('inherits');

var PropertiesActivator = require('../../PropertiesActivator');

var asyncCapableHelper = require('../../helper/AsyncCapableHelper'),
    ImplementationTypeHelper = require('../../helper/ImplementationTypeHelper');

var is = require('bpmn-js/lib/util/ModelUtil').is;

// bpmn properties
var processProps = require('../bpmn/parts/ProcessProps'),
    eventProps = require('../bpmn/parts/EventProps'),
    linkProps = require('../bpmn/parts/LinkProps'),
    documentationProps = require('../bpmn/parts/DocumentationProps'),
    idProps = require('../bpmn/parts/IdProps'),
    nameProps = require('../bpmn/parts/NameProps'),
    executableProps = require('../bpmn/parts/ExecutableProps');

// camunda properties
var serviceTaskDelegateProps = require('./parts/ServiceTaskDelegateProps'),
    userTaskProps = require('./parts/UserTaskProps'),
    asynchronousContinuationProps = require('./parts/AsynchronousContinuationProps'),
    callActivityProps = require('./parts/CallActivityProps'),
    multiInstanceProps = require('./parts/MultiInstanceLoopProps'),
    conditionalProps = require('./parts/ConditionalProps'),
    scriptProps = require('./parts/ScriptTaskProps'),
    formProps = require('./parts/FormProps'),
    startEventInitiator = require('./parts/StartEventInitiator'),
    variableMapping = require('./parts/VariableMappingProps'),
    versionTag = require('./parts/VersionTagProps');

var listenerProps = require('./parts/ListenerProps'),
    listenerDetails = require('./parts/ListenerDetailProps'),
    listenerFields = require('./parts/ListenerFieldInjectionProps');

var elementTemplateChooserProps = require('./element-templates/parts/ChooserProps'),
    elementTemplateCustomProps = require('./element-templates/parts/CustomProps');

// Input/Output
var inputOutput = require('./parts/InputOutputProps'),
    inputOutputParameter = require('./parts/InputOutputParameterProps');

// Connector
var connectorDetails = require('./parts/ConnectorDetailProps'),
    connectorInputOutput = require('./parts/ConnectorInputOutputProps'),
    connectorInputOutputParameter = require('./parts/ConnectorInputOutputParameterProps');

// properties
var properties = require('./parts/PropertiesProps');

// job configuration
var jobConfiguration = require('./parts/JobConfigurationProps');

// history time to live
var historyTimeToLive = require('./parts/HistoryTimeToLiveProps');

// candidate starter groups/users
var candidateStarter = require('./parts/CandidateStarterProps');

// tasklist
var tasklist = require('./parts/TasklistProps');

// external task configuration
var externalTaskConfiguration = require('./parts/ExternalTaskConfigurationProps');

// field injection
var fieldInjections = require('./parts/FieldInjectionProps');

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    eventDefinitionHelper = require('../../helper/EventDefinitionHelper'),
    implementationTypeHelper = require('../../helper/ImplementationTypeHelper');

// helpers ////////////////////////////////////////

var isExternalTaskPriorityEnabled = function(element) {
  var businessObject = getBusinessObject(element);

  // show only if element is a process, a participant ...
  if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
    return true;
  }

  var externalBo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element),
      isExternalTask = ImplementationTypeHelper.getImplementationType(externalBo) === 'external';

  // ... or an external task with selected external implementation type
  return !!ImplementationTypeHelper.isExternalCapable(externalBo) && isExternalTask;
};

var isJobConfigEnabled = function(element) {
  var businessObject = getBusinessObject(element);

  if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
    return true;
  }

  // async behavior
  var bo = getBusinessObject(element);
  if (asyncCapableHelper.isAsyncBefore(bo) || asyncCapableHelper.isAsyncAfter(bo)) {
    return true;
  }

  // timer definition
  if (is(element, 'bpmn:Event')) {
    return !!eventDefinitionHelper.getTimerEventDefinition(element);
  }

  return false;
};

var getInputOutputParameterLabel = function(param, translate) {

  if (is(param, 'camunda:InputParameter')) {
    return translate('Input Parameter');
  }

  if (is(param, 'camunda:OutputParameter')) {
    return translate('Output Parameter');
  }

  return '';
};

var getListenerLabel = function(param, translate) {

  if (is(param, 'camunda:ExecutionListener')) {
    return translate('Execution Listener');
  }

  if (is(param, 'camunda:TaskListener')) {
    return translate('Task Listener');
  }

  return '';
};

var PROCESS_KEY_HINT = 'This maps to the process definition key.';
var TASK_KEY_HINT = 'This maps to the task definition key.';

function createGeneralTabGroups(element, bpmnFactory, elementRegistry, elementTemplates, translate) {

  // refer to target element for external labels
  element = element.labelTarget || element;

  var generalGroup = {
    id: 'general',
    label: translate('General'),
    entries: []
  };

  var idOptions;
  var processOptions;

  if (is(element, 'bpmn:Process')) {
    idOptions = { description: PROCESS_KEY_HINT };
  }

  if (is(element, 'bpmn:UserTask')) {
    idOptions = { description: TASK_KEY_HINT };
  }

  if (is(element, 'bpmn:Participant')) {
    processOptions = { processIdDescription: PROCESS_KEY_HINT };
  }

  idProps(generalGroup, element, translate, idOptions);
  nameProps(generalGroup, element, translate);
  processProps(generalGroup, element, translate, processOptions);
  versionTag(generalGroup, element, translate);
  executableProps(generalGroup, element, translate);
  elementTemplateChooserProps(generalGroup, element, elementTemplates, translate);

  var customFieldsGroups = elementTemplateCustomProps(element, elementTemplates, bpmnFactory, translate);

  var detailsGroup = {
    id: 'details',
    label: translate('Details'),
    entries: []
  };
  serviceTaskDelegateProps(detailsGroup, element, bpmnFactory, translate);
  userTaskProps(detailsGroup, element, translate);
  scriptProps(detailsGroup, element, bpmnFactory, translate);
  linkProps(detailsGroup, element, translate);
  callActivityProps(detailsGroup, element, bpmnFactory, translate);
  eventProps(detailsGroup, element, bpmnFactory, elementRegistry, translate);
  conditionalProps(detailsGroup, element, bpmnFactory, translate);
  startEventInitiator(detailsGroup, element, translate); // this must be the last element of the details group!

  var multiInstanceGroup = {
    id: 'multiInstance',
    label: translate('Multi Instance'),
    entries: []
  };
  multiInstanceProps(multiInstanceGroup, element, bpmnFactory, translate);

  var asyncGroup = {
    id : 'async',
    label: translate('Asynchronous Continuations'),
    entries : []
  };
  asynchronousContinuationProps(asyncGroup, element, bpmnFactory, translate);

  var jobConfigurationGroup = {
    id : 'jobConfiguration',
    label : translate('Job Configuration'),
    entries : [],
    enabled: isJobConfigEnabled
  };
  jobConfiguration(jobConfigurationGroup, element, bpmnFactory, translate);

  var externalTaskGroup = {
    id : 'externalTaskConfiguration',
    label : translate('External Task Configuration'),
    entries : [],
    enabled: isExternalTaskPriorityEnabled
  };
  externalTaskConfiguration(externalTaskGroup, element, bpmnFactory, translate);

  var candidateStarterGroup = {
    id: 'candidateStarterConfiguration',
    label: translate('Candidate Starter Configuration'),
    entries: []
  };
  candidateStarter(candidateStarterGroup, element, bpmnFactory, translate);

  var historyTimeToLiveGroup = {
    id: 'historyConfiguration',
    label: translate('History Configuration'),
    entries: []
  };
  historyTimeToLive(historyTimeToLiveGroup, element, bpmnFactory, translate);

  var tasklistGroup = {
    id: 'tasklist',
    label: translate('Tasklist Configuration'),
    entries: []
  };
  tasklist(tasklistGroup, element, bpmnFactory, translate);

  var documentationGroup = {
    id: 'documentation',
    label: translate('Documentation'),
    entries: []
  };
  documentationProps(documentationGroup, element, bpmnFactory, translate);

  var groups = [];
  groups.push(generalGroup);
  customFieldsGroups.forEach(function(group) {
    groups.push(group);
  });
  groups.push(detailsGroup);
  groups.push(externalTaskGroup);
  groups.push(multiInstanceGroup);
  groups.push(asyncGroup);
  groups.push(jobConfigurationGroup);
  groups.push(candidateStarterGroup);
  groups.push(historyTimeToLiveGroup);
  groups.push(tasklistGroup);
  groups.push(documentationGroup);

  return groups;
}

function createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate) {
  var variablesGroup = {
    id : 'variables',
    label : translate('Variables'),
    entries: []
  };
  variableMapping(variablesGroup, element, bpmnFactory, translate);

  return [
    variablesGroup
  ];
}

function createFormsTabGroups(element, bpmnFactory, elementRegistry, translate) {
  var formGroup = {
    id : 'forms',
    label : translate('Forms'),
    entries: []
  };
  formProps(formGroup, element, bpmnFactory, translate);

  return [
    formGroup
  ];
}

function createListenersTabGroups(element, bpmnFactory, elementRegistry, translate) {

  var listenersGroup = {
    id : 'listeners',
    label: translate('Listeners'),
    entries: []
  };

  var options = listenerProps(listenersGroup, element, bpmnFactory, translate);

  var listenerDetailsGroup = {
    id: 'listener-details',
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedListener(element, node);
    },
    label: function(element, node) {
      var param = options.getSelectedListener(element, node);
      return getListenerLabel(param, translate);
    }
  };

  listenerDetails(listenerDetailsGroup, element, bpmnFactory, options, translate);

  var listenerFieldsGroup = {
    id: 'listener-fields',
    label: translate('Field Injection'),
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedListener(element, node);
    }
  };

  listenerFields(listenerFieldsGroup, element, bpmnFactory, options, translate);

  return [
    listenersGroup,
    listenerDetailsGroup,
    listenerFieldsGroup
  ];
}

function createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate) {

  var inputOutputGroup = {
    id: 'input-output',
    label: translate('Parameters'),
    entries: []
  };

  var options = inputOutput(inputOutputGroup, element, bpmnFactory, translate);

  var inputOutputParameterGroup = {
    id: 'input-output-parameter',
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedParameter(element, node);
    },
    label: function(element, node) {
      var param = options.getSelectedParameter(element, node);
      return getInputOutputParameterLabel(param, translate);
    }
  };

  inputOutputParameter(inputOutputParameterGroup, element, bpmnFactory, options, translate);

  return [
    inputOutputGroup,
    inputOutputParameterGroup
  ];
}

function createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate) {
  var connectorDetailsGroup = {
    id: 'connector-details',
    label: translate('Details'),
    entries: []
  };

  connectorDetails(connectorDetailsGroup, element, bpmnFactory, translate);

  var connectorInputOutputGroup = {
    id: 'connector-input-output',
    label: translate('Input/Output'),
    entries: []
  };

  var options = connectorInputOutput(connectorInputOutputGroup, element, bpmnFactory, translate);

  var connectorInputOutputParameterGroup = {
    id: 'connector-input-output-parameter',
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedParameter(element, node);
    },
    label: function(element, node) {
      var param = options.getSelectedParameter(element, node);
      return getInputOutputParameterLabel(param, translate);
    }
  };

  connectorInputOutputParameter(connectorInputOutputParameterGroup, element, bpmnFactory, options, translate);

  return [
    connectorDetailsGroup,
    connectorInputOutputGroup,
    connectorInputOutputParameterGroup
  ];
}

function createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate) {

  var fieldGroup = {
    id: 'field-injections-properties',
    label: translate('Field Injections'),
    entries: []
  };

  fieldInjections(fieldGroup, element, bpmnFactory, translate);

  return [
    fieldGroup
  ];
}

function createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate) {

  var propertiesGroup = {
    id : 'extensionElements-properties',
    label: translate('Properties'),
    entries: []
  };
  properties(propertiesGroup, element, bpmnFactory, translate);

  return [
    propertiesGroup
  ];
}

// Camunda Properties Provider /////////////////////////////////////

/**
 * A properties provider for Camunda related properties.
 *
 * @param {EventBus} eventBus
 * @param {BpmnFactory} bpmnFactory
 * @param {ElementRegistry} elementRegistry
 * @param {ElementTemplates} elementTemplates
 */
function CamundaPropertiesProvider(eventBus, bpmnFactory, elementRegistry, elementTemplates, translate) {

  PropertiesActivator.call(this, eventBus);

  this.getTabs = function(element) {

    var generalTab = {
      id: 'general',
      label: translate('General'),
      groups: createGeneralTabGroups(
        element, bpmnFactory,
        elementRegistry, elementTemplates, translate)
    };

    var variablesTab = {
      id: 'variables',
      label: translate('Variables'),
      groups: createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var formsTab = {
      id: 'forms',
      label: translate('Forms'),
      groups: createFormsTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var listenersTab = {
      id: 'listeners',
      label: translate('Listeners'),
      groups: createListenersTabGroups(element, bpmnFactory, elementRegistry, translate),
      enabled: function(element) {
        return !eventDefinitionHelper.getLinkEventDefinition(element)
          || (!is(element, 'bpmn:IntermediateThrowEvent')
          && eventDefinitionHelper.getLinkEventDefinition(element));
      }
    };

    var inputOutputTab = {
      id: 'input-output',
      label: translate('Input/Output'),
      groups: createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var connectorTab = {
      id: 'connector',
      label: translate('Connector'),
      groups: createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate),
      enabled: function(element) {
        var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element);
        return bo && implementationTypeHelper.getImplementationType(bo) === 'connector';
      }
    };

    var fieldInjectionsTab = {
      id: 'field-injections',
      label: translate('Field Injections'),
      groups: createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var extensionsTab = {
      id: 'extensionElements',
      label: translate('Extensions'),
      groups: createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate)
    };

    return [
      generalTab,
      variablesTab,
      connectorTab,
      formsTab,
      listenersTab,
      inputOutputTab,
      fieldInjectionsTab,
      extensionsTab
    ];
  };

}

CamundaPropertiesProvider.$inject = [
  'eventBus',
  'bpmnFactory',
  'elementRegistry',
  'elementTemplates',
  'translate'
];

inherits(CamundaPropertiesProvider, PropertiesActivator);

module.exports = CamundaPropertiesProvider;
<|endoftext|>


<commit_before>const {find, filter, forEach, pluck, propEq} = require('ramda');
const asArray = require('./asArray');
const connect = require('./connect');

module.exports = function (virtualNodes, handleConnectionToOutput = ()=>{}) {
  forEach((virtualAudioNode) =>
    forEach((connection) => {
      if (connection === 'output') {
        return handleConnectionToOutput(virtualAudioNode);
      }

      if (Object.prototype.toString.call(connection) === '[object Object]') {
        const {id, destination} = connection;
        const destinationVirtualAudioNode = find(propEq('id', id))(virtualNodes);

        return connect(virtualAudioNode,
                       destinationVirtualAudioNode.audioNode[destination]);
      }

      const destinationVirtualAudioNode = find(propEq('id', connection))(virtualNodes);

      if (destinationVirtualAudioNode.isCustomVirtualNode) {
        return forEach(connect(virtualAudioNode),
                       pluck('audioNode',
                             filter(propEq('input', 'input'),
                                    destinationVirtualAudioNode.virtualNodes)));
      }

      connect(virtualAudioNode, destinationVirtualAudioNode.audioNode);
    }, asArray(virtualAudioNode.output)), filter(propEq('connected', false),
                                                 virtualNodes));
};
<commit_msg>update for new api<commit_after>const {equals, filter, forEach, keys, pluck, propEq, values} = require('ramda');
const asArray = require('./asArray');
const connect = require('./connect');

const isPlainOldObject = x => equals(Object.prototype.toString.call(x),
                                     '[object Object]');

module.exports = (virtualGraph, handleConnectionToOutput = () => {}) =>
  forEach(id => {
            const virtualNode = virtualGraph[id];
            if (virtualNode.connected) {
              return;
            }
            forEach(output => {
                      if (output === 'output') {
                        return handleConnectionToOutput(virtualNode);
                      }

                      if (isPlainOldObject(output)) {
                        const {id, destination} = output;
                        return connect(virtualNode,
                                       virtualGraph[id].audioNode[destination]);
                      }

                      const destinationVirtualAudioNode = virtualGraph[output];

                      if (destinationVirtualAudioNode.isCustomVirtualNode) {
                        return forEach(connect(virtualNode),
                                       pluck('audioNode',
                                             filter(propEq('input', 'input'),
                                                    values(destinationVirtualAudioNode.virtualNodes))));
                      }

                      connect(virtualNode, destinationVirtualAudioNode.audioNode);
                    },
                    asArray(virtualNode.output));
          },
          keys(virtualGraph));
<|endoftext|>


<commit_before>/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
/*

  The MIT License (MIT)

  Copyright (c) 2007-2013 Einar Lielmanis and contributors.

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation files
  (the "Software"), to deal in the Software without restriction,
  including without limitation the rights to use, copy, modify, merge,
  publish, distribute, sublicense, and/or sell copies of the Software,
  and to permit persons to whom the Software is furnished to do so,
  subject to the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.

 CSS Beautifier
---------------

    Written by Harutyun Amirjanyan, (amirjanyan@gmail.com)

    Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
        http://jsbeautifier.org/

    Usage:
        css_beautify(source_text);
        css_beautify(source_text, options);

    The options are (default in brackets):
        indent_size (4)                   — indentation size,
        indent_char (space)               — character to indent with,
        selector_separator_newline (true) - separate selectors with newline or
                                            not (e.g. "a,\nbr" or "a, br")
        end_with_newline (false)          - end with a newline

    e.g

    css_beautify(css_source_text, {
      'indent_size': 1,
      'indent_char': '\t',
      'selector_separator': ' ',
      'end_with_newline': false,
    });
*/

// http://www.w3.org/TR/CSS21/syndata.html#tokenization
// http://www.w3.org/TR/css3-syntax/

(function () {
    function css_beautify(source_text, options) {
        options = options || {};
        var indentSize = options.indent_size || 4;
        var indentCharacter = options.indent_char || ' ';
        var selectorSeparatorNewline = true;
        if (options.selector_separator_newline != undefined)
            selectorSeparatorNewline = options.selector_separator_newline;
        var endWithNewline = options.end_with_newline || false;

        // compatibility
        if (typeof indentSize === "string") {
            indentSize = parseInt(indentSize, 10);
        }

        // tokenizer
        var whiteRe = /^\s+$/;
        var wordRe = /[\w$\-_]/;

        var pos = -1,
            ch;

        function next() {
            ch = source_text.charAt(++pos);
            return ch;
        }

        function peek() {
            return source_text.charAt(pos + 1);
        }

        function getrow() {
          var test1 = source_text.substr(pos, source_text.indexOf(';') + 1);
          var test2 = source_text.substr(pos, source_text.indexOf('{') + 1);

          if(test1.length > test2.length) {
            return test2;
          } else {
            return test1;
          }
        }

        function eatString(endChar) {
            var start = pos;
            while (next()) {
                if (ch === "\\") {
                    next();
                    next();
                } else if (ch === endChar) {
                    break;
                } else if (ch === "\n") {
                    break;
                }
            }
            return source_text.substring(start, pos + 1);
        }

        function eatWhitespace() {
            var start = pos;
            while (whiteRe.test(peek())) {
                pos++;
            }
            return pos !== start;
        }

        function skipWhitespace() {
            var start = pos;
            do {} while (whiteRe.test(next()));
            return pos !== start + 1;
        }

        function eatComment(singleLine) {
            var start = pos;
            next();
            while (next()) {
                if (ch === "*" && peek() === "/") {
                    pos++;
                    break;
                } else if (singleLine && ch === "\n") {
                    break;
                }
            }

            return source_text.substring(start, pos + 1);
        }

        function lookBack(str) {
            return source_text.substring(pos - str.length, pos).toLowerCase() ===
                str;
        }

        function isCommentOnLine() {
            var endOfLine = source_text.indexOf('\n', pos);
            if (endOfLine === -1) return false;
            var restOfLine = source_text.substring(pos, endOfLine);
            return restOfLine.indexOf('//') !== -1;
        }

        // printer
        var indentString = source_text.match(/^[\r\n]*[\t ]*/)[0];
        var singleIndent = Array(indentSize + 1).join(indentCharacter);
        var indentLevel = 0;

        function indent() {
            indentLevel++;
            indentString += singleIndent;
        }

        function outdent() {
            indentLevel--;
            indentString = indentString.slice(0, -indentSize);
        }

        var print = {};
        print["{"] = function (ch) {
            print.singleSpace();
            output.push(ch);
            print.newLine();
        };
        print["}"] = function (ch) {
            print.newLine();
            output.push(ch);
            print.newLine();
        };

        print._lastCharWhitespace = function () {
            return whiteRe.test(output[output.length - 1]);
        }

        print.newLine = function (keepWhitespace) {
            if (!keepWhitespace) {
                while (print._lastCharWhitespace()) {
                    output.pop();
                }
            }

            if (output.length) {
                output.push('\n');
            }
            if (indentString) {
                output.push(indentString);
            }
        };
        print.singleSpace = function () {
            if (output.length && !print._lastCharWhitespace()) {
                output.push(' ');
            }
        };
        var output = [];
        if (indentString) {
            output.push(indentString);
        }
        /*_____________________--------------------_____________________*/

        var insideRule = false;
        while (true) {
            var isAfterSpace = skipWhitespace();

            if (!ch) {
                break;
            } else if (ch === '/' && peek() === '*') { /* css comment */
                print.newLine();
                output.push(eatComment(), "\n", indentString);
                var header = lookBack("")
                if (header) {
                    print.newLine();
                }
            } else if (ch === '/' && peek() === '/') { // single line comment
                output.push(eatComment(true), indentString);
            } else if (ch === '{') {
                eatWhitespace();
                if (peek() == '}') {
                    next();
                    output.push(" {}");
                } else {
                    indent();
                    print["{"](ch);
                }
            } else if (ch === '}') {
                outdent();
                print["}"](ch);
                insideRule = false;
            } else if (ch === ":") {
                eatWhitespace();
                if(getrow().indexOf("{") !== -1){
                     output.push(ch);
                } else {
                    output.push(ch, " ");
                }
                insideRule = true;
            } else if (ch === '"' || ch === '\'') {
                output.push(eatString(ch));
            } else if (ch === ';') {
                if (isCommentOnLine()) {
                    var beforeComment = eatString('/');
                    var comment = eatComment(true);
                    output.push(beforeComment, comment.substring(1, comment.length - 1), '\n', indentString);
                } else {
                    output.push(ch, '\n', indentString);
                }
            } else if (ch === '(') { // may be a url
                if (lookBack("url")) {
                    output.push(ch);
                    eatWhitespace();
                    if (next()) {
                        if (ch !== ')' && ch !== '"' && ch !== '\'') {
                            output.push(eatString(')'));
                        } else {
                            pos--;
                        }
                    }
                } else {
                    if (isAfterSpace) {
                        print.singleSpace();
                    }
                    output.push(ch);
                    eatWhitespace();
                }
            } else if (ch === ')') {
                output.push(ch);
            } else if (ch === ',') {
                eatWhitespace();
                output.push(ch);
                if (!insideRule && selectorSeparatorNewline) {
                    print.newLine();
                } else {
                    print.singleSpace();
                }
            } else if (ch === ']') {
                output.push(ch);
            } else if (ch === '[' || ch === '=') { // no whitespace before or after
                eatWhitespace();
                output.push(ch);
            } else {
                if (isAfterSpace) {
                    print.singleSpace();
                }

                output.push(ch);
            }
        }

        var sweetCode = output.join('').replace(/[\n ]+$/, '');

        // establish end_with_newline
        var should = endWithNewline;
        var actually = /\n$/.test(sweetCode)
        if (should && !actually)
            sweetCode += "\n";
        else if (!should && actually)
            sweetCode = sweetCode.slice(0, -1);

        return sweetCode;
    }

    if (typeof define === "function") {
        // Add support for require.js
        define(function (require, exports, module) {
            exports.css_beautify = css_beautify;
        });
    } else if (typeof exports !== "undefined") {
        // Add support for CommonJS. Just put this file somewhere on your require.paths
        // and you will be able to `var html_beautify = require("beautify").html_beautify`.
        exports.css_beautify = css_beautify;
    } else if (typeof window !== "undefined") {
        // If we're running a web page and don't have either of the above, add our one global
        window.css_beautify = css_beautify;
    } else if (typeof global !== "undefined") {
        // If we don't even have window, try global.
        global.css_beautify = css_beautify;
    }

}());
<commit_msg>fixed formatting troubles<commit_after>/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
/*

  The MIT License (MIT)

  Copyright (c) 2007-2013 Einar Lielmanis and contributors.

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation files
  (the "Software"), to deal in the Software without restriction,
  including without limitation the rights to use, copy, modify, merge,
  publish, distribute, sublicense, and/or sell copies of the Software,
  and to permit persons to whom the Software is furnished to do so,
  subject to the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.

 CSS Beautifier
---------------

    Written by Harutyun Amirjanyan, (amirjanyan@gmail.com)

    Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
        http://jsbeautifier.org/

    Usage:
        css_beautify(source_text);
        css_beautify(source_text, options);

    The options are (default in brackets):
        indent_size (4)                   — indentation size,
        indent_char (space)               — character to indent with,
        selector_separator_newline (true) - separate selectors with newline or
                                            not (e.g. "a,\nbr" or "a, br")
        end_with_newline (false)          - end with a newline

    e.g

    css_beautify(css_source_text, {
      'indent_size': 1,
      'indent_char': '\t',
      'selector_separator': ' ',
      'end_with_newline': false,
    });
*/

// http://www.w3.org/TR/CSS21/syndata.html#tokenization
// http://www.w3.org/TR/css3-syntax/

(function () {
    function css_beautify(source_text, options) {
        options = options || {};
        var indentSize = options.indent_size || 4;
        var indentCharacter = options.indent_char || ' ';
        var selectorSeparatorNewline = true;
        if (options.selector_separator_newline != undefined)
            selectorSeparatorNewline = options.selector_separator_newline;
        var endWithNewline = options.end_with_newline || false;

        // compatibility
        if (typeof indentSize === "string") {
            indentSize = parseInt(indentSize, 10);
        }

        // tokenizer
        var whiteRe = /^\s+$/;
        var wordRe = /[\w$\-_]/;

        var pos = -1,
            ch;

        function next() {
            ch = source_text.charAt(++pos);
            return ch;
        }

        function peek() {
            return source_text.charAt(pos + 1);
        }

        function getrow() {
            var test1 = source_text.substr(pos, source_text.indexOf(';') + 1);
            var test2 = source_text.substr(pos, source_text.indexOf('{') + 1);

            if (test1.length > test2.length) {
                return test2;
            } else {
                return test1;
            }
        }

        function eatString(endChar) {
            var start = pos;
            while (next()) {
                if (ch === "\\") {
                    next();
                    next();
                } else if (ch === endChar) {
                    break;
                } else if (ch === "\n") {
                    break;
                }
            }
            return source_text.substring(start, pos + 1);
        }

        function eatWhitespace() {
            var start = pos;
            while (whiteRe.test(peek())) {
                pos++;
            }
            return pos !== start;
        }

        function skipWhitespace() {
            var start = pos;
            do {} while (whiteRe.test(next()));
            return pos !== start + 1;
        }

        function eatComment(singleLine) {
            var start = pos;
            next();
            while (next()) {
                if (ch === "*" && peek() === "/") {
                    pos++;
                    break;
                } else if (singleLine && ch === "\n") {
                    break;
                }
            }

            return source_text.substring(start, pos + 1);
        }

        function lookBack(str) {
            return source_text.substring(pos - str.length, pos).toLowerCase() ===
                str;
        }

        function isCommentOnLine() {
            var endOfLine = source_text.indexOf('\n', pos);
            if (endOfLine === -1) return false;
            var restOfLine = source_text.substring(pos, endOfLine);
            return restOfLine.indexOf('//') !== -1;
        }

        // printer
        var indentString = source_text.match(/^[\r\n]*[\t ]*/)[0];
        var singleIndent = Array(indentSize + 1).join(indentCharacter);
        var indentLevel = 0;

        function indent() {
            indentLevel++;
            indentString += singleIndent;
        }

        function outdent() {
            indentLevel--;
            indentString = indentString.slice(0, -indentSize);
        }

        var print = {};
        print["{"] = function (ch) {
            print.singleSpace();
            output.push(ch);
            print.newLine();
        };
        print["}"] = function (ch) {
            print.newLine();
            output.push(ch);
            print.newLine();
        };

        print._lastCharWhitespace = function () {
            return whiteRe.test(output[output.length - 1]);
        }

        print.newLine = function (keepWhitespace) {
            if (!keepWhitespace) {
                while (print._lastCharWhitespace()) {
                    output.pop();
                }
            }

            if (output.length) {
                output.push('\n');
            }
            if (indentString) {
                output.push(indentString);
            }
        };
        print.singleSpace = function () {
            if (output.length && !print._lastCharWhitespace()) {
                output.push(' ');
            }
        };
        var output = [];
        if (indentString) {
            output.push(indentString);
        }
        /*_____________________--------------------_____________________*/

        var insideRule = false;
        while (true) {
            var isAfterSpace = skipWhitespace();

            if (!ch) {
                break;
            } else if (ch === '/' && peek() === '*') { /* css comment */
                print.newLine();
                output.push(eatComment(), "\n", indentString);
                var header = lookBack("")
                if (header) {
                    print.newLine();
                }
            } else if (ch === '/' && peek() === '/') { // single line comment
                output.push(eatComment(true), indentString);
            } else if (ch === '{') {
                eatWhitespace();
                if (peek() == '}') {
                    next();
                    output.push(" {}");
                } else {
                    indent();
                    print["{"](ch);
                }
            } else if (ch === '}') {
                outdent();
                print["}"](ch);
                insideRule = false;
            } else if (ch === ":") {
                eatWhitespace();
                if(getrow().indexOf("{") !== -1){
                     output.push(ch);
                } else {
                    output.push(ch, " ");
                }
                insideRule = true;
            } else if (ch === '"' || ch === '\'') {
                output.push(eatString(ch));
            } else if (ch === ';') {
                if (isCommentOnLine()) {
                    var beforeComment = eatString('/');
                    var comment = eatComment(true);
                    output.push(beforeComment, comment.substring(1, comment.length - 1), '\n', indentString);
                } else {
                    output.push(ch, '\n', indentString);
                }
            } else if (ch === '(') { // may be a url
                if (lookBack("url")) {
                    output.push(ch);
                    eatWhitespace();
                    if (next()) {
                        if (ch !== ')' && ch !== '"' && ch !== '\'') {
                            output.push(eatString(')'));
                        } else {
                            pos--;
                        }
                    }
                } else {
                    if (isAfterSpace) {
                        print.singleSpace();
                    }
                    output.push(ch);
                    eatWhitespace();
                }
            } else if (ch === ')') {
                output.push(ch);
            } else if (ch === ',') {
                eatWhitespace();
                output.push(ch);
                if (!insideRule && selectorSeparatorNewline) {
                    print.newLine();
                } else {
                    print.singleSpace();
                }
            } else if (ch === ']') {
                output.push(ch);
            } else if (ch === '[' || ch === '=') { // no whitespace before or after
                eatWhitespace();
                output.push(ch);
            } else {
                if (isAfterSpace) {
                    print.singleSpace();
                }

                output.push(ch);
            }
        }

        var sweetCode = output.join('').replace(/[\n ]+$/, '');

        // establish end_with_newline
        var should = endWithNewline;
        var actually = /\n$/.test(sweetCode)
        if (should && !actually)
            sweetCode += "\n";
        else if (!should && actually)
            sweetCode = sweetCode.slice(0, -1);

        return sweetCode;
    }

    if (typeof define === "function") {
        // Add support for require.js
        define(function (require, exports, module) {
            exports.css_beautify = css_beautify;
        });
    } else if (typeof exports !== "undefined") {
        // Add support for CommonJS. Just put this file somewhere on your require.paths
        // and you will be able to `var html_beautify = require("beautify").html_beautify`.
        exports.css_beautify = css_beautify;
    } else if (typeof window !== "undefined") {
        // If we're running a web page and don't have either of the above, add our one global
        window.css_beautify = css_beautify;
    } else if (typeof global !== "undefined") {
        // If we don't even have window, try global.
        global.css_beautify = css_beautify;
    }

}());
<|endoftext|>


<commit_before>import { ClusterMarkers } from './ClusterMarkers';
import { STATION_ENTRANCE, FEATURE_ENTRANCE_DOTS } from '../core/constants';
import { Points, BufferGeometry, Float32BufferAttribute } from '../Three';

class Entrances extends ClusterMarkers {

	constructor ( ctx, survey ) {

		super( ctx, survey.modelLimits, 4 );

		const self = this;
		const surveyTree = survey.surveyTree;
		const entrances = survey.metadata.entrances;
		const vertices = [];

		const geometry = new BufferGeometry();

		const material = ctx.materials.getEntrancePointMaterial();

		this.entranceColor = ctx.cfg.themeColor( 'stations.entrances.marker' );

		const markers = new Points( geometry, material );

		markers.layers.set( FEATURE_ENTRANCE_DOTS );

		// remove common elements from station names if no alternatives available

		let endNode = surveyTree;

		while ( endNode.children.length === 1 ) endNode = endNode.children [ 0 ];

		// find entrances and add Markers

		surveyTree.traverse( _addEntrance );

		const l = vertices.length * 3;

		if ( l > 0 ) {

			const positions = new Float32BufferAttribute( l, 3 );
			const colors = new Float32BufferAttribute( l, 3 );

			positions.copyVector3sArray( vertices );

			geometry.setAttribute( 'position', positions );
			geometry.setAttribute( 'color', colors );

		} else {

			this.visible = false;

		}

		this.markers = markers;
		this.vertices = vertices;
		this.metadata = survey.metadata;

		// set default colors - needs to be after markers property is set
		this.setSelection( null );

		this.addStatic( markers );

		return this;

		function _addEntrance( node ) {

			// FIXME supress mutiple copies of the point being created

			if ( ! ( node.type & STATION_ENTRANCE ) ) return;
			//if ( node.next && ! ( node.ownType & STATION_ENTRANCE ) ) return;

			let name;

			const entranceInfo = entrances[ node.getPath() ];

			if ( entranceInfo?.name !== undefined ) {

				name = entranceInfo.name;

			} else if ( node.comment !== undefined ) {

				name = node.comment;

			} else {

				name = node.getPath( endNode );

			}

			vertices.push( node );

			if ( name === '-skip' ) return;

			self.addMarker( node, ' ' + name + ' ' );

		}

	}

	getStation ( index ) {

		const station = this.vertices[ index ];
		const stationName = station.getPath();

		return {
			station: station,
			name: stationName,
			info: this.metadata.entrances[ stationName ]
		};

	}

	setStation ( station, info ) {

		const metadata = this.metadata;

		metadata.entrances[ station.getPath() ] = info;

		metadata.saveLocal();

	}

	setSelection ( selection ) {

		const colors = this.markers.geometry.getAttribute( 'color' );
		const color = this.entranceColor;

		if ( colors === undefined ) return;

		if ( selection === null || selection.isEmpty() ) {

			const array = colors.array;
			const l = array.length;

			for ( let i = 0; i < l; i += 3 ) {

				color.toArray( array, i );

			}

		} else {

			const idSet = selection.getIds();

			this.vertices.forEach( function ( node, i ) {

				if ( idSet.has( node.id ) ) {

					color.toArray( colors, i * 3 );

				} else {

					colors.setXYZ( i, 0.5, 0.5, 0.5 );

				}

			} );

		}

		colors.needsUpdate = true;

	}

	forEachEntrance ( callback ) {

		this.vertices.forEach( (v, i ) => callback( v, i ) );

	}

}

export { Entrances };<commit_msg>select single label for duplicated entrance stations<commit_after>import { ClusterMarkers } from './ClusterMarkers';
import { STATION_ENTRANCE, FEATURE_ENTRANCE_DOTS } from '../core/constants';
import { Points, BufferGeometry, Float32BufferAttribute } from '../Three';

class Entrances extends ClusterMarkers {

	constructor ( ctx, survey ) {

		super( ctx, survey.modelLimits, 4 );

		const self = this;
		const surveyTree = survey.surveyTree;
		const entrances = survey.metadata.entrances;
		const vertices = [];

		const geometry = new BufferGeometry();

		const material = ctx.materials.getEntrancePointMaterial();

		this.entranceColor = ctx.cfg.themeColor( 'stations.entrances.marker' );

		const markers = new Points( geometry, material );

		markers.layers.set( FEATURE_ENTRANCE_DOTS );

		// remove common elements from station names if no alternatives available

		let endNode = surveyTree;

		while ( endNode.children.length === 1 ) endNode = endNode.children [ 0 ];

		// find entrances and add Markers

		surveyTree.traverse( _addEntrance );

		const l = vertices.length * 3;

		if ( l > 0 ) {

			const positions = new Float32BufferAttribute( l, 3 );
			const colors = new Float32BufferAttribute( l, 3 );

			positions.copyVector3sArray( vertices );

			geometry.setAttribute( 'position', positions );
			geometry.setAttribute( 'color', colors );

		} else {

			this.visible = false;

		}

		this.markers = markers;
		this.vertices = vertices;
		this.metadata = survey.metadata;

		// set default colors - needs to be after markers property is set
		this.setSelection( null );

		this.addStatic( markers );

		return this;

		function _addEntrance( node ) {

			if ( ! ( ( node.ownType ?? node.type ) & STATION_ENTRANCE ) ) return;

			let next = node.next;

			while ( next && next !== node ) {

				// skip if a colocated station is already found as an entrance.
				if ( vertices.includes( next ) ) return;
				next = next.next;

			}

			vertices.push( node );

			let name;

			const entranceInfo = entrances[ node.getPath() ];

			if ( entranceInfo?.name !== undefined ) {

				name = entranceInfo.name;
				if ( name === '-skip' ) return;

			} else if ( node.comment !== undefined ) {

				name = node.comment;

			} else {

				name = node.getPath( endNode );

			}

			self.addMarker( node, ' ' + name + ' ' );

		}

	}

	getStation ( index ) {

		const station = this.vertices[ index ];
		const stationName = station.getPath();

		return {
			station: station,
			name: stationName,
			info: this.metadata.entrances[ stationName ]
		};

	}

	setStation ( station, info ) {

		const metadata = this.metadata;

		metadata.entrances[ station.getPath() ] = info;

		metadata.saveLocal();

	}

	setSelection ( selection ) {

		const colors = this.markers.geometry.getAttribute( 'color' );
		const color = this.entranceColor;

		if ( colors === undefined ) return;

		if ( selection === null || selection.isEmpty() ) {

			const array = colors.array;
			const l = array.length;

			for ( let i = 0; i < l; i += 3 ) {

				color.toArray( array, i );

			}

		} else {

			const idSet = selection.getIds();

			this.vertices.forEach( function ( node, i ) {

				if ( idSet.has( node.id ) ) {

					color.toArray( colors, i * 3 );

				} else {

					colors.setXYZ( i, 0.5, 0.5, 0.5 );

				}

			} );

		}

		colors.needsUpdate = true;

	}

	forEachEntrance ( callback ) {

		this.vertices.forEach( (v, i ) => callback( v, i ) );

	}

}

export { Entrances };<|endoftext|>


<commit_before>// @flow weak

import keycode from 'keycode';
import warning from 'warning';
import contains from 'dom-helpers/query/contains';
import ownerDocument from 'dom-helpers/ownerDocument';
import addEventListener from '../utils/addEventListener';

const internal = {
  focusKeyPressed: false,
};

export function focusKeyPressed(pressed) {
  if (typeof pressed !== 'undefined') {
    internal.focusKeyPressed = Boolean(pressed);
  }

  return internal.focusKeyPressed;
}

export function detectKeyboardFocus(instance, element, callback, attempt = 1) {
  warning(instance.keyboardFocusCheckTime, 'Material-UI: missing instance.keyboardFocusCheckTime');
  warning(
    instance.keyboardFocusMaxCheckTimes,
    'Material-UI: missing instance.keyboardFocusMaxCheckTimes',
  );

  instance.keyboardFocusTimeout = setTimeout(() => {
    const doc = ownerDocument(element);

    if (
      focusKeyPressed() &&
      (doc.activeElement === element || contains(element, doc.activeElement))
    ) {
      callback();
    } else if (attempt < instance.keyboardFocusMaxCheckTimes) {
      detectKeyboardFocus(instance, element, callback, attempt + 1);
    }
  }, instance.keyboardFocusCheckTime);
}

const FOCUS_KEYS = ['tab', 'enter', 'space', 'esc', 'up', 'down', 'left', 'right'];

function isFocusKey(event) {
  return FOCUS_KEYS.indexOf(keycode(event)) !== -1;
}

const handleKeyUpEvent = event => {
  if (isFocusKey(event)) {
    internal.focusKeyPressed = true;
  }
};

export function listenForFocusKeys(win) {
  // The event listener will only be added once per window.
  // Duplicate event listeners will be ignored by addEventListener.
  // Also, this logic is client side only, we don't need a teardown.
  addEventListener(win, 'keyup', handleKeyUpEvent);
}
<commit_msg>[ButtonBase] Save one line of code (#10225)<commit_after>// @flow weak

import keycode from 'keycode';
import warning from 'warning';
import contains from 'dom-helpers/query/contains';
import ownerDocument from 'dom-helpers/ownerDocument';

const internal = {
  focusKeyPressed: false,
};

export function focusKeyPressed(pressed) {
  if (typeof pressed !== 'undefined') {
    internal.focusKeyPressed = Boolean(pressed);
  }

  return internal.focusKeyPressed;
}

export function detectKeyboardFocus(instance, element, callback, attempt = 1) {
  warning(instance.keyboardFocusCheckTime, 'Material-UI: missing instance.keyboardFocusCheckTime');
  warning(
    instance.keyboardFocusMaxCheckTimes,
    'Material-UI: missing instance.keyboardFocusMaxCheckTimes',
  );

  instance.keyboardFocusTimeout = setTimeout(() => {
    const doc = ownerDocument(element);

    if (
      focusKeyPressed() &&
      (doc.activeElement === element || contains(element, doc.activeElement))
    ) {
      callback();
    } else if (attempt < instance.keyboardFocusMaxCheckTimes) {
      detectKeyboardFocus(instance, element, callback, attempt + 1);
    }
  }, instance.keyboardFocusCheckTime);
}

const FOCUS_KEYS = ['tab', 'enter', 'space', 'esc', 'up', 'down', 'left', 'right'];

function isFocusKey(event) {
  return FOCUS_KEYS.indexOf(keycode(event)) !== -1;
}

const handleKeyUpEvent = event => {
  if (isFocusKey(event)) {
    internal.focusKeyPressed = true;
  }
};

export function listenForFocusKeys(win) {
  // The event listener will only be added once per window.
  // Duplicate event listeners will be ignored by addEventListener.
  // Also, this logic is client side only, we don't need a teardown.
  win.addEventListener('keyup', handleKeyUpEvent);
}
<|endoftext|>