<commit_before>// v2 of services form which displays a microservice/workload split
import React, {Component} from 'react';
import * as _ from 'lodash';
import {
  Button,
  Checkbox,
  Container,
  Dimmer,
  Header,
  Form,
  Input,
  Image,
  Divider,
  List,
  Loader,
  Segment,
  Dropdown,
  Grid,
  Label,
  Icon,
  Accordion,
  Popup,
} from 'semantic-ui-react';
import moment from 'moment';

import {labelContains} from './helpers.js';

const parseLastUpdated = (date) => {
  return moment(date.split('[UTC]')[0]).toString();
};

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

    this.state = {
      ephemeral: {
        fetching: true,
        submitting: false,
      },
      location: 'servicesForm',
    };
    this.handleUserInputChange = this.handleUserInputChange.bind(this);
    this.handleWorkloadEnablement = this.handleWorkloadEnablement.bind(this);
  /**
   * Sets the input in field state.
   * @param {SyntheticEvent} event
   * @param {object} data
   */
  handleUserInputChange(event, data) {

    // check for missing props
    if (typeof data === 'undefined') return;

    const fieldNameSplit = data.name.split('#');
    const workloads = this.state.fields.workloads;
    // TODO: this is hacky and mutates... fix ASAP
    for (let i = 0; i < workloads.length; i++) {
      if (workloads[i].originalKey === fieldNameSplit[0]) {
        for (let j = 0; j < workloads[i].userInput.length; j++) {
          if (workloads[i].userInput[j].name === fieldNameSplit[1]) {
            let tmpUserInput = workloads[i].userInput[j];
            if (data.type === 'checkbox') {
              tmpUserInput.defaultValue = data.checked;
            } else if (data.type === 'text') {
              tmpUserInput.defaultValue = data.value;
            }
          }
        }
      }
    }
    this.setState({fields: {...this.state.fields, workloads}});
  }

  /**
   * Handles checkbox toggle for workload enablement
   * @param {SyntheticEvent} event
   * @param {object} data
   */
  handleWorkloadEnablement(event, data) {
    console.log('workload enablement', event, data);

    const fieldNameSplit = data.name.split('#');
    const workloads = this.state.fields.workloads;
    // TODO: hacky... mutates
    for (let i = 0; i < workloads.length; i++) {
      if (workloads[i].originalKey === fieldNameSplit[0]) {
        workloads[i].enabled = data.checked;
        break;
      }
    }
    this.setState({fields: {...this.state.fields, workloads}});
  }
  }

  componentWillMount() {
    const { onMicroservicesGet, onWorkloadsGet, onConfigurationGet, configuration } = this.props;
    console.log('props in mswl', this.props);

    // onConfigurationGet()
    //     .then((configData) => {
          onMicroservicesGet('configData.exchange_api', 'IBM')
              .then((data) => {
                console.log('got data', data);
              });
        // })
        // .catch((err) => {
        //   console.error(err);
        // })
  }
  _getMicroserviceIcon(microserviceLabel) {
    const underscoreLabel = _.toLower(microserviceLabel);

    if (labelContains(underscoreLabel, 'netspeed')) return '/images/netspeed.svg';
    if (labelContains(underscoreLabel, 'network')) return '/images/netspeed.svg';
    if (labelContains(underscoreLabel, 'citygram')) return '/images/citygram.svg';
    if (labelContains(underscoreLabel, 'sdr')) return '/images/sdr.svg';
    if (labelContains(underscoreLabel, 'pws')) return '/images/pws.svg';
    // TODO: add location icon
    if (labelContains(underscoreLabel, 'location')) return '/images/gps.svg';
    if (labelContains(underscoreLabel, 'cpu')) return '/images/cputemp.svg';
    if (labelContains(underscoreLabel, 'air pollution')) return '/images/purpleair.svg';
    if (labelContains(underscoreLabel, 'aural')) return '/images/aural.svg';
    if (labelContains(underscoreLabel, 'gps')) return '/images/gps.svg';

    // TODO: add ? icon
    // else
    return '/images/gps.svg';
  }

  _getMicroserviceShortname(microserviceLabel) {
    const underscoreLabel = _.toLower(microserviceLabel);

    if (labelContains(underscoreLabel, 'netspeed')) return 'netspeed';
    if (labelContains(underscoreLabel, 'network')) return 'netspeed';
    if (labelContains(underscoreLabel, 'citygram')) return 'citygram';
    if (labelContains(underscoreLabel, 'sdr')) return 'sdr';
    if (labelContains(underscoreLabel, 'pws')) return 'pws';
    if (labelContains(underscoreLabel, 'location')) return 'location';
    if (labelContains(underscoreLabel, 'cpu')) return 'cputemp';
    if (labelContains(underscoreLabel, 'air pollution')) return 'purpleair';
    if (labelContains(underscoreLabel, 'aural')) return 'aural';
    if (labelContains(underscoreLabel, 'gps')) return 'gps';
    return '';
  }

  _generateHardwareList(matchHardware) {

    return (
      <List.Item>
        <List.Content>
          <List.Header>Hardware</List.Header>

            {
              _.map(Object.keys(matchHardware), (hwItem) => {
                return <List.Description key={hwItem}>{hwItem}: {matchHardware[hwItem]}</List.Description>
              })
            }

        </List.Content>
      </List.Item>
    )
  }

  _generateMicroserviceSegments(microservices, msKey) {

    const parseLastUpdated = (date) => {
      return moment(date.split('[UTC]')[0]).toString();
    };

    let segmentRender =
;
    const segments = _.map(Object.keys(microservices), (msSegmentKey) => {
      if (msKey === msSegmentKey) {
         segmentRender = _.map(microservices[msSegmentKey], (microservice) => {
          return (
            <Segment padded raised key={microservice.label}>
              {microservice.label} v{microservice.version}
              <Checkbox
                style={{marginBottom: '.75em'}}
                toggle
                label='enabled'
              />

                <Icon name='user outline' />
                {microservice.owner}

              <List>
                <List.Item>Description: {microservice.description}</List.Item>
                <List.Item>Architecture: {microservice.arch}</List.Item>
                <List.Item>Last Updated: {parseLastUpdated(microservice.lastUpdated)}</List.Item>
                <List.Item>Sharable: {microservice.sharable}</List.Item>
                <List.Item>Public: {microservice.public.toString()}</List.Item>
                <List.Item>Download URL: {microservice.downloadUrl}</List.Item>
                <List.Item>Spec Ref: {microservice.specRef}</List.Item>
                {this._generateHardwareList(microservice.matchHardware)}
              </List>
            </Segment>
          );
        });
      }
    });
    console.log('segments', segments)
    return segmentRender;
  }

  _generateMicroserviceSections(microservices) {
    const { servicesForm } = this.props;
    const orgSections = _.map(Object.keys(microservices), (msKey) => {
    return (
        <Segment vertical key={msKey}>
          {msKey}
          {this._generateMicroserviceSegments(microservices, msKey)}
        </Segment>
      );
    });
    return orgSections;
  }

  render() {
    const { services } = this.props;
    return (

        Services Selection
        <Grid columns={2} relaxed>
          <Grid.Column>
            {typeof services !== 'undefined'
              && typeof services.microservices !== 'undefined'
              && this._generateMicroserviceSections(services.microservices)
            }
          </Grid.Column>
          <Grid.Column>
            hi
          </Grid.Column>
        </Grid>

    )
  }
}

export default ServicesForm;<commit_msg>handle microservice enablement and bind it<commit_after>// v2 of services form which displays a microservice/workload split
import React, {Component} from 'react';
import * as _ from 'lodash';
import {
  Button,
  Checkbox,
  Container,
  Dimmer,
  Header,
  Form,
  Input,
  Image,
  Divider,
  List,
  Loader,
  Segment,
  Dropdown,
  Grid,
  Label,
  Icon,
  Accordion,
  Popup,
} from 'semantic-ui-react';
import moment from 'moment';

import {labelContains} from './helpers.js';

const parseLastUpdated = (date) => {
  return moment(date.split('[UTC]')[0]).toString();
};

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

    this.state = {
      ephemeral: {
        fetching: true,
        submitting: false,
      },
      location: 'servicesForm',
    };
    this.handleUserInputChange = this.handleUserInputChange.bind(this);
    this.handleWorkloadEnablement = this.handleWorkloadEnablement.bind(this);
    this.handleMicroserviceEnablement = this.handleMicroserviceEnablement.bind(this);
  }

  /**
   * Sets the input in field state.
   * @param {SyntheticEvent} event
   * @param {object} data
   */
  handleUserInputChange(event, data) {

    // check for missing props
    if (typeof data === 'undefined') return;

    const fieldNameSplit = data.name.split('#');
    const workloads = this.state.fields.workloads;
    // TODO: this is hacky and mutates... fix ASAP
    for (let i = 0; i < workloads.length; i++) {
      if (workloads[i].originalKey === fieldNameSplit[0]) {
        for (let j = 0; j < workloads[i].userInput.length; j++) {
          if (workloads[i].userInput[j].name === fieldNameSplit[1]) {
            let tmpUserInput = workloads[i].userInput[j];
            if (data.type === 'checkbox') {
              tmpUserInput.defaultValue = data.checked;
            } else if (data.type === 'text') {
              tmpUserInput.defaultValue = data.value;
            }
          }
        }
      }
    }
    this.setState({fields: {...this.state.fields, workloads}});
  }

  /**
   * Handles checkbox toggle for workload enablement
   * @param {SyntheticEvent} event
   * @param {object} data
   */
  handleWorkloadEnablement(event, data) {
    console.log('workload enablement', event, data);

    const fieldNameSplit = data.name.split('#');
    const workloads = this.state.fields.workloads;
    // TODO: hacky... mutates
    for (let i = 0; i < workloads.length; i++) {
      if (workloads[i].originalKey === fieldNameSplit[0]) {
        workloads[i].enabled = data.checked;
        break;
      }
    }
    this.setState({fields: {...this.state.fields, workloads}});
  }

  /**
   * Handles checkbox toggle for microservice enablement
   * @param {SyntheticEvent} event
   * @param {object} data
   */
  handleMicroserviceEnablement(event, data) {
    const fieldNameSplit = data.name.split('#');
    const mses = this.state.fields.microservices;
    for (let i = 0; i < mses.length; i++) {
      if (mses[i].originalKey === fieldNameSplit[0]) {
        mses[i].enabled = data.checked;
        break;
      }
    }
    this.setState({fields: {...this.state.fields, microservices: mses}});
  }
  }

  componentWillMount() {
    const { onMicroservicesGet, onWorkloadsGet, onConfigurationGet, configuration } = this.props;
    console.log('props in mswl', this.props);

    // onConfigurationGet()
    //     .then((configData) => {
          onMicroservicesGet('configData.exchange_api', 'IBM')
              .then((data) => {
                console.log('got data', data);
              });
        // })
        // .catch((err) => {
        //   console.error(err);
        // })
  }
  _getMicroserviceIcon(microserviceLabel) {
    const underscoreLabel = _.toLower(microserviceLabel);

    if (labelContains(underscoreLabel, 'netspeed')) return '/images/netspeed.svg';
    if (labelContains(underscoreLabel, 'network')) return '/images/netspeed.svg';
    if (labelContains(underscoreLabel, 'citygram')) return '/images/citygram.svg';
    if (labelContains(underscoreLabel, 'sdr')) return '/images/sdr.svg';
    if (labelContains(underscoreLabel, 'pws')) return '/images/pws.svg';
    // TODO: add location icon
    if (labelContains(underscoreLabel, 'location')) return '/images/gps.svg';
    if (labelContains(underscoreLabel, 'cpu')) return '/images/cputemp.svg';
    if (labelContains(underscoreLabel, 'air pollution')) return '/images/purpleair.svg';
    if (labelContains(underscoreLabel, 'aural')) return '/images/aural.svg';
    if (labelContains(underscoreLabel, 'gps')) return '/images/gps.svg';

    // TODO: add ? icon
    // else
    return '/images/gps.svg';
  }

  _getMicroserviceShortname(microserviceLabel) {
    const underscoreLabel = _.toLower(microserviceLabel);

    if (labelContains(underscoreLabel, 'netspeed')) return 'netspeed';
    if (labelContains(underscoreLabel, 'network')) return 'netspeed';
    if (labelContains(underscoreLabel, 'citygram')) return 'citygram';
    if (labelContains(underscoreLabel, 'sdr')) return 'sdr';
    if (labelContains(underscoreLabel, 'pws')) return 'pws';
    if (labelContains(underscoreLabel, 'location')) return 'location';
    if (labelContains(underscoreLabel, 'cpu')) return 'cputemp';
    if (labelContains(underscoreLabel, 'air pollution')) return 'purpleair';
    if (labelContains(underscoreLabel, 'aural')) return 'aural';
    if (labelContains(underscoreLabel, 'gps')) return 'gps';
    return '';
  }

  _generateHardwareList(matchHardware) {

    return (
      <List.Item>
        <List.Content>
          <List.Header>Hardware</List.Header>

            {
              _.map(Object.keys(matchHardware), (hwItem) => {
                return <List.Description key={hwItem}>{hwItem}: {matchHardware[hwItem]}</List.Description>
              })
            }

        </List.Content>
      </List.Item>
    )
  }

  _generateMicroserviceSegments(microservices, msKey) {

    const parseLastUpdated = (date) => {
      return moment(date.split('[UTC]')[0]).toString();
    };

    let segmentRender =
;
    const segments = _.map(Object.keys(microservices), (msSegmentKey) => {
      if (msKey === msSegmentKey) {
         segmentRender = _.map(microservices[msSegmentKey], (microservice) => {
          return (
            <Segment padded raised key={microservice.label}>
              {microservice.label} v{microservice.version}
              <Checkbox
                style={{marginBottom: '.75em'}}
                toggle
                label='enabled'
              />

                <Icon name='user outline' />
                {microservice.owner}

              <List>
                <List.Item>Description: {microservice.description}</List.Item>
                <List.Item>Architecture: {microservice.arch}</List.Item>
                <List.Item>Last Updated: {parseLastUpdated(microservice.lastUpdated)}</List.Item>
                <List.Item>Sharable: {microservice.sharable}</List.Item>
                <List.Item>Public: {microservice.public.toString()}</List.Item>
                <List.Item>Download URL: {microservice.downloadUrl}</List.Item>
                <List.Item>Spec Ref: {microservice.specRef}</List.Item>
                {this._generateHardwareList(microservice.matchHardware)}
              </List>
            </Segment>
          );
        });
      }
    });
    console.log('segments', segments)
    return segmentRender;
  }

  _generateMicroserviceSections(microservices) {
    const { servicesForm } = this.props;
    const orgSections = _.map(Object.keys(microservices), (msKey) => {
    return (
        <Segment vertical key={msKey}>
          {msKey}
          {this._generateMicroserviceSegments(microservices, msKey)}
        </Segment>
      );
    });
    return orgSections;
  }

  render() {
    const { services } = this.props;
    return (

        Services Selection
        <Grid columns={2} relaxed>
          <Grid.Column>
            {typeof services !== 'undefined'
              && typeof services.microservices !== 'undefined'
              && this._generateMicroserviceSections(services.microservices)
            }
          </Grid.Column>
          <Grid.Column>
            hi
          </Grid.Column>
        </Grid>

    )
  }
}

export default ServicesForm;<|endoftext|>


<commit_before>/**
 * Created by fbartels on 05.03.14.
 */

(function() {
    "use strict";

    var zeropad = function(x) {
        if (x < 10) {
            return "0" + x;
        }
        return x;
    };

    var xAxisFormat = function (d) {
        if (d === -1) {return "";}
        var date = new Date(d);
        return zeropad(date.getHours()) + ":"
            + zeropad(date.getMinutes()) + ":"
            + zeropad(date.getSeconds());
    };

    var mergeObjects = function(o1, o2, mergeAttribList) {
        if (!mergeAttribList) {mergeAttribList = [];}
        var vals = {};
        mergeAttribList.forEach(function (a) {
            var valO1 = o1[a];
            var valO2 = o2[a];
            if (valO1 === undefined) {
                valO1 = {};
            }
            if (valO2 === undefined) {
                valO2 = {};
            }
            vals[a] = _.extend(valO1, valO2);
        });
        var res = _.extend(o1,o2);
        Object.keys(vals).forEach(function(k) {
            res[k] = vals[k];
        });
        return res;
    };

    // graphs that should never show
    var hideGraphs = [
        "totalTime",
        "uptime",
        "residentSize",
        "physicalMemory",
        "minorPageFaults",
        "requestsTotal"
    ];

    var isCombinedChart = function (chart) {
        var result = false;
        Object.keys(combinedCharts).forEach(function (cc) {
            var part = cc.split("_");
            if (part[1] === chart.figure) {
                chart.key = cc;
                result = true;
            };
        });
        return result;
    };

    var differenceBasedLineChartType = "lineChartDiffBased";
    var regularLineChartType = "current";
    var distributionChartType = "distribution";
    var accumulatedChartType = "accumulated";
    var distributionBasedLineChartType = "currentDistribution";

    // different time series types for charts
    var chartTypeExceptions = {};
    chartTypeExceptions[accumulatedChartType] = {
            minorPageFaults : differenceBasedLineChartType,
            majorPageFaults : differenceBasedLineChartType,
            requestsTotal : differenceBasedLineChartType,
            requestsAsync: differenceBasedLineChartType,
            requestsGet: differenceBasedLineChartType,
            requestsHead: differenceBasedLineChartType,
            requestsPost: differenceBasedLineChartType,
            requestsPut: differenceBasedLineChartType,
            requestsPatch: differenceBasedLineChartType,
            requestsDelete: differenceBasedLineChartType,
            requestsOptions: differenceBasedLineChartType,
            requestsOther: differenceBasedLineChartType

    };
    chartTypeExceptions[distributionChartType] = {
            totalTime : distributionBasedLineChartType,
            requestTime: distributionBasedLineChartType,
            queueTime: distributionBasedLineChartType,
            bytesSent: distributionBasedLineChartType,
            bytesReceived: distributionBasedLineChartType
    };
    // figures supposed to be dispalyed in one chart
    var combinedCharts = {
        http_requests: [
            "requestsGet","requestsHead",
            "requestsPost","requestsPut",
            "requestsPatch","requestsDelete",
            "requestsOptions", "requestsOther"
        ],
        system_systemUserTime: ["systemTime","userTime"],
        client_totalRequestTime: ["requestTime","queueTime"]
    };

    //colors for dygraphs
    var colors = ["#617e2b", "#296e9c", "#81ccd8", "#7ca530", "#3c3c3c",
        "#aa90bd", "#e1811d", "#c7d4b2", "#d0b2d4"];

        //figure dependend options
    var  figureDependedOptions = {
        numberOfThreads : {
            div : "#systemResources"
        },
        residentSize : {
            div : "#systemResources"
        },
        residentSizePercent : {
            div : "#systemResources",
                axes : {
                y: {
                    labelsKMG2: false,
                    axisLabelFormatter: function(y) {
                        return y.toPrecision(2) + "%";
                    },
                    valueFormatter: function(y) {
                        return y.toPrecision(2) + "%";
                    }
                }
            }
        },
        physicalMemory : {
            div : "#systemResources"
        },
        virtualSize : {
            div : "#systemResources"
        },
        minorPageFaults : {
            div : "#systemResources",
                labelsKMG2: false
        },
        majorPageFaults : {
            div : "#systemResources",
                labelsKMG2: false
        },
        systemUserTime : {
            div : "#systemResources",
            title : "System and User Time",
            stacked : true
        },
        httpConnections : {
            div : "#requestStatistics"
        },
        totalTime : {
            div : "#requestStatistics",
            title : "Total time in milliseconds",
            labelsKMG2: false,
            axes : {
                y: {
                    valueFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    },
                    axisLabelFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    }
                }
            }
        },
        requestTime : {
            div : "#requestStatistics",
            title : "Request time in milliseconds",
            labelsKMG2: false,
            axes : {
                y: {
                    valueFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    },
                    axisLabelFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    }
                }
            }
        },
        queueTime : {
            div : "#requestStatistics",
            title : "Queue time in milliseconds",
            labelsKMG2: false,
            axes : {
                y: {
                    valueFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    },
                    axisLabelFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    }
                }
            }
        },
        totalRequestTime : {
            div : "#requestStatistics",
            title : "Total time in milliseconds",
            labelsKMG2: false,
            axes : {
                y: {
                    valueFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    },
                    axisLabelFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    }
                }
            }
        },
        bytesSent : {
            div : "#requestStatistics"
        },
        bytesReceived : {
            div : "#requestStatistics"
        },
        requestsTotal : {
            div : "#requestStatistics"
        },
        clusterAverageRequestTime : {
            showLabelsOnHighlight : true
        },
        requestsAsync : {
            div : "#requestStatistics"
        },
        requests : {
            div : "#requestStatistics",
                title : "HTTP Requests per second",
                stacked : true
        },
        uptime : {
            div : "#systemResources",
            axes : {
                y: {
                    labelsKMG2: false,
                        axisLabelFormatter: function(y) {
                        if (y < 60) {
                            return y.toPrecision(3) + "s";
                        }
                        if (y < 3600) {
                            y = y/60;
                            return y.toPrecision(3) + "m";
                        }
                        y = y/3600;
                        return y.toPrecision(3) + "h";
                    }
                }
            }
        }
    };

    //configuration for chart overview
    var getDefaultConfig = function(chart) {
        chart.options =  {
            digitsAfterDecimal: 2,
            drawGapPoints: true,
            fillGraph : true,
            showLabelsOnHighlight : false,
            strokeWidth: 2,
            strokeBorderWidth: 1,
            highlightCircleSize: 0,
            strokeBorderColor: '#ffffff',
            interactionModel :  {},
            dateWindow : [new Date().getTime() -
                Math.min(
                    20 * 60 * 1000,
                    chart.data.length * 10 * 1000)
                ,new Date().getTime()],
            colors: [colors[0]],
            xAxisLabelWidth : "60",
            rightGap: 10,
            showRangeSelector: false,
            rangeSelectorHeight: 40,
            rangeSelectorPlotStrokeColor: '#365300',
            rangeSelectorPlotFillColor: '#414a4c',
            pixelsPerLabel : 60,
            labelsKMG2: true,
            axes : {
                x: {
                    valueFormatter: function(d) {
                        return xAxisFormat(d);
                    }
                },
                y: {
                    ticker: Dygraph.numericLinearTicks
                }
            }
        };
        if (figureDependedOptions[chart.figure]) {
            chart.options =  mergeObjects(
                chart.options, figureDependedOptions[chart.figure], ["axes"]
            );
        }

    };

    var getDetailChartConfig = function (chart) {
        chart.options =  _.extend(
            chart.options,
            {
                showRangeSelector : true,
                title : "",
                interactionModel : null,
                showLabelsOnHighlight : true,
                highlightCircleSize : 3
            }
        );
    };

    var updateDateWindow = function(chart) {
        chart.options.dateWindow =   [new Date().getTime() -
                Math.min(
                    20 * 60 * 1000,
                    chart.data.length * 10 * 1000)
                ,new Date().getTime()];
    };
    window.dygraphConfig = {

        Chart : function (figure, type, showGraph, title) {
                this.type = type;
                this.showGraph = showGraph;
                this.data = type === distributionChartType ? undefined  : [];
                this.figure =  figure;
                this.options =  {};
                this.defaultConfig = function() {
                    getDefaultConfig(this);
                };
                this.detailChartConfig = function() {
                    getDetailChartConfig(this);
                };
                this.updateDateWindow = function() {
                    updateDateWindow(this);
                };
                this.isCombinedChart = function() {
                    return isCombinedChart(this);
                };
                var self = this;
                this.updateLabels = function (labels) {
                    if (labels) {
                        self.options.labels = labels;
                        var colorList = colors.concat([]);
                        self.options.colors = colorList.slice(0, self.options.labels.length-1);
                        return;
                    }
                    var labels = ["datetime"];
                    if (self.isCombinedChart()) {
                        combinedCharts[self.key].sort().forEach(function(attrib) {
                            labels.push(attrib);
                        });
                        self.options.labels = labels;
                        var colorList = colors.concat([]);
                        self.options.colors = colorList.slice(0, self.options.labels.length-1);
                    } else {
                        self.options.labels = ["datetime", self.figure];
                        self.options.colors = [colors[0]];
                    }
                };
            if (type !== distributionChartType) {
                this.defaultConfig();
                this.updateLabels();
                if (!this.options.title) {
                    this.options.title = title;
                }
            }
        },

        getChartsForFigure : function (figure, type, title) {
            var result = {};
            if (chartTypeExceptions[type] &&
                chartTypeExceptions[type][figure]) {
                result[chartTypeExceptions[type][figure]] =
                    this.getChartStructure(
                        figure,
                        chartTypeExceptions[type][figure],
                        title
                    );
                if (type === distributionChartType) {
                    result[type] = this.getChartStructure(figure, type, title);
                }
            } else {
                result[type] = this.getChartStructure(figure, type, title);
            }
            return result;
        },

        getChartStructure: function (figure, type, title) {
            var showGraph = true;
            if (type === differenceBasedLineChartType) {
                title +=  " per seconds";
                type = regularLineChartType;
            } else if (type === accumulatedChartType) {
                showGraph = false;
            } else if (type === distributionBasedLineChartType)  {
                type = regularLineChartType;
            }
            return new this.Chart(figure, type, showGraph, title);
        },

        chartTypeExceptions : chartTypeExceptions,

        combinedCharts : combinedCharts,

        hideGraphs: hideGraphs,

        figureDependedOptions: figureDependedOptions,

        differenceBasedLineChartType : differenceBasedLineChartType,
        regularLineChartType : regularLineChartType,
        distributionChartType : distributionChartType,
        accumulatedChartType : accumulatedChartType,
        distributionBasedLineChartType : distributionBasedLineChartType

    };
}());
<commit_msg> fixed bug jan found, always show 20 min of history<commit_after>/**
 * Created by fbartels on 05.03.14.
 */

(function() {
    "use strict";

    var zeropad = function(x) {
        if (x < 10) {
            return "0" + x;
        }
        return x;
    };

    var xAxisFormat = function (d) {
        if (d === -1) {return "";}
        var date = new Date(d);
        return zeropad(date.getHours()) + ":"
            + zeropad(date.getMinutes()) + ":"
            + zeropad(date.getSeconds());
    };

    var mergeObjects = function(o1, o2, mergeAttribList) {
        if (!mergeAttribList) {mergeAttribList = [];}
        var vals = {};
        mergeAttribList.forEach(function (a) {
            var valO1 = o1[a];
            var valO2 = o2[a];
            if (valO1 === undefined) {
                valO1 = {};
            }
            if (valO2 === undefined) {
                valO2 = {};
            }
            vals[a] = _.extend(valO1, valO2);
        });
        var res = _.extend(o1,o2);
        Object.keys(vals).forEach(function(k) {
            res[k] = vals[k];
        });
        return res;
    };

    // graphs that should never show
    var hideGraphs = [
        "totalTime",
        "uptime",
        "residentSize",
        "physicalMemory",
        "minorPageFaults",
        "requestsTotal"
    ];

    var isCombinedChart = function (chart) {
        var result = false;
        Object.keys(combinedCharts).forEach(function (cc) {
            var part = cc.split("_");
            if (part[1] === chart.figure) {
                chart.key = cc;
                result = true;
            };
        });
        return result;
    };

    var differenceBasedLineChartType = "lineChartDiffBased";
    var regularLineChartType = "current";
    var distributionChartType = "distribution";
    var accumulatedChartType = "accumulated";
    var distributionBasedLineChartType = "currentDistribution";

    // different time series types for charts
    var chartTypeExceptions = {};
    chartTypeExceptions[accumulatedChartType] = {
            minorPageFaults : differenceBasedLineChartType,
            majorPageFaults : differenceBasedLineChartType,
            requestsTotal : differenceBasedLineChartType,
            requestsAsync: differenceBasedLineChartType,
            requestsGet: differenceBasedLineChartType,
            requestsHead: differenceBasedLineChartType,
            requestsPost: differenceBasedLineChartType,
            requestsPut: differenceBasedLineChartType,
            requestsPatch: differenceBasedLineChartType,
            requestsDelete: differenceBasedLineChartType,
            requestsOptions: differenceBasedLineChartType,
            requestsOther: differenceBasedLineChartType

    };
    chartTypeExceptions[distributionChartType] = {
            totalTime : distributionBasedLineChartType,
            requestTime: distributionBasedLineChartType,
            queueTime: distributionBasedLineChartType,
            bytesSent: distributionBasedLineChartType,
            bytesReceived: distributionBasedLineChartType
    };
    // figures supposed to be dispalyed in one chart
    var combinedCharts = {
        http_requests: [
            "requestsGet","requestsHead",
            "requestsPost","requestsPut",
            "requestsPatch","requestsDelete",
            "requestsOptions", "requestsOther"
        ],
        system_systemUserTime: ["systemTime","userTime"],
        client_totalRequestTime: ["requestTime","queueTime"]
    };

    //colors for dygraphs
    var colors = ["#617e2b", "#296e9c", "#81ccd8", "#7ca530", "#3c3c3c",
        "#aa90bd", "#e1811d", "#c7d4b2", "#d0b2d4"];

        //figure dependend options
    var  figureDependedOptions = {
        numberOfThreads : {
            div : "#systemResources"
        },
        residentSize : {
            div : "#systemResources"
        },
        residentSizePercent : {
            div : "#systemResources",
                axes : {
                y: {
                    labelsKMG2: false,
                    axisLabelFormatter: function(y) {
                        return y.toPrecision(2) + "%";
                    },
                    valueFormatter: function(y) {
                        return y.toPrecision(2) + "%";
                    }
                }
            }
        },
        physicalMemory : {
            div : "#systemResources"
        },
        virtualSize : {
            div : "#systemResources"
        },
        minorPageFaults : {
            div : "#systemResources",
                labelsKMG2: false
        },
        majorPageFaults : {
            div : "#systemResources",
                labelsKMG2: false
        },
        systemUserTime : {
            div : "#systemResources",
            title : "System and User Time",
            stacked : true
        },
        httpConnections : {
            div : "#requestStatistics"
        },
        totalTime : {
            div : "#requestStatistics",
            title : "Total time in milliseconds",
            labelsKMG2: false,
            axes : {
                y: {
                    valueFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    },
                    axisLabelFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    }
                }
            }
        },
        requestTime : {
            div : "#requestStatistics",
            title : "Request time in milliseconds",
            labelsKMG2: false,
            axes : {
                y: {
                    valueFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    },
                    axisLabelFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    }
                }
            }
        },
        queueTime : {
            div : "#requestStatistics",
            title : "Queue time in milliseconds",
            labelsKMG2: false,
            axes : {
                y: {
                    valueFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    },
                    axisLabelFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    }
                }
            }
        },
        totalRequestTime : {
            div : "#requestStatistics",
            title : "Total time in milliseconds",
            labelsKMG2: false,
            axes : {
                y: {
                    valueFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    },
                    axisLabelFormatter: function(y) {
                        y = y * 1000;
                        return y.toPrecision(3);
                    }
                }
            }
        },
        bytesSent : {
            div : "#requestStatistics"
        },
        bytesReceived : {
            div : "#requestStatistics"
        },
        requestsTotal : {
            div : "#requestStatistics"
        },
        clusterAverageRequestTime : {
            showLabelsOnHighlight : true
        },
        requestsAsync : {
            div : "#requestStatistics"
        },
        requests : {
            div : "#requestStatistics",
                title : "HTTP Requests per second",
                stacked : true
        },
        uptime : {
            div : "#systemResources",
            axes : {
                y: {
                    labelsKMG2: false,
                        axisLabelFormatter: function(y) {
                        if (y < 60) {
                            return y.toPrecision(3) + "s";
                        }
                        if (y < 3600) {
                            y = y/60;
                            return y.toPrecision(3) + "m";
                        }
                        y = y/3600;
                        return y.toPrecision(3) + "h";
                    }
                }
            }
        }
    };

    //configuration for chart overview
    var getDefaultConfig = function(chart) {
        chart.options =  {
            digitsAfterDecimal: 2,
            drawGapPoints: true,
            fillGraph : true,
            showLabelsOnHighlight : false,
            strokeWidth: 2,
            strokeBorderWidth: 1,
            highlightCircleSize: 0,
            strokeBorderColor: '#ffffff',
            interactionModel :  {},
            dateWindow : [new Date().getTime() -
                Math.min(
                    20 * 60 * 1000,
                    chart.data.length * 10 * 1000)
                ,new Date().getTime()],
            colors: [colors[0]],
            xAxisLabelWidth : "60",
            rightGap: 10,
            showRangeSelector: false,
            rangeSelectorHeight: 40,
            rangeSelectorPlotStrokeColor: '#365300',
            rangeSelectorPlotFillColor: '#414a4c',
            pixelsPerLabel : 60,
            labelsKMG2: true,
            axes : {
                x: {
                    valueFormatter: function(d) {
                        return xAxisFormat(d);
                    }
                },
                y: {
                    ticker: Dygraph.numericLinearTicks
                }
            }
        };
        if (figureDependedOptions[chart.figure]) {
            chart.options =  mergeObjects(
                chart.options, figureDependedOptions[chart.figure], ["axes"]
            );
        }

    };

    var getDetailChartConfig = function (chart) {
        chart.options =  _.extend(
            chart.options,
            {
                showRangeSelector : true,
                title : "",
                interactionModel : null,
                showLabelsOnHighlight : true,
                highlightCircleSize : 3
            }
        );
    };

    var updateDateWindow = function(chart) {
        chart.options.dateWindow =   [new Date().getTime() -
                    20 * 60 * 1000
                ,new Date().getTime()];
    };
    window.dygraphConfig = {

        Chart : function (figure, type, showGraph, title) {
                this.type = type;
                this.showGraph = showGraph;
                this.data = type === distributionChartType ? undefined  : [];
                this.figure =  figure;
                this.options =  {};
                this.defaultConfig = function() {
                    getDefaultConfig(this);
                };
                this.detailChartConfig = function() {
                    getDetailChartConfig(this);
                };
                this.updateDateWindow = function() {
                    updateDateWindow(this);
                };
                this.isCombinedChart = function() {
                    return isCombinedChart(this);
                };
                var self = this;
                this.updateLabels = function (labels) {
                    if (labels) {
                        self.options.labels = labels;
                        var colorList = colors.concat([]);
                        self.options.colors = colorList.slice(0, self.options.labels.length-1);
                        return;
                    }
                    var labels = ["datetime"];
                    if (self.isCombinedChart()) {
                        combinedCharts[self.key].sort().forEach(function(attrib) {
                            labels.push(attrib);
                        });
                        self.options.labels = labels;
                        var colorList = colors.concat([]);
                        self.options.colors = colorList.slice(0, self.options.labels.length-1);
                    } else {
                        self.options.labels = ["datetime", self.figure];
                        self.options.colors = [colors[0]];
                    }
                };
            if (type !== distributionChartType) {
                this.defaultConfig();
                this.updateLabels();
                if (!this.options.title) {
                    this.options.title = title;
                }
            }
        },

        getChartsForFigure : function (figure, type, title) {
            var result = {};
            if (chartTypeExceptions[type] &&
                chartTypeExceptions[type][figure]) {
                result[chartTypeExceptions[type][figure]] =
                    this.getChartStructure(
                        figure,
                        chartTypeExceptions[type][figure],
                        title
                    );
                if (type === distributionChartType) {
                    result[type] = this.getChartStructure(figure, type, title);
                }
            } else {
                result[type] = this.getChartStructure(figure, type, title);
            }
            return result;
        },

        getChartStructure: function (figure, type, title) {
            var showGraph = true;
            if (type === differenceBasedLineChartType) {
                title +=  " per seconds";
                type = regularLineChartType;
            } else if (type === accumulatedChartType) {
                showGraph = false;
            } else if (type === distributionBasedLineChartType)  {
                type = regularLineChartType;
            }
            return new this.Chart(figure, type, showGraph, title);
        },

        chartTypeExceptions : chartTypeExceptions,

        combinedCharts : combinedCharts,

        hideGraphs: hideGraphs,

        figureDependedOptions: figureDependedOptions,

        differenceBasedLineChartType : differenceBasedLineChartType,
        regularLineChartType : regularLineChartType,
        distributionChartType : distributionChartType,
        accumulatedChartType : accumulatedChartType,
        distributionBasedLineChartType : distributionBasedLineChartType

    };
}());
<|endoftext|>


<commit_before>(function() {

var chinese = false;

var checkVersion = Dagaz.Model.checkVersion;

Dagaz.Model.checkVersion = function(design, name, value) {
  if (name == "banqi-invariant") {
      if (value == "chinese") chinese = true;
  } else {
      checkVersion(design, name, value);
  }
}

var getShadow = function(design, board) {
  var player = board.getValue(board.player);
  if (player === null) return [];
  if (_.isUndefined(board.shadow)) {
      board.shadow = [];
      _.each(design.allPositions(), function(pos) {
           var piece = board.getPiece(pos);
           if ((piece !== null) && (piece.type < 7)) {
               var value = piece.type + 7;
               if (piece.player != player) {
                   value = -value;
               }
               board.shadow.push(value);
           }
      });
  }
  return board.shadow;
}

var isFriend = function(design, x) {
  return x > 0;
}

var isPiece = function(design, x, y) {
  return x == y;
}

var isAttacker = function(design, x, enemy) {
  if (x < 0) return false;
  if ((x == 13) && (enemy == 7)) return true;
  if (!chinese && (x == 7) && (enemy == 13)) return false;
  if (!chinese && (x == 12)) return false;
  return x <= enemy;
}

var isDefender = function(design, x, enemy, friend) {
  if (!isAttacker(design, x, enemy)) return false;
  return design.price[friend] <= design.price[enemy];
}

var estimate = function(design, board, p, y, z) {
  var shadow = getShadow(design, board);
  if (shadow.length == 0) return 0;
  var r = 0;
  _.each(shadow, function(x) {
      if (p(design, x, y, z)) r++;
  });
  return (100 * r) / shadow.length;
}

var getGoals = function(design, board) {
  var r = [];
  _.each(design.allPositions(), function(pos) {
      var piece = board.getPiece(pos);
      if ((piece !== null) && (piece.type >= 7)) {
          r.push(pos);
      }
  });
  return {
      positions: r
  };
}

var getTargets = function(design, board, goals) {
  var r = {
      positions: []
  };
  if (!chinese) {
      r.map = [];
      _.each(goals, function(pos) {
          _.each(design.allDirections(), function(dir) {
              var p = design.navigate(board.player, pos, dir);
              while (p !== null) {
                  if (board.getPiece(p) !== null) break;
                  p = design.navigate(board.player, p, dir);
              }
              p = design.navigate(board.player, p, dir);
              while (p !== null) {
                  var piece = board.getPiece(p);
                  if ((piece === null) || (piece.type == 12)) {
                      r.positions.push(p);
                      if (_.isUndefined(r.map[p])) {
                          r.map[p] = [];
                      }
                      r.map[p].push(pos);
                  }
                  if (piece !== null) break;
                  p = design.navigate(board.player, p, dir);
              }
          });
      });
  }
  return r;
}

var copy = function(list) {
  var r = [];
  _.each(list, function(x) {
      r.push(x);
  });
  return r;
}

var getTrace = function(design, board, src, dst, level) {
  var r = [];
  var pos = dst;
  while (pos !== null) {
      r.unshift(pos);
      var current = level[pos];
      if (current == 0) return r;
      var next = null;
      _.each(design.allDirections(), function(dir) {
          if (next === null) {
              var p = design.navigate(board.player, pos, dir);
              while (p !== null) {
                  if (_.isUndefined(level[p])) break;
                  if (level[p] < current) {
                      next = p;
                      break;
                  }
                  if (level[p] > current) break;
                  p = design.navigate(board.player, p, dir);
              }
          }
      });
      pos = next;
  }
  return null;
}

var getChainPrice = function(design, board, attacker, attacking, len) {
  if ((attacker == null) || (attacking === null)) return 0;
  if (attacker.player == attacking.player) return 0;
  var isAttacking = isAttacker(design, attacker.type, attacking.type);
  var isAttacked  = isAttacker(design, attacking.type, attacker.type);
  if (!chinese && (attacker.type == 12)) {
      isAttacking = true;
      isAttacked  = (attacking.type == attacker.type) && (len == 1);
  }
  var price = 0;
  if (isAttacking) {
      if (isAttacked) {
          price = (len % 2 == 0) ? (len - design.price[attacker.type]) : (design.price[attacking.type] - len);
          if (len == 1) price *= 100;
      } else {
          price = design.price[attacking.type] - len;
          if (len % 2 == 0) price = (price / 2) | 0;
      }
  } else {
      if (isAttacked) {
          price = len - design.price[attacker.type];
          if (len == 1) price *= 100;
      }
  }
  return price;
}

var getChains = function(design, board) {
  var player = board.getValue(board.player);
  if (player === null) return [];
  if (_.isUndefined(board.chains)) {
      board.chains = [];
      var pieces   = getGoals(design, board);
      var targets  = getTargets(design, board, pieces);
      _.each(pieces, function(pos) {
          var goals = pieces; var f = true;
          var piece = board.getPiece(pos);
          if (piece === null) return;
          if (!chinese && (piece.type == 12)) {
              goals = targets;
              f = false;
          }
          var group  = [ pos ];
          var level  = [];
          level[pos] = 0;
          for (var i = 0; i < group.length; i++) {
              if (_.indexOf(goals.positions, group[i]) >= 0) {
                  if (!f || (group[i] != pos))   {
                      if (_.isUndefined(board.chains[pos])) {
                          board.chains[pos] = [];
                      }
                      var t = getTrace(design, board, pos, group[i], level);
                      if (!f) {
                          if (!_.isUndefined(goals.map[ group[i] ])) {
                              _.each(goals.map[ group[i] ], function(q) {
                                  var c = copy(t);
                                  c.push(q);
                                  var target = board.getPiece(q);
                                  if (target !== null) {
                                      board.chains[pos].push({
                                          trace: c,
                                          price: getChainPrice(design, board, piece, target, c.length)
                                      });
                                  }
                              });
                          }
                      } else {
                          var target = board.getPiece(group[i]);
                          if (target !== null) {
                              board.chains[pos].push({
                                  trace: t,
                                  price: getChainPrice(design, board, piece, target, t.length)
                              });
                          }
                      }
                  }
              }
              _.each(design.allDirections(), function(dir) {
                   p = design.navigate(board.player, group[i], dir);
                   while (p !== null) {
                        if (_.indexOf(group, p) >= 0) break;
                        group.push(p);
                        level[p] = level[ group[i] ] + 1;
                        if (f || (board.getPiece(p) !== null)) break;
                        p = design.navigate(board.player, p, dir);
                   }
              });
          }
      });
  }
  return board.chains;
}

var addWish = function(board, price, src, dst) {
  if (_.isUndefined(board.wish[src])) {
      board.wish[src] = [];
  }
  if (_.isUndefined(dst)) dst = src;
  board.wish[src][dst] = price;
}

var getWish = function(design, board) {
  if (_.isUndefined(board.wish)) {
      var player = board.getValue(board.player);
      if (player === null) return [];
      board.wish = [];
      // TODO: Use Chains

      if (board.wish.length == 0) {
          var pFriend = estimate(design, board, isFriend);
          if (pFriend > 30) {
              var pCannon = estimate(design, board, isPiece, 12);
              _.each(design.allPositions(), function(pos) {
                  var piece = board.getPiece(pos);
                  if ((piece !== null) && (piece.player != player) && (piece.type >= 7)) {
                      _.each(design.allDirections(), function(dir) {
                          var p = design.navigate(board.player, pos, dir);
                          if (p !== null) {
                              var x = board.getPiece(p);
                              if ((x !== null) && (x.type < 7)) {
                                  var r = estimate(design, board, isAttacker, piece.type);
                                  if (!chinese) {
                                      if (pCannon > 50) {
                                          r = 0;
                                      } else {
                                          if (piece.type == 12) r = 100;
                                      }
                                  }
                                  if (r > 50) {
                                      addWish(board, design.price[piece.type] * r, p);
                                  }
                              }
                              if (!chinese && (piece.type != 12)) {
                                  while (x === null) {
                                      p = design.navigate(board.player, p, dir);
                                      if (p === null) return;
                                      x = board.getPiece(p);
                                  }
                                  p = design.navigate(board.player, p, dir);
                                  if (p === null) return;
                                  x = board.getPiece(p);
                                  while (x === null) {
                                      p = design.navigate(board.player, p, dir);
                                      if (p === null) return;
                                      x = board.getPiece(p);
                                  }
                                  if (x.type < 7) {
                                      addWish(board, design.price[piece.type] * pCannon, p);
                                  }
                              }
                          }
                      });
                  }
              });
              var targets = []; var enemies = [];
              _.each(design.allPositions(), function(pos) {
                  if (!_.isUndefined(board.chains[pos])) {
                      var piece = board.getPiece(pos) {
                      if ((piece !== null) && (piece.player != player) && (piece.type >= 7)) {
                          _.each(board.chains[pos], function(chain) {
                              if (chain.trace.length == 1) {
                                  var p  = chain.trace[0];
                                  var ix = _.indexOf(targets, p);
                                  if (ix < 0) {
                                      ix = targets.length;
                                  }
                                  targets[ix] = p;
                                  if (_.isUndefined(enemies[ix]) || (enemies[ix] > piece.type)) {
                                      enemies[ix] = piece.type;
                                  }
                              }
                          });
                      }
                  }
              });
              for (var ix = 0; ix < targets.length; ix++) {
                  var pos     = targets[ix];
                  var emp     = [];
                  var piece   = board.getPiece(pos);
                  var pDefend = estimate(design, board, isDefender, enemies[ix], piece.type);
                  if (piece === null) continue;
                  _.each(design.allDirections(), function(dir) {
                      var p = design.navigate(board.player, pos, dir);
                      if (p !== null) {
                          var x = board.getPiece(p);
                          if (x !== null) {
                              if ((x.type < 7) && (pDefend > 50)) {
                                  addWish(board, design.price[piece.type], p);
                              }
                          } else {
                              emp.push(p);
                          }
                      }
                  });
                  _.each(emp, function(p) {
                      addWish(board, design.price[piece.type], pos, p);
                  });
              }
          }
      }
  }
  return board.wish;
}

Dagaz.AI.heuristic = function(ai, design, board, move) {
  var chains = getChains(design, board);
  var wish   = getWish(design, board);
  if (move.isSimpleMove() &&
      !_.isUndefined(wish[ move.actions[0][0][0] ]) &&
      !_.isUndefined(wish[ move.actions[0][0][0] ][ move.actions[0][1][0] ])) {
      return wish[ move.actions[0][0][0] ][ move.actions[0][1][0] ];
  }
  return 0;
}

var CheckInvariants = Dagaz.Model.CheckInvariants;

Dagaz.Model.CheckInvariants = function(board) {
  var design = board.game.design;
  _.each(board.moves, function(move) {
      if ((move.actions.length > 0) && (move.actions[0][0] !== null) && (move.actions[0][1] !== null) && (move.actions[0][0][0] != move.actions[0][1][0])) {
           var pos = move.actions[0][0][0];
           var piece = board.getPiece(pos);
           if (piece === null) return;
           _.each(move.actions, function(a) {
               if ((a[0] !== null) && (a[1] !== null) && (a[0][0] != a[1][0])) {
                   var target = board.getPiece(a[1][0]);
                   if (target === null) return;
                   if ((target.player == piece.player) || (target.type < 7)) {
                       move.failed = true;
                       return;
                   }
                   if (!chinese && (piece.type == 7) && (target.type == 13)) {
                       move.failed = true;
                       return;
                   }
                   if (target.type < piece.type) {
                       if ((piece.type == 13) && (target.type == 7)) return;
                       if (!chinese && (piece.type == 12) && (target.type >= 7)) return;
                       move.failed = true;
                       return;
                   }
               }
           });
      }
  });
  CheckInvariants(board);
}

})();
<commit_msg>BanQi (AI completed)<commit_after>(function() {

var chinese = false;

var checkVersion = Dagaz.Model.checkVersion;

Dagaz.Model.checkVersion = function(design, name, value) {
  if (name == "banqi-invariant") {
      if (value == "chinese") chinese = true;
  } else {
      checkVersion(design, name, value);
  }
}

var getShadow = function(design, board) {
  var player = board.getValue(board.player);
  if (player === null) return [];
  if (_.isUndefined(board.shadow)) {
      board.shadow = [];
      _.each(design.allPositions(), function(pos) {
           var piece = board.getPiece(pos);
           if ((piece !== null) && (piece.type < 7)) {
               var value = piece.type + 7;
               if (piece.player != player) {
                   value = -value;
               }
               board.shadow.push(value);
           }
      });
  }
  return board.shadow;
}

var isFriend = function(design, x) {
  return x > 0;
}

var isPiece = function(design, x, y) {
  return x == y;
}

var isAttacker = function(design, x, enemy) {
  if (x < 0) return false;
  if ((x == 13) && (enemy == 7)) return true;
  if (!chinese && (x == 7) && (enemy == 13)) return false;
  if (!chinese && (x == 12)) return false;
  return x <= enemy;
}

var isDefender = function(design, x, enemy, friend) {
  if (!isAttacker(design, x, enemy)) return false;
  return design.price[friend] <= design.price[enemy];
}

var estimate = function(design, board, p, y, z) {
  var shadow = getShadow(design, board);
  if (shadow.length == 0) return 0;
  var r = 0;
  _.each(shadow, function(x) {
      if (p(design, x, y, z)) r++;
  });
  return (100 * r) / shadow.length;
}

var getGoals = function(design, board) {
  var r = [];
  _.each(design.allPositions(), function(pos) {
      var piece = board.getPiece(pos);
      if ((piece !== null) && (piece.type >= 7)) {
          r.push(pos);
      }
  });
  return {
      positions: r
  };
}

var getTargets = function(design, board, goals) {
  var r = {
      positions: []
  };
  if (!chinese) {
      r.map = [];
      _.each(goals, function(pos) {
          _.each(design.allDirections(), function(dir) {
              var p = design.navigate(board.player, pos, dir);
              while (p !== null) {
                  if (board.getPiece(p) !== null) break;
                  p = design.navigate(board.player, p, dir);
              }
              p = design.navigate(board.player, p, dir);
              while (p !== null) {
                  var piece = board.getPiece(p);
                  if ((piece === null) || (piece.type == 12)) {
                      r.positions.push(p);
                      if (_.isUndefined(r.map[p])) {
                          r.map[p] = [];
                      }
                      r.map[p].push(pos);
                  }
                  if (piece !== null) break;
                  p = design.navigate(board.player, p, dir);
              }
          });
      });
  }
  return r;
}

var copy = function(list) {
  var r = [];
  _.each(list, function(x) {
      r.push(x);
  });
  return r;
}

var getTrace = function(design, board, src, dst, level) {
  var r = [];
  var pos = dst;
  while (pos !== null) {
      r.unshift(pos);
      var current = level[pos];
      if (current == 0) return r;
      var next = null;
      _.each(design.allDirections(), function(dir) {
          if (next === null) {
              var p = design.navigate(board.player, pos, dir);
              while (p !== null) {
                  if (_.isUndefined(level[p])) break;
                  if (level[p] < current) {
                      next = p;
                      break;
                  }
                  if (level[p] > current) break;
                  p = design.navigate(board.player, p, dir);
              }
          }
      });
      pos = next;
  }
  return null;
}

var getChainPrice = function(design, board, attacker, attacking, len) {
  if ((attacker == null) || (attacking === null)) return 0;
  if (attacker.player == attacking.player) return 0;
  var isAttacking = isAttacker(design, attacker.type, attacking.type);
  var isAttacked  = isAttacker(design, attacking.type, attacker.type);
  if (!chinese && (attacker.type == 12)) {
      isAttacking = true;
      isAttacked  = (attacking.type == attacker.type) && (len == 1);
  }
  var price = 0;
  if (isAttacking) {
      if (isAttacked) {
          price = (len % 2 == 0) ? (len - design.price[attacker.type]) : (design.price[attacking.type] - len);
          if (len == 1) price *= 100;
      } else {
          price = design.price[attacking.type] - len;
          if (len % 2 == 0) price = (price / 2) | 0;
      }
  } else {
      if (isAttacked) {
          price = len - design.price[attacker.type];
          if (len == 1) price *= 100;
      }
  }
  return price;
}

var getChains = function(design, board) {
  var player = board.getValue(board.player);
  if (player === null) return [];
  if (_.isUndefined(board.chains)) {
      board.chains = [];
      var pieces   = getGoals(design, board);
      var targets  = getTargets(design, board, pieces);
      _.each(pieces, function(pos) {
          var goals = pieces; var f = true;
          var piece = board.getPiece(pos);
          if (piece === null) return;
          if (!chinese && (piece.type == 12)) {
              goals = targets;
              f = false;
          }
          var group  = [ pos ];
          var level  = [];
          level[pos] = 0;
          for (var i = 0; i < group.length; i++) {
              if (_.indexOf(goals.positions, group[i]) >= 0) {
                  if (!f || (group[i] != pos))   {
                      if (_.isUndefined(board.chains[pos])) {
                          board.chains[pos] = [];
                      }
                      var t = getTrace(design, board, pos, group[i], level);
                      if (!f) {
                          if (!_.isUndefined(goals.map[ group[i] ])) {
                              _.each(goals.map[ group[i] ], function(q) {
                                  var c = copy(t);
                                  c.push(q);
                                  var target = board.getPiece(q);
                                  if (target !== null) {
                                      var price = getChainPrice(design, board, piece, target, c.length);
                                      board.chains[pos].push({
                                          trace: c,
                                          price: price
                                      });
                                      console.log("Chain[C]: " + chainToStr(c) + ", price = " + price);
                                  }
                              });
                          }
                      } else {
                          var target = board.getPiece(group[i]);
                          if (target !== null) {
                              var price = getChainPrice(design, board, piece, target, t.length);
                              board.chains[pos].push({
                                  trace: t,
                                  price: price
                              });
                              console.log("Chain[L]: " + chainToStr(t) + ", price = " + price);
                          }
                      }
                  }
              }
              _.each(design.allDirections(), function(dir) {
                   p = design.navigate(board.player, group[i], dir);
                   while (p !== null) {
                        if (_.indexOf(group, p) >= 0) break;
                        group.push(p);
                        level[p] = level[ group[i] ] + 1;
                        if (f || (board.getPiece(p) !== null)) break;
                        p = design.navigate(board.player, p, dir);
                   }
              });
          }
      });
  }
  return board.chains;
}

var addWish = function(board, comment, price, src, dst) {
  if (_.isUndefined(board.wish[src])) {
      board.wish[src] = [];
  }
  if (_.isUndefined(dst)) dst = src;
  if (_.isUndefined(board.wish[src][dst])) {
      board.wish[src][dst] = price;
  } else {
      board.wish[src][dst] += price;
  }
  console.log("Wish [" + comment + "]: " + Dagaz.Model.posToString(src) + " - " + Dagaz.Model.posToString(dst) + " = " + price);
}

var getWish = function(design, board) {
  if (_.isUndefined(board.wish)) {
      var player = board.getValue(board.player);
      if (player === null) return [];
      var chains   = getChains(design, board);
      board.wish   = [];
      var attacks  = [];
      _.each(design.allPositions(), function(pos) {
          if (!_.isUndefined(chains[pos])) {
              var piece = board.getPiece(pos);
              if ((piece === null) || (piece.type < 7)) return;
              if (piece.player == player) {
                  _.each(chains[pos], function(chain) {
                      if (chain.trace.length == 0) return;
                      var price = chain.price;
                      if (chain.trace.length == 1) price *= 10;
                      if ((chain.trace.length > 3) && (price > 0)) price /= 10;
                      addWish(board, "1", price, pos, chain.trace[0]);
                  });
              } else {
                  var len = _.chain(chains[pos]).map(function(chain) {
                      return chain.trace.length;
                  }).min().value();
                  if ((len > 1) && (len < 4)) {
                      attacks.push(pos);
                  }
              }
          }
      });
      if (board.wish.length == 0) {
          var pFriend = estimate(design, board, isFriend);
          if (pFriend > 30) {
              var pCannon = estimate(design, board, isPiece, 12);
              var chain   = null;
              var maxp    = 0;
              _.each(attacks, function(pos) {
                  var piece = board.getPiece(pos);
                  if ((piece !== null) && (piece.player != player)) {
                      var p = estimate(design, board, isAttacker, piece.type);
                      if (p > 30) {
                          if ((chain === null) || (p > maxp)) {
                               chain = _.min(chains[pos], function(chain) {
                                   return chain.trace.length;
                               });
                               maxp  = p;
                          }
                      }
                  }
              });
              if ((chain !== null) && (maxp > 50)) {
                 for (var ix = 0; ix < chain.trace - 1; ix++) {
                     _.each(design.allDirections(), function(dir) {
                          var p = design.navigate(board.player, chain.trace[ix], dir);
                          if (p !== null) {
                              var piece = board.getPiece(p);
                              if ((piece !== null) && (piece.type < 7)) {
                                  addWish(board, "2", chain.price * maxp, p);
                              }
                          }
                     });
                 }
              }
              _.each(design.allPositions(), function(pos) {
                  var piece = board.getPiece(pos);
                  if ((piece !== null) && (piece.player != player) && (piece.type >= 7)) {
                      _.each(design.allDirections(), function(dir) {
                          var p = design.navigate(board.player, pos, dir);
                          if (p !== null) {
                              var x = board.getPiece(p);
                              if ((x !== null) && (x.type < 7)) {
                                  var r = estimate(design, board, isAttacker, piece.type);
                                  if (!chinese) {
                                      if (pCannon > 50) {
                                          r = 0;
                                      } else {
                                          if (piece.type == 12) r = 100;
                                      }
                                  }
                                  if (r > 50) {
                                      addWish(board, "3", design.price[piece.type] * r, p);
                                  }
                              }
                              if (!chinese && (piece.type != 12)) {
                                  while (x === null) {
                                      p = design.navigate(board.player, p, dir);
                                      if (p === null) return;
                                      x = board.getPiece(p);
                                  }
                                  p = design.navigate(board.player, p, dir);
                                  if (p === null) return;
                                  x = board.getPiece(p);
                                  while (x === null) {
                                      p = design.navigate(board.player, p, dir);
                                      if (p === null) return;
                                      x = board.getPiece(p);
                                  }
                                  if (x.type < 7) {
                                      addWish(board, "4", design.price[piece.type] * pCannon, p);
                                  }
                              }
                          }
                      });
                  }
              });
              var targets = []; var enemies = [];
              _.each(design.allPositions(), function(pos) {
                  if (!_.isUndefined(chains[pos])) {
                      var piece = board.getPiece(pos) {
                      if ((piece !== null) && (piece.player != player) && (piece.type >= 7)) {
                          _.each(chains[pos], function(chain) {
                              if (chain.trace.length == 1) {
                                  var p  = chain.trace[0];
                                  var ix = _.indexOf(targets, p);
                                  if (ix < 0) {
                                      ix = targets.length;
                                  }
                                  targets[ix] = p;
                                  if (_.isUndefined(enemies[ix]) || (enemies[ix] > piece.type)) {
                                      enemies[ix] = piece.type;
                                  }
                              }
                          });
                      }
                  }
              });
              for (var ix = 0; ix < targets.length; ix++) {
                  var pos     = targets[ix];
                  var emp     = [];
                  var piece   = board.getPiece(pos);
                  var pDefend = estimate(design, board, isDefender, enemies[ix], piece.type);
                  if (piece === null) continue;
                  _.each(design.allDirections(), function(dir) {
                      var p = design.navigate(board.player, pos, dir);
                      if (p !== null) {
                          var x = board.getPiece(p);
                          if (x !== null) {
                              if ((x.type < 7) && (pDefend > 50)) {
                                  addWish(board, "5", design.price[piece.type], p);
                              }
                          } else {
                              emp.push(p);
                          }
                      }
                  });
                  _.each(emp, function(p) {
                      addWish(board, "6", design.price[piece.type], pos, p);
                  });
              }
          }
      }
  }
  return board.wish;
}

Dagaz.AI.heuristic = function(ai, design, board, move) {
  var wish = getWish(design, board);
  if (move.isSimpleMove() &&
      !_.isUndefined(wish[ move.actions[0][0][0] ]) &&
      !_.isUndefined(wish[ move.actions[0][0][0] ][ move.actions[0][1][0] ])) {
      return wish[ move.actions[0][0][0] ][ move.actions[0][1][0] ];
  }
  return 0;
}

var CheckInvariants = Dagaz.Model.CheckInvariants;

Dagaz.Model.CheckInvariants = function(board) {
  var design = board.game.design;
  _.each(board.moves, function(move) {
      if ((move.actions.length > 0) && (move.actions[0][0] !== null) && (move.actions[0][1] !== null) && (move.actions[0][0][0] != move.actions[0][1][0])) {
           var pos = move.actions[0][0][0];
           var piece = board.getPiece(pos);
           if (piece === null) return;
           _.each(move.actions, function(a) {
               if ((a[0] !== null) && (a[1] !== null) && (a[0][0] != a[1][0])) {
                   var target = board.getPiece(a[1][0]);
                   if (target === null) return;
                   if ((target.player == piece.player) || (target.type < 7)) {
                       move.failed = true;
                       return;
                   }
                   if (!chinese && (piece.type == 7) && (target.type == 13)) {
                       move.failed = true;
                       return;
                   }
                   if (target.type < piece.type) {
                       if ((piece.type == 13) && (target.type == 7)) return;
                       if (!chinese && (piece.type == 12) && (target.type >= 7)) return;
                       move.failed = true;
                       return;
                   }
               }
           });
      }
  });
  CheckInvariants(board);
}

})();
<|endoftext|>


<commit_before>import Vue from 'vue'
import { test } from '~util/testing'
import VDataTable from './VDataTable'

test('VDataTable.js', ({ mount }) => {
  it('should be able to filter null and undefined values', async () => {
    const pagination = {
      descending: false,
      sortBy: 'column'
    }
    const wrapper = mount(VDataTable, {
      propsData: {
        pagination,
        headers: [
          { text: 'Other', value: 'other' },
          { text: 'Column', value: 'column' }
        ],
        items: [
          { other: 1, column: 'foo' },
          { other: 2, column: null },
          { other: 3, column: undefined }
        ]
      }
    })

    await wrapper.vm.$nextTick()

    pagination.descending = true

    expect(wrapper.vm.$props.pagination.descending).toBe(true)
    expect('Application is missing <v-app> component.').toHaveBeenTipped()
    // Also expect tests to not crash :)
  })

/* avoriaz needs to support scoped slots
  it('should emit pagination object with correct items length', async () => {
    const vm = new Vue()
    const wrapper = mount(VDataTable, {
      propsData: {
        pagination: {},
        headers: [
          { text: 'First', value: 'first' },
          { text: 'Second', value: 'first' }
        ],
        items: [
          { first: 1, second: 'foo' },
          { first: 2, second: 'bar' },
          { first: 3, second: 'baz' }
        ]
      },
      scopedSlots: {
        items: (props) => vm.createElement('td', [props.item.first])
      }
    })

    const change = jest.fn()
    wrapper.instance().$on('update:pagination', change)

    wrapper.setProps({ search: 'f' })

    await wrapper.vm.$nextTick()

    expect('Application is missing <v-app> component.').toHaveBeenTipped()
    expect(change).toBeCalledWith({ page: 1, totalItems: 1 })
  })
*/
})
<commit_msg>Fixed lint error<commit_after>// import Vue from 'vue'
import { test } from '~util/testing'
import VDataTable from './VDataTable'

test('VDataTable.js', ({ mount }) => {
  it('should be able to filter null and undefined values', async () => {
    const pagination = {
      descending: false,
      sortBy: 'column'
    }
    const wrapper = mount(VDataTable, {
      propsData: {
        pagination,
        headers: [
          { text: 'Other', value: 'other' },
          { text: 'Column', value: 'column' }
        ],
        items: [
          { other: 1, column: 'foo' },
          { other: 2, column: null },
          { other: 3, column: undefined }
        ]
      }
    })

    await wrapper.vm.$nextTick()

    pagination.descending = true

    expect(wrapper.vm.$props.pagination.descending).toBe(true)
    expect('Application is missing <v-app> component.').toHaveBeenTipped()
    // Also expect tests to not crash :)
  })

/* avoriaz needs to support scoped slots
  it('should emit pagination object with correct items length', async () => {
    const vm = new Vue()
    const wrapper = mount(VDataTable, {
      propsData: {
        pagination: {},
        headers: [
          { text: 'First', value: 'first' },
          { text: 'Second', value: 'first' }
        ],
        items: [
          { first: 1, second: 'foo' },
          { first: 2, second: 'bar' },
          { first: 3, second: 'baz' }
        ]
      },
      scopedSlots: {
        items: (props) => vm.createElement('td', [props.item.first])
      }
    })

    const change = jest.fn()
    wrapper.instance().$on('update:pagination', change)

    wrapper.setProps({ search: 'f' })

    await wrapper.vm.$nextTick()

    expect('Application is missing <v-app> component.').toHaveBeenTipped()
    expect(change).toBeCalledWith({ page: 1, totalItems: 1 })
  })
*/
})
<|endoftext|>


<commit_before>define(["pilotstats/RangeFilter"], function(RangeFilter)
{
    "use strict";
    QUnit.module("RangeFilter");

    QUnit.test("RangeFilter()", function(assert)
    {
        // Setup.
        var columnKey = "pilotSkill";
        var isMinEnabled = false;
        var minValue = 1;
        var isMaxEnabled = false;
        var maxValue = 10;

        // Run.
        var result = new RangeFilter(columnKey, isMinEnabled, minValue, isMaxEnabled, maxValue);

        // Verify.
        assert.equal(result.columnKey(), columnKey);
        assert.equal(result.isMinEnabled(), isMinEnabled);
        assert.equal(result.minValue(), minValue);
        assert.equal(result.isMaxEnabled(), isMaxEnabled);
        assert.equal(result.maxValue(), maxValue);
    });

    QUnit.test("RangeFilter()", function(assert)
    {
        // Setup.
        var columnKey = "pilotSkill";
        var isMinEnabled = false;
        var minValue = 1;
        var isMaxEnabled = false;
        var maxValue = 10;
        var data = {
            pilotSkill: 5,
        };

        // Run / Verify.
        assert.ok((new RangeFilter(columnKey, isMinEnabled, minValue, isMaxEnabled, maxValue)).passes(data));
        assert.ok((new RangeFilter("bogus", isMinEnabled, minValue, isMaxEnabled, maxValue)).passes(data));
        assert.ok((new RangeFilter(columnKey, true, minValue, isMaxEnabled, maxValue)).passes(data));
        assert.ok((new RangeFilter(columnKey, isMinEnabled, 6, isMaxEnabled, maxValue)).passes(data));
        assert.ok((new RangeFilter(columnKey, isMinEnabled, minValue, true, maxValue)).passes(data));
        assert.ok((new RangeFilter(columnKey, isMinEnabled, minValue, isMaxEnabled, 4)).passes(data));

        assert.ok(!(new RangeFilter(columnKey, true, 6, isMaxEnabled, maxValue)).passes(data));
        assert.ok(!(new RangeFilter(columnKey, isMinEnabled, minValue, true, 4)).passes(data));
    });
});
<commit_msg>Changed to save the filters to local storage.<commit_after>define(["pilotstats/RangeFilter"], function(RangeFilter)
{
    "use strict";
    QUnit.module("RangeFilter");

    QUnit.test("RangeFilter()", function(assert)
    {
        // Setup.
        var columnKey = "pilotSkill";
        var isMinEnabled = false;
        var minValue = 1;
        var isMaxEnabled = false;
        var maxValue = 10;

        // Run.
        var result = new RangeFilter(columnKey, isMinEnabled, minValue, isMaxEnabled, maxValue);

        // Verify.
        assert.equal(result.columnKey(), columnKey);
        assert.equal(result.isMinEnabled(), isMinEnabled);
        assert.equal(result.minValue(), minValue);
        assert.equal(result.isMaxEnabled(), isMaxEnabled);
        assert.equal(result.maxValue(), maxValue);
    });

    QUnit.test("RangeFilter.fromObject()", function(assert)
    {
        // Setup.
        var object = {
            type: "RangeFilter",
            columnKey: "pilotSkill",
            isMinEnabled: false,
            minValue: 1,
            isMaxEnabled: true,
            maxValue: 10,
        };

        // Run.
        var result = RangeFilter.fromObject(object);

        // Verify.
        assert.ok(result);
        assert.equal(result.columnKey(), "pilotSkill");
        assert.equal(result.isMinEnabled(), false);
        assert.equal(result.minValue(), 1);
        assert.equal(result.isMaxEnabled(), true);
        assert.equal(result.maxValue(), 10);
    });

    QUnit.test("passes()", function(assert)
    {
        // Setup.
        var columnKey = "pilotSkill";
        var isMinEnabled = false;
        var minValue = 1;
        var isMaxEnabled = false;
        var maxValue = 10;
        var data = {
            pilotSkill: 5,
        };

        // Run / Verify.
        assert.ok((new RangeFilter(columnKey, isMinEnabled, minValue, isMaxEnabled, maxValue)).passes(data));
        assert.ok((new RangeFilter("bogus", isMinEnabled, minValue, isMaxEnabled, maxValue)).passes(data));
        assert.ok((new RangeFilter(columnKey, true, minValue, isMaxEnabled, maxValue)).passes(data));
        assert.ok((new RangeFilter(columnKey, isMinEnabled, 6, isMaxEnabled, maxValue)).passes(data));
        assert.ok((new RangeFilter(columnKey, isMinEnabled, minValue, true, maxValue)).passes(data));
        assert.ok((new RangeFilter(columnKey, isMinEnabled, minValue, isMaxEnabled, 4)).passes(data));

        assert.ok(!(new RangeFilter(columnKey, true, 6, isMaxEnabled, maxValue)).passes(data));
        assert.ok(!(new RangeFilter(columnKey, isMinEnabled, minValue, true, 4)).passes(data));
    });

    QUnit.test("toObject()", function(assert)
    {
        // Setup.
        var columnKey = "factionKey";
        var isMinEnabled = false;
        var minValue = 1;
        var isMaxEnabled = true;
        var maxValue = 10;
        var filter = new RangeFilter(columnKey, isMinEnabled, minValue, isMaxEnabled, maxValue);

        // Run.
        var result = filter.toObject();

        // Verify.
        assert.ok(result);
        assert.equal(result.type, "RangeFilter");
        assert.equal(result.columnKey, columnKey);
        assert.equal(result.isMinEnabled, isMinEnabled);
        assert.equal(result.minValue, minValue);
        assert.equal(result.isMaxEnabled, isMaxEnabled);
        assert.equal(result.maxValue, maxValue);
    });
});
<|endoftext|>