<commit_before>// Visual concepts
// - timeline: the sequence and all channels
// - sequence: the state of the cells in the timeline
// - channel: a dimension of each time frame
// - frame: a state of each channel at a given time
// - cell: a state of a channel at a given time
const mcbsp = require('mcbsp');
const way = require('senseway');

const clearElem = (el) => {
  while(el.firstChild){
    el.removeChild(el.firstChild);
  }
  return el;
};

const createPredictionDistanceControl = (model, dispatch) => {
  const control = document.createElement('div');

  const input = document.createElement('input');
  input.type = 'range';
  input.value = model.predictionDistance;
  input.name = 'predictionDistance';
  input.min = '1';
  input.max = '16';
  input.step = '1';

  input.addEventListener('change', (ev) => {
    dispatch({
      type: 'SET_PREDICTION_DISTANCE',
      value: parseInt(input.value)
    });
  });

  const label = document.createElement('label');
  label.for = 'predictionDistance';
  label.innerHTML = model.predictionDistance + ' Prediction Distance';

  control.appendChild(input);
  control.appendChild(label);

  return control;
};

const createContextDistanceControl = (model, dispatch) => {
  const control = document.createElement('div');

  const input = document.createElement('input');
  input.type = 'range';
  input.value = model.contextDistance;
  input.name = 'contextDistance';
  input.min = '1';
  input.max = '16';
  input.step = '1';

  input.addEventListener('change', (ev) => {
    dispatch({
      type: 'SET_CONTEXT_DISTANCE',
      value: parseInt(input.value)
    });
  });

  const label = document.createElement('label');
  label.for = 'contextDistance';
  label.innerHTML = model.contextDistance + ' Context Distance';

  control.appendChild(input);
  control.appendChild(label);

  return control;
};

const createPredictionControlsElem = (model, dispatch) => {
  const controls = document.createElement('div');

  const contextDistanceElem = createContextDistanceControl(model, dispatch);
  controls.appendChild(contextDistanceElem);

  const predDistanceElem = createPredictionDistanceControl(model, dispatch);
  controls.appendChild(predDistanceElem);

  return controls;
};

const createChannelControlsElem = (model, dispatch) => {
  const controls = document.createElement('div');
  model.history.forEach((channel, i) => {
    const audio = document.createElement('div');
    audio.classList.add('channel-control');
    audio.dataset.channel = i;

    const img = document.createElement('img');
    img.width = 16;
    img.height = 16;
    img.src = 'img/audio.png';
    audio.appendChild(img);

    controls.appendChild(audio);
  });

  return controls;
};

const createFrameElem = (t) => {
  const f = document.createElement('div');
  f.dataset.time = t;
  f.classList.add('frame');

  const label = document.createElement('div');
  label.classList.add('frame-label');
  if (t % 4 === 0) {
    label.innerHTML = t.toString(10);
  } else {
    label.innerHTML = '';
  }
  f.appendChild(label);

  return f;
};

const createCellRowElem = (t) => {
  const r = document.createElement('div');
  r.dataset.time = t;
  r.classList.add('cellrow');
  return r;
};

const createDeleteFrameElem = (t, dispatch) => {
  const b = document.createElement('button');
  b.innerHTML = 'del';

  b.addEventListener('click', () => {
    dispatch({
      type: 'REMOVE_FRAME',
      time: t
    });
  });

  return b;
};

const createDuplicateFrameElem = (t, dispatch) => {
  const b = document.createElement('button');
  b.innerHTML = 'duplicate';

  b.addEventListener('click', () => {
    dispatch({
      type: 'DUPLICATE_FRAME',
      time: t
    });
  });

  return b;
};

const createCellElem = (t, ch, value, numChannels) => {
  const cel = document.createElement('div');
  cel.dataset.time = t;
  cel.dataset.channel = ch;
  cel.dataset.value = value;
  cel.classList.add('cell');

  const probStr = ((1 - value) * 100).toFixed(0) + '%';
  cel.style.backgroundColor = 'hsl(0,0%,' + probStr + ')';

  cel.title = value;

  cel.classList.add('cell-ch' + numChannels);

  return cel;
};

const bindCellElem = (cel, dispatch) => {
  cel.addEventListener('click', () => {
    dispatch({
      type: 'SET_VALUE',
      time: cel.dataset.time,
      channel: cel.dataset.channel,
      value: parseFloat(cel.dataset.value) > 0.5 ? 0 : 1 // invert
    });
  });
};

const createTimelineElem = (model, dispatch) => {
  const timeline = document.createElement('div');
  const channels = model.history.length;
  const duration = model.history[0].length;

  let t, ch, cel, val, fr, cr;
  for (t = 0; t < duration; t += 1) {
    fr = createFrameElem(t);
    cr = createCellRowElem(t);

    if (t >= duration - model.contextDistance) {
      fr.classList.add('frame-context');
    }

    for (ch = 0; ch < channels; ch += 1) {
      val = model.history[ch][t];
      cel = createCellElem(t, ch, val, channels);
      cel.classList.add('cell-history');
      bindCellElem(cel, dispatch)
      cr.appendChild(cel);
    }
    fr.appendChild(cr);

    fr.appendChild(createDeleteFrameElem(t, dispatch));
    fr.appendChild(createDuplicateFrameElem(t, dispatch));

    timeline.appendChild(fr);
  }

  return timeline;
};

const createPredictedTimelineElem = (model, dispatch) => {
  const timeline = document.createElement('div');
  const distance = model.predictionDistance;
  const channels = model.history.length;
  const currentTime = model.history[0].length;

  const prediction = predict(model);

  let t, ch, cel, val, fr, cr;
  for (t = 0; t < distance; t += 1) {
    fr = createFrameElem(currentTime + t);
    cr = createCellRowElem(currentTime + t);

    fr.classList.add('prediction');

    for (ch = 0; ch < channels; ch += 1) {
      val = prediction[ch][t];
      cel = createCellElem(t, ch, val, channels);
      cel.classList.add('cell-prediction');
      cr.appendChild(cel);
    }
    fr.appendChild(cr);

    timeline.appendChild(fr);
  }

  return timeline;
};

const historySetValue = (hist, ev) => {
  const newHist = way.clone(hist);
  newHist[ev.channel][ev.time] = ev.value;
  return newHist;
}

const historyDuplicateFrame = (hist, t) => {
  const newHist = way.clone(hist);
  newHist.map((ch, i) => {
    const cellValue = ch[t];
    return ch.splice(t, 0, cellValue);
  });
  return newHist;
};

const historyRemoveFrame = (hist, t) => {
  const newHist = way.clone(hist);
  newHist.map((ch) => {
    return ch.splice(t, 1);
  });
  return newHist;
};

const predict = (model) => {
  let contextDistance = model.contextDistance;
  let distance = model.predictionDistance;
  let t = model.history[0].length;
  let context = way.before(model.history, t, contextDistance);
  let pred = mcbsp.predict(model.history, context, distance);
  return pred.probabilities;
};

{
  const initialModel = {
    history: [
      [1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0], // sun up
      [0,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0], // flower open
      [0,1,1,1,0,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0],
      [0,1,1,1,0,1,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,1,0,0],
      [0,0,0,1,0,0,0,0,1,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0],
      [0,1,0,1,0,1,1,0,0,0,1,1,0,0,0,1,1,0,1,0,0,1,0,0]
    ],
    contextDistance: 8,
    predictionDistance: 8,
  };
  let currentModel = initialModel;

  const reducer = (model, ev) => {
    switch (ev.type) {

      case 'SET_CONTEXT_DISTANCE': {
        return Object.assign({}, model, {
          contextDistance: ev.value
        });
      }

      case 'SET_PREDICTION_DISTANCE': {
        return Object.assign({}, model, {
          predictionDistance: ev.value
        });
      }

      case 'SET_VALUE': {
        return Object.assign({}, model, {
          history: historySetValue(model.history, ev)
        });
      }

      case 'DUPLICATE_FRAME': {
        return Object.assign({}, model, {
          history: historyDuplicateFrame(model.history, ev.time)
        });
      }

      case 'REMOVE_FRAME': {
        return Object.assign({}, model, {
          history: historyRemoveFrame(model.history, ev.time)
        });
      }

      default:
        return model;
    }
  };

  const render = (model) => {
    const container = document.getElementById('timeline');
    clearElem(container);

    const predictionControls = createPredictionControlsElem(model, dispatch);
    container.appendChild(predictionControls);

    const channelControls = createChannelControlsElem(model, dispatch);
    container.appendChild(channelControls);

    const timeline = createTimelineElem(model, dispatch);
    container.appendChild(timeline);

    const predictedTimeline = createPredictedTimelineElem(model, dispatch);
    container.appendChild(predictedTimeline);
  };

  const dispatch = (ev) => {
    const newModel = reducer(currentModel, ev);
    render(newModel);
    currentModel = newModel;
  };

  // Init
  render(initialModel);
};
<commit_msg>Some synthetic datasets for dev<commit_after>// Visual concepts
// - timeline: the sequence and all channels
// - sequence: the state of the cells in the timeline
// - channel: a dimension of each time frame
// - frame: a state of each channel at a given time
// - cell: a state of a channel at a given time
const mcbsp = require('mcbsp');
const way = require('senseway');

const clearElem = (el) => {
  while(el.firstChild){
    el.removeChild(el.firstChild);
  }
  return el;
};

const createPredictionDistanceControl = (model, dispatch) => {
  const control = document.createElement('div');

  const input = document.createElement('input');
  input.type = 'range';
  input.value = model.predictionDistance;
  input.name = 'predictionDistance';
  input.min = '1';
  input.max = '16';
  input.step = '1';

  input.addEventListener('change', (ev) => {
    dispatch({
      type: 'SET_PREDICTION_DISTANCE',
      value: parseInt(input.value)
    });
  });

  const label = document.createElement('label');
  label.for = 'predictionDistance';
  label.innerHTML = model.predictionDistance + ' Prediction Distance';

  control.appendChild(input);
  control.appendChild(label);

  return control;
};

const createContextDistanceControl = (model, dispatch) => {
  const control = document.createElement('div');

  const input = document.createElement('input');
  input.type = 'range';
  input.value = model.contextDistance;
  input.name = 'contextDistance';
  input.min = '1';
  input.max = '16';
  input.step = '1';

  input.addEventListener('change', (ev) => {
    dispatch({
      type: 'SET_CONTEXT_DISTANCE',
      value: parseInt(input.value)
    });
  });

  const label = document.createElement('label');
  label.for = 'contextDistance';
  label.innerHTML = model.contextDistance + ' Context Distance';

  control.appendChild(input);
  control.appendChild(label);

  return control;
};

const createPredictionControlsElem = (model, dispatch) => {
  const controls = document.createElement('div');

  const contextDistanceElem = createContextDistanceControl(model, dispatch);
  controls.appendChild(contextDistanceElem);

  const predDistanceElem = createPredictionDistanceControl(model, dispatch);
  controls.appendChild(predDistanceElem);

  return controls;
};

const createChannelControlsElem = (model, dispatch) => {
  const controls = document.createElement('div');
  model.history.forEach((channel, i) => {
    const audio = document.createElement('div');
    audio.classList.add('channel-control');
    audio.dataset.channel = i;

    const img = document.createElement('img');
    img.width = 16;
    img.height = 16;
    img.src = 'img/audio.png';
    audio.appendChild(img);

    controls.appendChild(audio);
  });

  return controls;
};

const createFrameElem = (t) => {
  const f = document.createElement('div');
  f.dataset.time = t;
  f.classList.add('frame');

  const label = document.createElement('div');
  label.classList.add('frame-label');
  if (t % 4 === 0) {
    label.innerHTML = t.toString(10);
  } else {
    label.innerHTML = '';
  }
  f.appendChild(label);

  return f;
};

const createCellRowElem = (t) => {
  const r = document.createElement('div');
  r.dataset.time = t;
  r.classList.add('cellrow');
  return r;
};

const createDeleteFrameElem = (t, dispatch) => {
  const b = document.createElement('button');
  b.innerHTML = 'del';

  b.addEventListener('click', () => {
    dispatch({
      type: 'REMOVE_FRAME',
      time: t
    });
  });

  return b;
};

const createDuplicateFrameElem = (t, dispatch) => {
  const b = document.createElement('button');
  b.innerHTML = 'duplicate';

  b.addEventListener('click', () => {
    dispatch({
      type: 'DUPLICATE_FRAME',
      time: t
    });
  });

  return b;
};

const createCellElem = (t, ch, value, numChannels) => {
  const cel = document.createElement('div');
  cel.dataset.time = t;
  cel.dataset.channel = ch;
  cel.dataset.value = value;
  cel.classList.add('cell');

  const probStr = ((1 - value) * 100).toFixed(0) + '%';
  cel.style.backgroundColor = 'hsl(0,0%,' + probStr + ')';

  cel.title = value;

  cel.classList.add('cell-ch' + numChannels);

  return cel;
};

const bindCellElem = (cel, dispatch) => {
  cel.addEventListener('click', () => {
    dispatch({
      type: 'SET_VALUE',
      time: cel.dataset.time,
      channel: cel.dataset.channel,
      value: parseFloat(cel.dataset.value) > 0.5 ? 0 : 1 // invert
    });
  });
};

const createTimelineElem = (model, dispatch) => {
  const timeline = document.createElement('div');
  const channels = model.history.length;
  const duration = model.history[0].length;

  let t, ch, cel, val, fr, cr;
  for (t = 0; t < duration; t += 1) {
    fr = createFrameElem(t);
    cr = createCellRowElem(t);

    if (t >= duration - model.contextDistance) {
      fr.classList.add('frame-context');
    }

    for (ch = 0; ch < channels; ch += 1) {
      val = model.history[ch][t];
      cel = createCellElem(t, ch, val, channels);
      cel.classList.add('cell-history');
      bindCellElem(cel, dispatch)
      cr.appendChild(cel);
    }
    fr.appendChild(cr);

    fr.appendChild(createDeleteFrameElem(t, dispatch));
    fr.appendChild(createDuplicateFrameElem(t, dispatch));

    timeline.appendChild(fr);
  }

  return timeline;
};

const createPredictedTimelineElem = (model, dispatch) => {
  const timeline = document.createElement('div');
  const distance = model.predictionDistance;
  const channels = model.history.length;
  const currentTime = model.history[0].length;

  const prediction = predict(model);

  let t, ch, cel, val, fr, cr;
  for (t = 0; t < distance; t += 1) {
    fr = createFrameElem(currentTime + t);
    cr = createCellRowElem(currentTime + t);

    fr.classList.add('prediction');

    for (ch = 0; ch < channels; ch += 1) {
      val = prediction[ch][t];
      cel = createCellElem(t, ch, val, channels);
      cel.classList.add('cell-prediction');
      cr.appendChild(cel);
    }
    fr.appendChild(cr);

    timeline.appendChild(fr);
  }

  return timeline;
};

const historySetValue = (hist, ev) => {
  const newHist = way.clone(hist);
  newHist[ev.channel][ev.time] = ev.value;
  return newHist;
}

const historyDuplicateFrame = (hist, t) => {
  const newHist = way.clone(hist);
  newHist.map((ch, i) => {
    const cellValue = ch[t];
    return ch.splice(t, 0, cellValue);
  });
  return newHist;
};

const historyRemoveFrame = (hist, t) => {
  const newHist = way.clone(hist);
  newHist.map((ch) => {
    return ch.splice(t, 1);
  });
  return newHist;
};

const predict = (model) => {
  let contextDistance = model.contextDistance;
  let distance = model.predictionDistance;
  let t = model.history[0].length;
  let context = way.before(model.history, t, contextDistance);
  let pred = mcbsp.predict(model.history, context, distance);
  return pred.probabilities;
};

{

  const FLOWER = [
    [1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0], // sun up
    [0,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0], // flower open
    [0,1,1,1,0,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0],
    [0,1,1,1,0,1,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,1,0,0],
    [0,0,0,1,0,0,0,0,1,1,1,0,0,0,0,1,1,0,1,0,0,1,0,0],
    [0,1,0,1,0,1,1,0,0,0,1,1,0,0,0,1,1,0,1,0,0,1,0,0]
  ];

  const SHEAR16 = [
    [1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0], // sun up
    [0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0], // flower open
    [0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0],
    [0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0],
    [0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],
    [0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1]
  ];

  const SHEAR36 = [
    [1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0], // sun up
    [0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0], // flower open
    [0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0],
    [0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1],
    [1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1],
    [1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1]
  ];

  const SHEAR56 = [
    [1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0], // sun up
    [0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1], // flower open
    [1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1],
    [1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1],
    [1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1],
    [1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1]
  ];

  const NOISE = way.map(way.create(6, 24, 0), q => Math.random());

  const initialModel = {
    history: FLOWER,
    contextDistance: 8,
    predictionDistance: 8,
  };
  let currentModel = initialModel;

  const reducer = (model, ev) => {
    switch (ev.type) {

      case 'SET_CONTEXT_DISTANCE': {
        return Object.assign({}, model, {
          contextDistance: ev.value
        });
      }

      case 'SET_PREDICTION_DISTANCE': {
        return Object.assign({}, model, {
          predictionDistance: ev.value
        });
      }

      case 'SET_VALUE': {
        return Object.assign({}, model, {
          history: historySetValue(model.history, ev)
        });
      }

      case 'DUPLICATE_FRAME': {
        return Object.assign({}, model, {
          history: historyDuplicateFrame(model.history, ev.time)
        });
      }

      case 'REMOVE_FRAME': {
        return Object.assign({}, model, {
          history: historyRemoveFrame(model.history, ev.time)
        });
      }

      default:
        return model;
    }
  };

  const render = (model) => {
    const container = document.getElementById('timeline');
    clearElem(container);

    const predictionControls = createPredictionControlsElem(model, dispatch);
    container.appendChild(predictionControls);

    const channelControls = createChannelControlsElem(model, dispatch);
    container.appendChild(channelControls);

    const timeline = createTimelineElem(model, dispatch);
    container.appendChild(timeline);

    const predictedTimeline = createPredictedTimelineElem(model, dispatch);
    container.appendChild(predictedTimeline);
  };

  const dispatch = (ev) => {
    const newModel = reducer(currentModel, ev);
    render(newModel);
    currentModel = newModel;
  };

  // Init
  render(initialModel);
};
<|endoftext|>


<commit_before>const React = require('react-native');
const {
  Dimensions,
  StyleSheet,
  ScrollView,
  View,
  Image,
  Text,
  Component,
} = React;

const window = Dimensions.get('window');
const uri = 'http://pickaface.net/includes/themes/clean/img/slide2.png';

const styles = StyleSheet.create({
  menu: {
    flex: 1,
    width: window.width,
    height: window.height,
    backgroundColor: 'gray',
    padding: 20,
  },
  avatarContainer: {
    marginBottom: 20,
    marginTop: 20,
  },
  avatar: {
    width: 48,
    height: 48,
    borderRadius: 24,
    flex: 1,
  },
  name: {
    position: 'absolute',
    left: 70,
    top: 20,
  },
  item: {
    fontSize: 14,
    fontWeight: '300',
    paddingTop: 5,
  },
});

module.exports = class Menu extends Component {
  render() {
    return (
      <ScrollView style={styles.menu}>
        <View style={styles.avatarContainer}>
          <Image
            style={styles.avatar}
            source={{ uri, }}/>
          <Text style={styles.name}>Your name</Text>
        </View>

        <Text style={styles.item}>About</Text>
        <Text style={styles.item}>Contacts</Text>
      </ScrollView>
    );
  }
};
<commit_msg>Update Menu.js<commit_after>const React = require('react-native');
const {
  Dimensions,
  StyleSheet,
  ScrollView,
  View,
  Image,
  Text,
  Component,
} = React;

const window = Dimensions.get('window');
const uri = 'http://pickaface.net/includes/themes/clean/img/slide2.png';

const styles = StyleSheet.create({
  menu: {
    flex: 1,
    width: window.width,
    height: window.height,
    backgroundColor: 'gray',
    padding: 20,
  },
  avatarContainer: {
    marginBottom: 20,
    marginTop: 20,
  },
  avatar: {
    width: 48,
    height: 48,
    borderRadius: 24,
    flex: 1,
  },
  name: {
    position: 'absolute',
    left: 70,
    top: 20,
  },
  item: {
    fontSize: 14,
    fontWeight: '300',
    paddingTop: 5,
  },
});

module.exports = class Menu extends Component {
  render() {
    return (
      <ScrollView scrollsToTop={false} style={styles.menu}>
        <View style={styles.avatarContainer}>
          <Image
            style={styles.avatar}
            source={{ uri, }}/>
          <Text style={styles.name}>Your name</Text>
        </View>

        <Text style={styles.item}>About</Text>
        <Text style={styles.item}>Contacts</Text>
      </ScrollView>
    );
  }
};
<|endoftext|>


<commit_before>/**
 * Created with JetBrains WebStorm.
 * User: 林超捷
 * Date: 14-2-10
 * Time: 上午10:16
 * To change this template use File | Settings | File Templates.
 */
function getResourceList(){
    return ["daisy.png"];
}

function getDescription(){
    return "这个项目展示了Bitmap的正常显示、位移、缩放、旋转、斜切";
}

function createExample(){

    var container = new ns_egret.DisplayObjectContainer();
    context.stage.addChild(container);
    var texture = ns_egret.TextureCache.getInstance().getTexture("daisy.png");
//    container.setContentSize(10, 1

    var bitmap1 = ns_egret.Bitmap.initWithTexture(texture);
    container.addChild(bitmap1);
    bitmap1.x = bitmap1.y = 50;
    container.touchEnabled = true;
    bitmap1.touchEnabled = true;
    bitmap1.setContentSize(100,100)

    var bitmap2 = ns_egret.Bitmap.initWithTexture(texture);
    container.addChild(bitmap2);
    bitmap2.x = 150;
    bitmap2.y = 50;
//    bitmap2.scaleX = bitmap2.scaleY = 0.5;

    var bitmap3 = ns_egret.Bitmap.initWithTexture(texture);
    container.addChild(bitmap3);
    bitmap3.x = 50;
    bitmap3.y = 150;
//    bitmap3.rotation = 45;

    var bitmap4 = ns_egret.Bitmap.initWithTexture(texture);
    container.addChild(bitmap4);
    bitmap4.x = 150;
    bitmap4.y = 150;
//    bitmap4.cacheAsBitmap(true);
//    bitmap4.skewX = 45;

    container.cacheAsBitmap(true);

}<commit_msg>恢复注释的代码，解决TestBitmap图片不缩放等问题。<commit_after>/**
 * Created with JetBrains WebStorm.
 * User: 林超捷
 * Date: 14-2-10
 * Time: 上午10:16
 * To change this template use File | Settings | File Templates.
 */
function getResourceList(){
    return ["daisy.png"];
}

function getDescription(){
    return "这个项目展示了Bitmap的正常显示、位移、缩放、旋转、斜切";
}

function createExample(){

    var container = new ns_egret.DisplayObjectContainer();
    context.stage.addChild(container);
    var texture = ns_egret.TextureCache.getInstance().getTexture("daisy.png");

    var bitmap1 = ns_egret.Bitmap.initWithTexture(texture);
    container.addChild(bitmap1);
    bitmap1.x = bitmap1.y = 50;
    container.touchEnabled = true;
    bitmap1.touchEnabled = true;
    bitmap1.setContentSize(100,100)

    var bitmap2 = ns_egret.Bitmap.initWithTexture(texture);
    container.addChild(bitmap2);
    bitmap2.x = 150;
    bitmap2.y = 50;
    bitmap2.scaleX = bitmap2.scaleY = 0.5;

    var bitmap3 = ns_egret.Bitmap.initWithTexture(texture);
    container.addChild(bitmap3);
    bitmap3.x = 50;
    bitmap3.y = 150;
    bitmap3.rotation = 45;

    var bitmap4 = ns_egret.Bitmap.initWithTexture(texture);
    container.addChild(bitmap4);
    bitmap4.x = 150;
    bitmap4.y = 150;
    bitmap4.skewX = 45;

    container.cacheAsBitmap(true);

}<|endoftext|>


<commit_before>import React from 'react';
import test from 'ava';
import sinon from 'sinon';
import { shallow, mount } from 'enzyme';
import { App } from '../App';

const children =
Test
;
const dispatch = sinon.spy();
const props = {
    children,
    dispatch,
};

test('renders properly', t => {
    const wrapper = shallow(
    <App {...props} />
  );

  // t.is(wrapper.find('Helmet').length, 1);
  // t.is(wrapper.find('Header').length, 1);
    t.is(wrapper.find('Footer').length, 1);
    t.truthy(wrapper.find('Header + div').children(), children);
});
/*
test('calls componentDidMount', t => {
  sinon.spy(App.prototype, 'componentDidMount');
  mount(
    <App {...props} />,
    {
      context: {
        router: {
          isActive: sinon.stub().returns(true),
          push: sinon.stub(),
          replace: sinon.stub(),
          go: sinon.stub(),
          goBack: sinon.stub(),
          goForward: sinon.stub(),
          setRouteLeaveHook: sinon.stub(),
          createHref: sinon.stub(),
        },
        intl,
      },
      childContextTypes: {
        router: React.PropTypes.object,
        intl: intlShape,
      },
    },
  );

  t.truthy(App.prototype.componentDidMount.calledOnce);
  App.prototype.componentDidMount.restore();
}); */
<commit_msg>Updated specs to refelct new UI changes<commit_after>import React from 'react';
import test from 'ava';
import sinon from 'sinon';
import { shallow, mount } from 'enzyme';
import { App } from '../App';

const children =
Test
;
const dispatch = sinon.spy();
const props = {
    children,
    dispatch,
};

test('renders properly', t => {
    const wrapper = shallow(
    <App {...props} />
  );

  // t.is(wrapper.find('Helmet').length, 1);
  // t.is(wrapper.find('Header').length, 1);
  // t.is(wrapper.find('Footer').length, 1);
    t.truthy(wrapper.find('Header + div').children(), children);
});
/*
test('calls componentDidMount', t => {
  sinon.spy(App.prototype, 'componentDidMount');
  mount(
    <App {...props} />,
    {
      context: {
        router: {
          isActive: sinon.stub().returns(true),
          push: sinon.stub(),
          replace: sinon.stub(),
          go: sinon.stub(),
          goBack: sinon.stub(),
          goForward: sinon.stub(),
          setRouteLeaveHook: sinon.stub(),
          createHref: sinon.stub(),
        },
        intl,
      },
      childContextTypes: {
        router: React.PropTypes.object,
        intl: intlShape,
      },
    },
  );

  t.truthy(App.prototype.componentDidMount.calledOnce);
  App.prototype.componentDidMount.restore();
}); */
<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';
import ImageInfo from './ImageInfo/ImageInfo';
import ImageView from './ImageView/ImageView';
import Immutable from 'immutable';

class Image extends React.Component {
  render() {
    const userPics = this.props.userPics;
    //const viewing = this.props.viewing;
    const picId = this.props.params.imageId;
    const pic = userPics.get(picId);
    const originalUrl = pic.get('originalUrl');
    const folder = pic.get('folder');
    const title = pic.get('title');
    const currentTags = pic.get('tags');
    return (

          <ImageInfo
            picId={ picId }
            folder={ folder }
            title={ title }
            originalUrl={ originalUrl }
            currentTags={ currentTags }
            history={ this.props.history }
          />

          <ImageView originalUrl={ originalUrl } />

    );
/*    return (

          <ImageInfo
            picId={ picId }
            folder={ folder }
            title={ title }
            originalUrl={ originalUrl }
            currentTags={ currentTags }
            history={ this.props.history }
          />

          <ImageView
            originalUrl={ originalUrl }
            picId={ picId }
          />

    );*/

/*    return (

            <ImageInfo
              picId={ this.props.picId }
              folder={ this.props.folder }
              title={ this.props.title }
              originalUrl={ this.props.originalUrl }
              currentTags={ this.props.currentTags }
              history={ this.props.history }
              />

            <ImageView originalUrl={ this.props.originalUrl } />

    );*/

  }
}

const mapStateToProps = (state) => {
  return {
    userPics: state.userPics,
    viewing: state.viewing
  };
};

/*const mapStateToProps = (state) => {
  const userPics = state.userPics;
  const viewing = state.viewing;
  const picId = viewing.get('currentImage', 0);
  const pic = userPics.get(picId);
  const originalUrl = pic.get('originalUrl');
  const folder = pic.get('folder');
  const title = pic.get('title');
  const currentTags = pic.get('tags');
  return {
    picId: pic,
    originalUrl: originalUrl,
    folder: folder,
    title: title,
    currentTags: currentTags,
  };
};*/

export default connect(mapStateToProps)(Image);
<commit_msg>Added picId prop to ImageView component<commit_after>import React from 'react';
import { connect } from 'react-redux';
import ImageInfo from './ImageInfo/ImageInfo';
import ImageView from './ImageView/ImageView';
import Immutable from 'immutable';

class Image extends React.Component {
  render() {
    const userPics = this.props.userPics;
    //const viewing = this.props.viewing;
    const picId = this.props.params.imageId;
    const pic = userPics.get(picId);
    const originalUrl = pic.get('originalUrl');
    const folder = pic.get('folder');
    const title = pic.get('title');
    const currentTags = pic.get('tags');
    return (

          <ImageInfo
            picId={ picId }
            folder={ folder }
            title={ title }
            originalUrl={ originalUrl }
            currentTags={ currentTags }
            history={ this.props.history }
          />

          <ImageView
            originalUrl={ originalUrl }
            picId={ picId }
          />

    );
/*    return (

          <ImageInfo
            picId={ picId }
            folder={ folder }
            title={ title }
            originalUrl={ originalUrl }
            currentTags={ currentTags }
            history={ this.props.history }
          />

          <ImageView
            originalUrl={ originalUrl }
            picId={ picId }
          />

    );*/

/*    return (

            <ImageInfo
              picId={ this.props.picId }
              folder={ this.props.folder }
              title={ this.props.title }
              originalUrl={ this.props.originalUrl }
              currentTags={ this.props.currentTags }
              history={ this.props.history }
              />

            <ImageView originalUrl={ this.props.originalUrl } />

    );*/

  }
}

const mapStateToProps = (state) => {
  return {
    userPics: state.userPics,
    viewing: state.viewing
  };
};

/*const mapStateToProps = (state) => {
  const userPics = state.userPics;
  const viewing = state.viewing;
  const picId = viewing.get('currentImage', 0);
  const pic = userPics.get(picId);
  const originalUrl = pic.get('originalUrl');
  const folder = pic.get('folder');
  const title = pic.get('title');
  const currentTags = pic.get('tags');
  return {
    picId: pic,
    originalUrl: originalUrl,
    folder: folder,
    title: title,
    currentTags: currentTags,
  };
};*/

export default connect(mapStateToProps)(Image);
<|endoftext|>


<commit_before>import debug from 'debug';
import reqwest from 'reqwest';
import trimStart from 'lodash/trimStart';

import { blurSearch, clearControlError, closeWebsocket, openWebsocket, receiveError,
  receiveApiDetails, receiveNodesDelta, receiveNodeDetails, receiveControlError,
  receiveControlNodeRemoved, receiveControlPipe, receiveControlPipeStatus,
  receiveControlSuccess, receiveTopologies, receiveNotFound,
  receiveNodesForTopology } from '../actions/app-actions';

import { API_INTERVAL, TOPOLOGY_INTERVAL } from '../constants/timer';

const log = debug('scope:web-api-utils');

const reconnectTimerInterval = 5000;
const updateFrequency = '5s';
const FIRST_RENDER_TOO_LONG_THRESHOLD = 100; // ms

let socket;
let reconnectTimer = 0;
let currentUrl = null;
let currentOptions = null;
let topologyTimer = 0;
let apiDetailsTimer = 0;
let controlErrorTimer = 0;
let createWebsocketAt = 0;
let firstMessageOnWebsocketAt = 0;

export function buildOptionsQuery(options) {
  if (options) {
    return options.map((value, param) => `${param}=${value}`).join('&');
  }
  return '';
}

export function basePath(urlPath) {
  //
  // "/scope/terminal.html" -> "/scope"
  // "/scope/" -> "/scope"
  // "/scope" -> "/scope"
  // "/" -> ""
  //
  const parts = urlPath.split('/');
  // if the last item has a "." in it, e.g. foo.html...
  if (parts[parts.length - 1].indexOf('.') !== -1) {
    return parts.slice(0, -1).join('/');
  }
  return parts.join('/').replace(/\/$/, '');
}

export function basePathSlash(urlPath) {
  //
  // "/scope/terminal.html" -> "/scope/"
  // "/scope/" -> "/scope/"
  // "/scope" -> "/scope/"
  // "/" -> "/"
  //
  return `${basePath(urlPath)}/`;
}

// JJP - `apiPath` is used to get API URLs right when running as a React component.
// This needs to be refactored to just accept a URL prop on the scope component.
let apiPath;
let websocketUrl;
const isIframe = window.location !== window.parent.location;
const isStandalone = window.location.pathname === '/';
const wsProto = location.protocol === 'https:' ? 'wss' : 'ws';

if (isIframe || isStandalone) {
  apiPath = 'api';
  websocketUrl = `${wsProto}://${location.host}${basePath(location.pathname)}`;
} else {
  apiPath = `/api${basePath(window.location.pathname)}/api`;
  websocketUrl = `${wsProto}://${location.host}/api${basePath(window.location.pathname)}`;
}

export const wsUrl = websocketUrl;

function createWebsocket(topologyUrl, optionsQuery, dispatch) {
  if (socket) {
    socket.onclose = null;
    socket.onerror = null;
    socket.close();
    // onclose() is not called, but that's fine since we're opening a new one
    // right away
  }

  // profiling
  createWebsocketAt = new Date();
  firstMessageOnWebsocketAt = 0;

  socket = new WebSocket(`${wsUrl}${topologyUrl}/ws?t=${updateFrequency}&${optionsQuery}`);

  socket.onopen = () => {
    dispatch(openWebsocket());
  };

  socket.onclose = () => {
    clearTimeout(reconnectTimer);
    log(`Closing websocket to ${topologyUrl}`, socket.readyState);
    socket = null;
    dispatch(closeWebsocket());

    reconnectTimer = setTimeout(() => {
      createWebsocket(topologyUrl, optionsQuery, dispatch);
    }, reconnectTimerInterval);
  };

  socket.onerror = () => {
    log(`Error in websocket to ${topologyUrl}`);
    dispatch(receiveError(currentUrl));
  };

  socket.onmessage = (event) => {
    const msg = JSON.parse(event.data);
    dispatch(receiveNodesDelta(msg));

    // profiling (receiveNodesDelta triggers synchronous render)
    if (!firstMessageOnWebsocketAt) {
      firstMessageOnWebsocketAt = new Date();
      const timeToFirstMessage = firstMessageOnWebsocketAt - createWebsocketAt;
      if (timeToFirstMessage > FIRST_RENDER_TOO_LONG_THRESHOLD) {
        log('Time (ms) to first nodes render after websocket was created',
          firstMessageOnWebsocketAt - createWebsocketAt);
      }
    }
  };
}

/* keep URLs relative */

/**
 * Gets nodes for all topologies (for search)
 */
export function getAllNodes(getState, dispatch) {
  const state = getState();
  const topologyOptions = state.get('topologyOptions');
  // fetch sequentially
  state.get('topologyUrlsById')
    .reduce((sequence, topologyUrl, topologyId) => sequence.then(() => {
      const optionsQuery = buildOptionsQuery(topologyOptions.get(topologyId));
      // Trim the leading slash from the url before requesting.
      // This ensures that scope will request from the correct route if embedded in an iframe.
      return fetch(`${trimStart(topologyUrl, '/')}?${optionsQuery}`);
    })
    .then(response => response.json())
    .then(json => dispatch(receiveNodesForTopology(json.nodes, topologyId))),
    Promise.resolve());
}

export function getTopologies(options, dispatch) {
  clearTimeout(topologyTimer);
  const optionsQuery = buildOptionsQuery(options);
  const url = `${apiPath}/topology?${optionsQuery}`;
  reqwest({
    url,
    success: (res) => {
      dispatch(receiveTopologies(res));
      topologyTimer = setTimeout(() => {
        getTopologies(options, dispatch);
      }, TOPOLOGY_INTERVAL);
    },
    error: (err) => {
      log(`Error in topology request: ${err.responseText}`);
      dispatch(receiveError(url));
      topologyTimer = setTimeout(() => {
        getTopologies(options, dispatch);
      }, TOPOLOGY_INTERVAL);
    }
  });
}

export function getNodesDelta(topologyUrl, options, dispatch) {
  const optionsQuery = buildOptionsQuery(options);

  // only recreate websocket if url changed
  if (topologyUrl && (topologyUrl !== currentUrl || currentOptions !== optionsQuery)) {
    createWebsocket(topologyUrl, optionsQuery, dispatch);
    currentUrl = topologyUrl;
    currentOptions = optionsQuery;
  }
}

export function getNodeDetails(topologyUrlsById, currentTopologyId, options, nodeMap, dispatch) {
  // get details for all opened nodes
  const obj = nodeMap.last();
  if (obj && topologyUrlsById.has(obj.topologyId)) {
    const topologyUrl = topologyUrlsById.get(obj.topologyId);
    let urlComponents = [apiPath, '/', trimStart(topologyUrl, '/api'), '/', encodeURIComponent(obj.id)];
    if (currentTopologyId === obj.topologyId) {
      // Only forward filters for nodes in the current topology
      const optionsQuery = buildOptionsQuery(options);
      urlComponents = urlComponents.concat(['?', optionsQuery]);
    }
    const url = urlComponents.join('');

    reqwest({
      url,
      success: (res) => {
        // make sure node is still selected
        if (nodeMap.has(res.node.id)) {
          dispatch(receiveNodeDetails(res.node));
        }
      },
      error: (err) => {
        log(`Error in node details request: ${err.responseText}`);
        // dont treat missing node as error
        if (err.status === 404) {
          dispatch(receiveNotFound(obj.id));
        } else {
          dispatch(receiveError(topologyUrl));
        }
      }
    });
  } else if (obj) {
    log('No details or url found for ', obj);
  }
}

export function getApiDetails(dispatch) {
  clearTimeout(apiDetailsTimer);
  const url = apiPath;
  reqwest({
    url,
    success: (res) => {
      dispatch(receiveApiDetails(res));
      apiDetailsTimer = setTimeout(() => {
        getApiDetails(dispatch);
      }, API_INTERVAL);
    },
    error: (err) => {
      log(`Error in api details request: ${err.responseText}`);
      receiveError(url);
      apiDetailsTimer = setTimeout(() => {
        getApiDetails(dispatch);
      }, API_INTERVAL / 2);
    }
  });
}

export function doControlRequest(nodeId, control, dispatch) {
  clearTimeout(controlErrorTimer);
  const url = `${apiPath}/control/${encodeURIComponent(control.probeId)}/`
    + `${encodeURIComponent(control.nodeId)}/${control.id}`;
  reqwest({
    method: 'POST',
    url,
    success: (res) => {
      dispatch(receiveControlSuccess(nodeId));
      if (res) {
        if (res.pipe) {
          dispatch(blurSearch());
          const resizeTtyControl = res.resize_tty_control &&
            {id: res.resize_tty_control, probeId: control.probeId, nodeId: control.nodeId};
          dispatch(receiveControlPipe(
            res.pipe,
            nodeId,
            res.raw_tty,
            resizeTtyControl,
            control
          ));
        }
        if (res.removedNode) {
          dispatch(receiveControlNodeRemoved(nodeId));
        }
      }
    },
    error: (err) => {
      dispatch(receiveControlError(nodeId, err.response));
      controlErrorTimer = setTimeout(() => {
        dispatch(clearControlError(nodeId));
      }, 10000);
    }
  });
}

export function doResizeTty(pipeId, control, cols, rows) {
  const url = `${apiPath}/control/${encodeURIComponent(control.probeId)}/`
    + `${encodeURIComponent(control.nodeId)}/${control.id}`;

  return reqwest({
    method: 'POST',
    url,
    data: JSON.stringify({pipeID: pipeId, width: cols.toString(), height: rows.toString()}),
  })
    .fail((err) => {
      log(`Error resizing pipe: ${err}`);
    });
}

export function deletePipe(pipeId, dispatch) {
  const url = `${apiPath}/pipe/${encodeURIComponent(pipeId)}`;
  reqwest({
    method: 'DELETE',
    url,
    success: () => {
      log('Closed the pipe!');
    },
    error: (err) => {
      log(`Error closing pipe:${err}`);
      dispatch(receiveError(url));
    }
  });
}

export function getPipeStatus(pipeId, dispatch) {
  const url = `${apiPath}/pipe/${encodeURIComponent(pipeId)}/check`;
  reqwest({
    method: 'GET',
    url,
    complete: (res) => {
      const status = {
        204: 'PIPE_ALIVE',
        404: 'PIPE_DELETED'
      }[res.status];

      if (!status) {
        log('Unexpected pipe status:', res.status);
        return;
      }

      dispatch(receiveControlPipeStatus(pipeId, status));
    }
  });
}
<commit_msg>Fix for URLs in contrast mode<commit_after>import debug from 'debug';
import reqwest from 'reqwest';
import trimStart from 'lodash/trimStart';

import { blurSearch, clearControlError, closeWebsocket, openWebsocket, receiveError,
  receiveApiDetails, receiveNodesDelta, receiveNodeDetails, receiveControlError,
  receiveControlNodeRemoved, receiveControlPipe, receiveControlPipeStatus,
  receiveControlSuccess, receiveTopologies, receiveNotFound,
  receiveNodesForTopology } from '../actions/app-actions';

import { API_INTERVAL, TOPOLOGY_INTERVAL } from '../constants/timer';

const log = debug('scope:web-api-utils');

const reconnectTimerInterval = 5000;
const updateFrequency = '5s';
const FIRST_RENDER_TOO_LONG_THRESHOLD = 100; // ms

let socket;
let reconnectTimer = 0;
let currentUrl = null;
let currentOptions = null;
let topologyTimer = 0;
let apiDetailsTimer = 0;
let controlErrorTimer = 0;
let createWebsocketAt = 0;
let firstMessageOnWebsocketAt = 0;

export function buildOptionsQuery(options) {
  if (options) {
    return options.map((value, param) => `${param}=${value}`).join('&');
  }
  return '';
}

export function basePath(urlPath) {
  //
  // "/scope/terminal.html" -> "/scope"
  // "/scope/" -> "/scope"
  // "/scope" -> "/scope"
  // "/" -> ""
  //
  const parts = urlPath.split('/');
  // if the last item has a "." in it, e.g. foo.html...
  if (parts[parts.length - 1].indexOf('.') !== -1) {
    return parts.slice(0, -1).join('/');
  }
  return parts.join('/').replace(/\/$/, '');
}

export function basePathSlash(urlPath) {
  //
  // "/scope/terminal.html" -> "/scope/"
  // "/scope/" -> "/scope/"
  // "/scope" -> "/scope/"
  // "/" -> "/"
  //
  return `${basePath(urlPath)}/`;
}

// JJP - `apiPath` is used to get API URLs right when running as a React component.
// This needs to be refactored to just accept a URL prop on the scope component.
let apiPath;
let websocketUrl;
const isIframe = window.location !== window.parent.location;
const isStandalone = window.location.pathname === '/' || /\/(.+).html/.test(window.location.pathname);
const wsProto = location.protocol === 'https:' ? 'wss' : 'ws';

if (isIframe || isStandalone) {
  apiPath = 'api';
  websocketUrl = `${wsProto}://${location.host}${basePath(location.pathname)}`;
} else {
  apiPath = `/api${basePath(window.location.pathname)}/api`;
  websocketUrl = `${wsProto}://${location.host}/api${basePath(window.location.pathname)}`;
}

export const wsUrl = websocketUrl;

function createWebsocket(topologyUrl, optionsQuery, dispatch) {
  if (socket) {
    socket.onclose = null;
    socket.onerror = null;
    socket.close();
    // onclose() is not called, but that's fine since we're opening a new one
    // right away
  }

  // profiling
  createWebsocketAt = new Date();
  firstMessageOnWebsocketAt = 0;

  socket = new WebSocket(`${wsUrl}${topologyUrl}/ws?t=${updateFrequency}&${optionsQuery}`);

  socket.onopen = () => {
    dispatch(openWebsocket());
  };

  socket.onclose = () => {
    clearTimeout(reconnectTimer);
    log(`Closing websocket to ${topologyUrl}`, socket.readyState);
    socket = null;
    dispatch(closeWebsocket());

    reconnectTimer = setTimeout(() => {
      createWebsocket(topologyUrl, optionsQuery, dispatch);
    }, reconnectTimerInterval);
  };

  socket.onerror = () => {
    log(`Error in websocket to ${topologyUrl}`);
    dispatch(receiveError(currentUrl));
  };

  socket.onmessage = (event) => {
    const msg = JSON.parse(event.data);
    dispatch(receiveNodesDelta(msg));

    // profiling (receiveNodesDelta triggers synchronous render)
    if (!firstMessageOnWebsocketAt) {
      firstMessageOnWebsocketAt = new Date();
      const timeToFirstMessage = firstMessageOnWebsocketAt - createWebsocketAt;
      if (timeToFirstMessage > FIRST_RENDER_TOO_LONG_THRESHOLD) {
        log('Time (ms) to first nodes render after websocket was created',
          firstMessageOnWebsocketAt - createWebsocketAt);
      }
    }
  };
}

/* keep URLs relative */

/**
 * Gets nodes for all topologies (for search)
 */
export function getAllNodes(getState, dispatch) {
  const state = getState();
  const topologyOptions = state.get('topologyOptions');
  // fetch sequentially
  state.get('topologyUrlsById')
    .reduce((sequence, topologyUrl, topologyId) => sequence.then(() => {
      const optionsQuery = buildOptionsQuery(topologyOptions.get(topologyId));
      // Trim the leading slash from the url before requesting.
      // This ensures that scope will request from the correct route if embedded in an iframe.
      return fetch(`${trimStart(topologyUrl, '/')}?${optionsQuery}`);
    })
    .then(response => response.json())
    .then(json => dispatch(receiveNodesForTopology(json.nodes, topologyId))),
    Promise.resolve());
}

export function getTopologies(options, dispatch) {
  clearTimeout(topologyTimer);
  const optionsQuery = buildOptionsQuery(options);
  const url = `${apiPath}/topology?${optionsQuery}`;
  reqwest({
    url,
    success: (res) => {
      dispatch(receiveTopologies(res));
      topologyTimer = setTimeout(() => {
        getTopologies(options, dispatch);
      }, TOPOLOGY_INTERVAL);
    },
    error: (err) => {
      log(`Error in topology request: ${err.responseText}`);
      dispatch(receiveError(url));
      topologyTimer = setTimeout(() => {
        getTopologies(options, dispatch);
      }, TOPOLOGY_INTERVAL);
    }
  });
}

export function getNodesDelta(topologyUrl, options, dispatch) {
  const optionsQuery = buildOptionsQuery(options);

  // only recreate websocket if url changed
  if (topologyUrl && (topologyUrl !== currentUrl || currentOptions !== optionsQuery)) {
    createWebsocket(topologyUrl, optionsQuery, dispatch);
    currentUrl = topologyUrl;
    currentOptions = optionsQuery;
  }
}

export function getNodeDetails(topologyUrlsById, currentTopologyId, options, nodeMap, dispatch) {
  // get details for all opened nodes
  const obj = nodeMap.last();
  if (obj && topologyUrlsById.has(obj.topologyId)) {
    const topologyUrl = topologyUrlsById.get(obj.topologyId);
    let urlComponents = [apiPath, '/', trimStart(topologyUrl, '/api'), '/', encodeURIComponent(obj.id)];
    if (currentTopologyId === obj.topologyId) {
      // Only forward filters for nodes in the current topology
      const optionsQuery = buildOptionsQuery(options);
      urlComponents = urlComponents.concat(['?', optionsQuery]);
    }
    const url = urlComponents.join('');

    reqwest({
      url,
      success: (res) => {
        // make sure node is still selected
        if (nodeMap.has(res.node.id)) {
          dispatch(receiveNodeDetails(res.node));
        }
      },
      error: (err) => {
        log(`Error in node details request: ${err.responseText}`);
        // dont treat missing node as error
        if (err.status === 404) {
          dispatch(receiveNotFound(obj.id));
        } else {
          dispatch(receiveError(topologyUrl));
        }
      }
    });
  } else if (obj) {
    log('No details or url found for ', obj);
  }
}

export function getApiDetails(dispatch) {
  clearTimeout(apiDetailsTimer);
  const url = apiPath;
  reqwest({
    url,
    success: (res) => {
      dispatch(receiveApiDetails(res));
      apiDetailsTimer = setTimeout(() => {
        getApiDetails(dispatch);
      }, API_INTERVAL);
    },
    error: (err) => {
      log(`Error in api details request: ${err.responseText}`);
      receiveError(url);
      apiDetailsTimer = setTimeout(() => {
        getApiDetails(dispatch);
      }, API_INTERVAL / 2);
    }
  });
}

export function doControlRequest(nodeId, control, dispatch) {
  clearTimeout(controlErrorTimer);
  const url = `${apiPath}/control/${encodeURIComponent(control.probeId)}/`
    + `${encodeURIComponent(control.nodeId)}/${control.id}`;
  reqwest({
    method: 'POST',
    url,
    success: (res) => {
      dispatch(receiveControlSuccess(nodeId));
      if (res) {
        if (res.pipe) {
          dispatch(blurSearch());
          const resizeTtyControl = res.resize_tty_control &&
            {id: res.resize_tty_control, probeId: control.probeId, nodeId: control.nodeId};
          dispatch(receiveControlPipe(
            res.pipe,
            nodeId,
            res.raw_tty,
            resizeTtyControl,
            control
          ));
        }
        if (res.removedNode) {
          dispatch(receiveControlNodeRemoved(nodeId));
        }
      }
    },
    error: (err) => {
      dispatch(receiveControlError(nodeId, err.response));
      controlErrorTimer = setTimeout(() => {
        dispatch(clearControlError(nodeId));
      }, 10000);
    }
  });
}

export function doResizeTty(pipeId, control, cols, rows) {
  const url = `${apiPath}/control/${encodeURIComponent(control.probeId)}/`
    + `${encodeURIComponent(control.nodeId)}/${control.id}`;

  return reqwest({
    method: 'POST',
    url,
    data: JSON.stringify({pipeID: pipeId, width: cols.toString(), height: rows.toString()}),
  })
    .fail((err) => {
      log(`Error resizing pipe: ${err}`);
    });
}

export function deletePipe(pipeId, dispatch) {
  const url = `${apiPath}/pipe/${encodeURIComponent(pipeId)}`;
  reqwest({
    method: 'DELETE',
    url,
    success: () => {
      log('Closed the pipe!');
    },
    error: (err) => {
      log(`Error closing pipe:${err}`);
      dispatch(receiveError(url));
    }
  });
}

export function getPipeStatus(pipeId, dispatch) {
  const url = `${apiPath}/pipe/${encodeURIComponent(pipeId)}/check`;
  reqwest({
    method: 'GET',
    url,
    complete: (res) => {
      const status = {
        204: 'PIPE_ALIVE',
        404: 'PIPE_DELETED'
      }[res.status];

      if (!status) {
        log('Unexpected pipe status:', res.status);
        return;
      }

      dispatch(receiveControlPipeStatus(pipeId, status));
    }
  });
}
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as customerActions from '../actions/customerActions';
import CustomerForm from './CustomerForm';
import toastr from 'toastr';

class ManageCustomer extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      customer: Object.assign({}, props.customer),
      errors: {},
      saving: false
    };
    this.change = this.change.bind(this);
    this.save = this.save.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.customer.id != nextProps.customer.id) {
      this.setState({customer: Object.assign({}, nextProps.customer)});
    }
  }

  save(event) {
    event.preventDefault();
    this.setState({saving: true});
    this.props.actions.saveCustomer(this.state.customer)
      .then(() => {
        var self = this;
        setTimeout(function() {
          self.setState({saving: false});
          toastr.success("Customer saved");
          self.context.router.push('/');
        }, 2000);
      });
  }

  change(event) {
    const field = event.target.name;
    let customer = this.state.customer;
    customer[field] = event.target.value;
    return this.setState({customer: customer});
  };

  render() {
    return (

Manage Customer

        <CustomerForm
          onChange={this.change}
          onSave={this.save}
          customer={this.state.customer}
          errors={this.state.errors}
          saving={this.state.saving} />

    );
  }
}

ManageCustomer.contextTypes = {
  router: PropTypes.object
};

function mapStateToProps(state, ownProps) {
  var customer = {};

  if (ownProps.params.id) {
    var customerId = parseInt(ownProps.params.id, 10);
    if (state.customers.length > 0) {
      customer = state.customers.find(c => c.id === customerId)
    }
  }

  return {
    customer: customer
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(customerActions, dispatch)
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(ManageCustomer);<commit_msg>remove lag simulation<commit_after>import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as customerActions from '../actions/customerActions';
import CustomerForm from './CustomerForm';
import toastr from 'toastr';

class ManageCustomer extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      customer: Object.assign({}, props.customer),
      errors: {},
      saving: false
    };
    this.change = this.change.bind(this);
    this.save = this.save.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.customer.id != nextProps.customer.id) {
      this.setState({customer: Object.assign({}, nextProps.customer)});
    }
  }

  save(event) {
    event.preventDefault();
    this.setState({saving: true});
    this.props.actions.saveCustomer(this.state.customer)
      .then(() => {
        this.setState({saving: false});
        toastr.success("Customer saved");
        this.context.router.push('/');
      });
  }

  change(event) {
    const field = event.target.name;
    let customer = this.state.customer;
    customer[field] = event.target.value;
    return this.setState({customer: customer});
  };

  render() {
    return (

Manage Customer

        <CustomerForm
          onChange={this.change}
          onSave={this.save}
          customer={this.state.customer}
          errors={this.state.errors}
          saving={this.state.saving} />

    );
  }
}

ManageCustomer.contextTypes = {
  router: PropTypes.object
};

function mapStateToProps(state, ownProps) {
  var customer = {};

  if (ownProps.params.id) {
    var customerId = parseInt(ownProps.params.id, 10);
    if (state.customers.length > 0) {
      customer = state.customers.find(c => c.id === customerId)
    }
  }

  return {
    customer: customer
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(customerActions, dispatch)
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(ManageCustomer);<|endoftext|>


<commit_before>import Sass from 'sass.js';

onmessage = e => {
  const data = e.data;
  Sass.compile(data, result => {
    self.postMessage(result.text);
  });
};
<commit_msg>fix(client): propagate SASS parser errors from worker<commit_after>import Sass from 'sass.js';

onmessage = e => {
  const data = e.data;
  Sass.compile(data, result => {
    if (result.status === 0) {
      self.postMessage(result.text);
    } else {
      throw result.formatted;
    }
  });
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import './LoginPage.css';

// The page for users to login for accessing research data.
class EmailLinkLoginPage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      email: "",
      link: "",
      token: ""
    };

    this.onUpdateEmail = this.onUpdateEmail.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
    this.getQueryVariable = this.getQueryVariable.bind(this);
  }

  getQueryVariable(variable) {
    const params = {};
    const rawParam = window.location.search;
    if (rawParam) {
      const rawParams = rawParam.substring(1); // gets rid of ?
      rawParams.split("&").forEach(function(v) {
        const varAndVal = v.split("=");
        params[decodeURIComponent(varAndVal[0])] = decodeURIComponent(varAndVal[1]);
      });
    }
    return params[variable];
  }

  onUpdateEmail(e) {
    const { value } = e.target;
    this.setState({ email : value });
  }

  onSubmit(e) {
    e.preventDefault();
    const newValue = this.getQueryVariable('linkToken');
    this.setState({ link : newValue });
    fetch('/api/research/email', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      method: 'POST',
      body: JSON.stringify({
        email: this.state.email,
        link: this.state.link
      })
    });
  }

  //Should there be something when email is not valid?
  //then we'd have to wait for promise to return.....
  //or make it send an email saying email is not valid?

  render() {
    const { email } = this.state;
    return (

Welcome back to Teacher Moments!

        <form name="loginForm" onSubmit={this.onSubmit}>

            Please enter your email below.

            <input type="email" id='email' placeholder="Enter email here" name="email" value={email} onChange={this.onUpdateEmail} required></input>

            <button type="submit"> Get Link </button>

        </form>

    );
  }
}

export default EmailLinkLoginPage;
<commit_msg>fix some styling issues<commit_after>import React, { Component } from 'react';
import './LoginPage.css';

// The page for users to login for accessing research data.
class EmailLinkLoginPage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      email: "",
      link: "",
      token: ""
    };

    this.onUpdateEmail = this.onUpdateEmail.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
    this.getQueryVariable = this.getQueryVariable.bind(this);
  }

  getQueryVariable(variable) {
    const params = {};
    const rawParam = window.location.search;
    if (rawParam) {
      const rawParams = rawParam.substring(1); // gets rid of ?
      rawParams.split("&").forEach(function(v) {
        const varAndVal = v.split("=");
        params[decodeURIComponent(varAndVal[0])] = decodeURIComponent(varAndVal[1]);
      });
    }
    return params[variable];
  }

  onUpdateEmail(e) {
    const { value } = e.target;
    this.setState({ email : value });
  }

  onSubmit(e) {
    e.preventDefault();
    const newValue = this.getQueryVariable('linkToken');
    this.setState({ link : newValue });
    fetch('/api/research/email', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      method: 'POST',
      body: JSON.stringify({
        email: this.state.email,
        link: this.state.link
      })
    });
  }

  //Should there be something when email is not valid?
  //then we'd have to wait for promise to return.....
  //or make it send an email saying email is not valid?

  render() {
    const { email } = this.state;
    return (

Welcome back to Teacher Moments!

        <form name="loginForm" onSubmit={this.onSubmit}>

            Please enter your email below.

            <input type="email" id='email' placeholder="Enter email here" name="email" value={email} onChange={this.onUpdateEmail} required></input>

            <button type="submit"> Get Link </button>

        </form>

    );
  }
}

export default EmailLinkLoginPage;
<|endoftext|>


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

/**
 * @fileoverview Unchecked conversions to create values of goog.html types from
 * plain strings.  Use of these functions could potentially result in instances
 * of goog.html types that violate their type contracts, and hence result in
 * security vulnerabilties.
 *
 * Therefore, all uses of the methods herein must be carefully security
 * reviewed.  Avoid use of the methods in this file whenever possible; instead
 * prefer to create instances of goog.html types using inherently safe builders
 * or template systems.
 */

goog.provide('goog.html.uncheckedconversions');

goog.require('goog.asserts');
goog.require('goog.html.SafeHtml');
goog.require('goog.html.SafeScript');
goog.require('goog.html.SafeStyle');
goog.require('goog.html.SafeStyleSheet');
goog.require('goog.html.SafeUrl');
goog.require('goog.html.TrustedResourceUrl');
goog.require('goog.string');
goog.require('goog.string.Const');

/**
 * Performs an "unchecked conversion" to SafeHtml from a plain string that is
 * known to satisfy the SafeHtml type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `html` satisfies the SafeHtml type contract in all
 * possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} html A string that is claimed to adhere to the SafeHtml
 *     contract.
 * @param {?goog.i18n.bidi.Dir=} opt_dir The optional directionality of the
 *     SafeHtml to be constructed. A null or undefined value signifies an
 *     unknown directionality.
 * @return {!goog.html.SafeHtml} The value of html, wrapped in a SafeHtml
 *     object.
 */
goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract =
    function(justification, html, opt_dir) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
      html, opt_dir || null);
};

/**
 * Performs an "unchecked conversion" to SafeScript from a plain string that is
 * known to satisfy the SafeScript type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `script` satisfies the SafeScript type contract in
 * all possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} script The string to wrap as a SafeScript.
 * @return {!goog.html.SafeScript} The value of `script`, wrapped in a
 *     SafeScript object.
 */
goog.html.uncheckedconversions.safeScriptFromStringKnownToSatisfyTypeContract =
    function(justification, script) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(
      script);
};

/**
 * Performs an "unchecked conversion" to SafeStyle from a plain string that is
 * known to satisfy the SafeStyle type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `style` satisfies the SafeStyle type contract in all
 * possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} style The string to wrap as a SafeStyle.
 * @return {!goog.html.SafeStyle} The value of `style`, wrapped in a
 *     SafeStyle object.
 */
goog.html.uncheckedconversions.safeStyleFromStringKnownToSatisfyTypeContract =
    function(justification, style) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
      style);
};

/**
 * Performs an "unchecked conversion" to SafeStyleSheet from a plain string
 * that is known to satisfy the SafeStyleSheet type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `styleSheet` satisfies the SafeStyleSheet type
 * contract in all possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} styleSheet The string to wrap as a SafeStyleSheet.
 * @return {!goog.html.SafeStyleSheet} The value of `styleSheet`, wrapped
 *     in a SafeStyleSheet object.
 */
goog.html.uncheckedconversions
    .safeStyleSheetFromStringKnownToSatisfyTypeContract = function(
    justification, styleSheet) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeStyleSheet
      .createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheet);
};

/**
 * Performs an "unchecked conversion" to SafeUrl from a plain string that is
 * known to satisfy the SafeUrl type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `url` satisfies the SafeUrl type contract in all
 * possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} url The string to wrap as a SafeUrl.
 * @return {!goog.html.SafeUrl} The value of `url`, wrapped in a SafeUrl
 *     object.
 */
goog.html.uncheckedconversions.safeUrlFromStringKnownToSatisfyTypeContract =
    function(justification, url) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
};

/**
 * Performs an "unchecked conversion" to TrustedResourceUrl from a plain string
 * that is known to satisfy the TrustedResourceUrl type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `url` satisfies the TrustedResourceUrl type contract
 * in all possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} url The string to wrap as a TrustedResourceUrl.
 * @return {!goog.html.TrustedResourceUrl} The value of `url`, wrapped in
 *     a TrustedResourceUrl object.
 */
goog.html.uncheckedconversions
    .trustedResourceUrlFromStringKnownToSatisfyTypeContract = function(
    justification, url) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.TrustedResourceUrl
      .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url);
};
<commit_msg>Remove visibility restriction for unchecked conversions.<commit_after>// Copyright 2013 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Unchecked conversions to create values of goog.html types from
 * plain strings.  Use of these functions could potentially result in instances
 * of goog.html types that violate their type contracts, and hence result in
 * security vulnerabilties.
 *
 * Therefore, all uses of the methods herein must be carefully security
 * reviewed.  Avoid use of the methods in this file whenever possible; instead
 * prefer to create instances of goog.html types using inherently safe builders
 * or template systems.
 *
 *
 */

goog.provide('goog.html.uncheckedconversions');

goog.require('goog.asserts');
goog.require('goog.html.SafeHtml');
goog.require('goog.html.SafeScript');
goog.require('goog.html.SafeStyle');
goog.require('goog.html.SafeStyleSheet');
goog.require('goog.html.SafeUrl');
goog.require('goog.html.TrustedResourceUrl');
goog.require('goog.string');
goog.require('goog.string.Const');

/**
 * Performs an "unchecked conversion" to SafeHtml from a plain string that is
 * known to satisfy the SafeHtml type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `html` satisfies the SafeHtml type contract in all
 * possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} html A string that is claimed to adhere to the SafeHtml
 *     contract.
 * @param {?goog.i18n.bidi.Dir=} opt_dir The optional directionality of the
 *     SafeHtml to be constructed. A null or undefined value signifies an
 *     unknown directionality.
 * @return {!goog.html.SafeHtml} The value of html, wrapped in a SafeHtml
 *     object.
 */
goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract =
    function(justification, html, opt_dir) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
      html, opt_dir || null);
};

/**
 * Performs an "unchecked conversion" to SafeScript from a plain string that is
 * known to satisfy the SafeScript type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `script` satisfies the SafeScript type contract in
 * all possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} script The string to wrap as a SafeScript.
 * @return {!goog.html.SafeScript} The value of `script`, wrapped in a
 *     SafeScript object.
 */
goog.html.uncheckedconversions.safeScriptFromStringKnownToSatisfyTypeContract =
    function(justification, script) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(
      script);
};

/**
 * Performs an "unchecked conversion" to SafeStyle from a plain string that is
 * known to satisfy the SafeStyle type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `style` satisfies the SafeStyle type contract in all
 * possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} style The string to wrap as a SafeStyle.
 * @return {!goog.html.SafeStyle} The value of `style`, wrapped in a
 *     SafeStyle object.
 */
goog.html.uncheckedconversions.safeStyleFromStringKnownToSatisfyTypeContract =
    function(justification, style) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
      style);
};

/**
 * Performs an "unchecked conversion" to SafeStyleSheet from a plain string
 * that is known to satisfy the SafeStyleSheet type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `styleSheet` satisfies the SafeStyleSheet type
 * contract in all possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} styleSheet The string to wrap as a SafeStyleSheet.
 * @return {!goog.html.SafeStyleSheet} The value of `styleSheet`, wrapped
 *     in a SafeStyleSheet object.
 */
goog.html.uncheckedconversions
    .safeStyleSheetFromStringKnownToSatisfyTypeContract = function(
    justification, styleSheet) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeStyleSheet
      .createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheet);
};

/**
 * Performs an "unchecked conversion" to SafeUrl from a plain string that is
 * known to satisfy the SafeUrl type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `url` satisfies the SafeUrl type contract in all
 * possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} url The string to wrap as a SafeUrl.
 * @return {!goog.html.SafeUrl} The value of `url`, wrapped in a SafeUrl
 *     object.
 */
goog.html.uncheckedconversions.safeUrlFromStringKnownToSatisfyTypeContract =
    function(justification, url) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
};

/**
 * Performs an "unchecked conversion" to TrustedResourceUrl from a plain string
 * that is known to satisfy the TrustedResourceUrl type contract.
 *
 * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
 * that the value of `url` satisfies the TrustedResourceUrl type contract
 * in all possible program states.
 *
 *
 * @param {!goog.string.Const} justification A constant string explaining why
 *     this use of this method is safe. May include a security review ticket
 *     number.
 * @param {string} url The string to wrap as a TrustedResourceUrl.
 * @return {!goog.html.TrustedResourceUrl} The value of `url`, wrapped in
 *     a TrustedResourceUrl object.
 */
goog.html.uncheckedconversions
    .trustedResourceUrlFromStringKnownToSatisfyTypeContract = function(
    justification, url) {
  // unwrap() called inside an assert so that justification can be optimized
  // away in production code.
  goog.asserts.assertString(
      goog.string.Const.unwrap(justification), 'must provide justification');
  goog.asserts.assert(
      !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
      'must provide non-empty justification');
  return goog.html.TrustedResourceUrl
      .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url);
};
<|endoftext|>


<commit_before>// test/testdom.js
module.exports = function(markup) {
  if (typeof document !== 'undefined') {
    return;
  }
  var jsdom = require('jsdom').jsdom;
  global.document = jsdom(markup || '');
  global.window = document.defaultView;
  global.navigator = {
    userAgent: 'node.js'
  };
};<commit_msg>Catalinker: linting - add missing global<commit_after>/*global document*/
module.exports = function(markup) {
  if (typeof document !== 'undefined') {
    return;
  }
  var jsdom = require('jsdom').jsdom;
  global.document = jsdom(markup || '');
  global.window = document.defaultView;
  global.navigator = {
    userAgent: 'node.js'
  };
};<|endoftext|>


<commit_before>'use strict';

var _ = require('underscore');

module.exports = function(req, res, next){

  var baseUrlFunc = _.isFunction(res.conf.baseUrl) ? res.conf.baseUrl : undefined;

  if(!_.isUndefined(baseUrlFunc)){
    res.conf.baseUrl = baseUrlFunc({
      host: req.headers.host,
      secure: req.secure
    });
  }

  next();
};<commit_msg>Bugfix<commit_after>'use strict';

var _ = require('underscore');

module.exports = function(req, res, next){

  res.conf.baseUrlFunc = res.conf.baseUrlFunc || (_.isFunction(res.conf.baseUrl) ? res.conf.baseUrl : undefined);

  if(!_.isUndefined(res.conf.baseUrlFunc)){
    res.conf.baseUrl = res.conf.baseUrlFunc({
      host: req.headers.host,
      secure: req.secure
    });
  }

  next();
};<|endoftext|>


<commit_before>var miniSurvey ={
	bid:0,
	serviceURL: $("input[name=miniSurveyServices]").val() + '?block=form&',
	init: function(){
			this.tabSetup();
			this.answerTypes=document.forms['ccm-block-form'].answerType;
			this.answerTypesEdit=document.forms['ccm-block-form'].answerTypeEdit;

			for(var i=0;i<this.answerTypes.length;i++){
				this.answerTypes[i].onclick=function(){miniSurvey.optionsCheck(this);miniSurvey.settingsCheck(this);}
				this.answerTypes[i].onchange=function(){miniSurvey.optionsCheck(this);miniSurvey.settingsCheck(this);}
			}
			for(var i=0;i<this.answerTypesEdit.length;i++){
				this.answerTypesEdit[i].onclick=function(){miniSurvey.optionsCheck(this,'Edit');miniSurvey.settingsCheck(this,'Edit');}
				this.answerTypesEdit[i].onchange=function(){miniSurvey.optionsCheck(this,'Edit');miniSurvey.settingsCheck(this,'Edit');}
			}
			$('#refreshButton').click( function(){ miniSurvey.refreshSurvey() } );
			$('#addQuestion').click(   function(){ miniSurvey.addQuestion()   } );
			$('#editQuestion').click(  function(){ miniSurvey.addQuestion('Edit')   } );
			$('#cancelEditQuestion').click(   function(){ $('#editQuestionForm').css('display','none') } );
			this.serviceURL+='cID='+this.cID+'&arHandle='+this.arHandle+'&bID='+this.bID+'&btID='+this.btID+'&';
			miniSurvey.refreshSurvey();
		},
	tabSetup: function(){
		$('ul#ccm-formblock-tabs li a').each( function(num,el){
			el.onclick=function(){
				var pane=this.id.replace('ccm-formblock-tab-','');
				miniSurvey.showPane(pane);
			}
		});
	},
	showPane:function(pane){
		$('ul#ccm-formblock-tabs li').each(function(num,el){ $(el).removeClass('ccm-nav-active') });
		$(document.getElementById('ccm-formblock-tab-'+pane).parentNode).addClass('ccm-nav-active');
		$('div.ccm-formBlockPane').each(function(num,el){ el.style.display='none'; });
		$('#ccm-formBlockPane-'+pane).css('display','block');
	},
	refreshSurvey : function(){
			$.ajax({
					url: this.serviceURL+'mode=refreshSurvey&qsID='+parseInt(this.qsID)+'&hide='+miniSurvey.hideQuestions.join(','),
					success: function(msg){ $('#miniSurveyPreviewWrap').html(msg); }
				});
			$.ajax({
					url: this.serviceURL+'mode=refreshSurvey&qsID='+parseInt(this.qsID)+'&showEdit=1&hide='+miniSurvey.hideQuestions.join(','),
					success: function(msg){	$('#miniSurveyWrap').html(msg); }
				});
		},
	optionsCheck : function(radioButton,mode){
			if(mode!='Edit') mode='';
			if( radioButton.value=='select' || radioButton.value=='radios' || radioButton.value=='checkboxlist'){
				 $('#answerOptionsArea'+mode).css('display','block');
			}else $('#answerOptionsArea'+mode).css('display','none');
		},
	settingsCheck : function(radioButton,mode){
			if(mode!='Edit') mode='';
			if( radioButton.value=='text'){
				 $('#answerSettings'+mode).css('display','block');
			}else $('#answerSettings'+mode).css('display','none');
		},
	addQuestion : function(mode){
			var msqID=0;
			if(mode!='Edit') mode='';
			else msqID=parseInt($('#msqID').val())
			var postStr='question='+encodeURIComponent($('#question'+mode).val())+'&options='+encodeURIComponent($('#answerOptions'+mode).val());
			postStr+='&width='+escape($('#width'+mode).val());
			postStr+='&height='+escape($('#height'+mode).val());
			var req=($('#required'+mode).get(0).checked)?1:0;
			postStr+='&required='+req;
			postStr+='&position='+escape($('#position'+mode).val());
			postStr+='&inputType='+$('input[@name=answerType'+mode+']:checked').val()
			postStr+='&msqID='+msqID+'&qsID='+parseInt(this.qsID);
			$.ajax({
					type: "POST",
					data: postStr,
					url: this.serviceURL+'mode=addQuestion&qsID='+parseInt(this.qsID),
					success: function(msg){
						eval('var jsonObj='+msg);
						if(!jsonObj){
						   alert(ccm_t('ajax-error'));
						}else if(jsonObj.noRequired){
						   alert(ccm_t('complete-required'));
						}else{
						   if(jsonObj.mode=='Edit'){
							   $('#questionEditedMsg').slideDown('slow');
							   setTimeout("$('#questionEditedMsg').slideUp('slow');",5000);
							   if(jsonObj.hideQID) miniSurvey.hideQuestions.push(jsonObj.hideQID);
						   }else{
							   $('#questionAddedMsg').slideDown('slow');
							   setTimeout("$('#questionAddedMsg').slideUp('slow');",5000);
							   //miniSurvey.saveOrder();
						   }
						   $('#editQuestionForm').css('display','none');
						   miniSurvey.qsID=jsonObj.qsID;
						   miniSurvey.ignoreQuestionId(jsonObj.msqID);
						   $('#qsID').val(jsonObj.qsID);
						   miniSurvey.resetQuestion();
						   miniSurvey.refreshSurvey();
						   //miniSurvey.showPane('preview');
						}
					}
				});
	},
	//prevent duplication of these questions, for block question versioning
	ignoreQuestionId:function(msqID){
		var msqID, ignoreEl=$('#ccm-ignoreQuestionIDs');
		if(ignoreEl.val()) msqIDs=ignoreEl.val().split(',');
		else msqIDs=[];
		msqIDs.push( parseInt(msqID) );
		ignoreEl.val( msqIDs.join(',') );
	},
	reloadQuestion : function(qID){
			$.ajax({
				url: this.serviceURL+"mode=getQuestion&qsID="+parseInt(this.qsID)+'&qID='+parseInt(qID),
				success: function(msg){
						eval('var jsonObj='+msg);
						$('#editQuestionForm').css('display','block')
						$('#questionEdit').val(jsonObj.question);
						$('#answerOptionsEdit').val(jsonObj.optionVals.replace(/%%/g,"\r\n") );
						$('#widthEdit').val(jsonObj.width);
						$('#heightEdit').val(jsonObj.height);
						$('#positionEdit').val(jsonObj.position);
						if( parseInt(jsonObj.required)==1 )
							 $('#requiredEdit').get(0).checked=true;
						else $('#requiredEdit').get(0).checked=false;
						$('#msqID').val(jsonObj.msqID);
						for(var i=0;i<miniSurvey.answerTypesEdit.length;i++){
							if(miniSurvey.answerTypesEdit[i].value==jsonObj.inputType){
								miniSurvey.answerTypesEdit[i].checked=true;
								miniSurvey.optionsCheck(miniSurvey.answerTypesEdit[i],'Edit');
								miniSurvey.settingsCheck(miniSurvey.answerTypesEdit[i],'Edit');
							}
						}
						scroll(0,165);
					}
			});
	},
	//prevent duplication of these questions, for block question versioning
	pendingDeleteQuestionId:function(msqID){
		var msqID, el=$('#ccm-pendingDeleteIDs');
		if(el.val()) msqIDs=ignoreEl.val().split(',');
		else msqIDs=[];
		msqIDs.push( parseInt(msqID) );
		el.val( msqIDs.join(',') );
	},
	hideQuestions : [],
	deleteQuestion : function(el,msqID,qID){
			if(confirm(ccm_t('delete-question'))) {
				$.ajax({
					url: this.serviceURL+"mode=delQuestion&qsID="+parseInt(this.qsID)+'&msqID='+parseInt(msqID),
					success: function(msg){	miniSurvey.resetQuestion(); miniSurvey.refreshSurvey();  }
				});

				miniSurvey.ignoreQuestionId(msqID);
				miniSurvey.hideQuestions.push(qID);
				miniSurvey.pendingDeleteQuestionId(msqID)
			}
	},
	resetQuestion : function(){
			$('#question').val('');
			$('#answerOptions').val('');
			$('#width').val('50');
			$('#height').val('3');
			$('#msqID').val('');
			for(var i=0;i<this.answerTypes.length;i++){
				this.answerTypes[i].checked=false;
			}
			$('#answerOptionsArea').hide();
			$('#answerSettings').hide();
			$('#required').get(0).checked=0;
	},

	validate:function(){
			var failed=0;

			var n=$('#ccmSurveyName');
			if( !n || parseInt(n.val().length)==0 ){
				alert(ccm_t('form-name'));
				this.showPane('options');
				n.focus();
				failed=1;
			}

			var Qs=$('.miniSurveyQuestionRow');
			if( !Qs || parseInt(Qs.length)<1 ){
				alert(ccm_t('form-min-1'));
				failed=1;
			}

			if(failed){
				ccm_isBlockError=1;
				return false;
			}
			return true;
	},

	moveUp:function(el,thisQID){
		var qIDs=this.serialize();
		var previousQID=0;
		for(var i=0;i<qIDs.length;i++){
			if(qIDs[i]==thisQID){
				if(previousQID==0) break;
				$('#miniSurveyQuestionRow'+thisQID).after($('#miniSurveyQuestionRow'+previousQID));
				break;
			}
			previousQID=qIDs[i];
		}
		this.saveOrder();
	},
	moveDown:function(el,thisQID){
		var qIDs=this.serialize();
		var thisQIDfound=0;
		for(var i=0;i<qIDs.length;i++){
			if(qIDs[i]==thisQID){
				thisQIDfound=1;
				continue;
			}
			if(thisQIDfound){
				$('#miniSurveyQuestionRow'+qIDs[i]).after($('#miniSurveyQuestionRow'+thisQID));
				break;
			}
		}
		this.saveOrder();
	},
	serialize:function(){
		var t = document.getElementById("miniSurveyPreviewTable");
		var qIDs=[];
		for(var i=0;i<t.childNodes.length;i++){
			if( t.childNodes[i].className && t.childNodes[i].className.indexOf('miniSurveyQuestionRow')>=0 ){
				var qID=t.childNodes[i].id.substr('miniSurveyQuestionRow'.length);
				qIDs.push(qID);
			}
		}
		return qIDs;
	},
	saveOrder:function(){
		var postStr='qIDs='+this.serialize().join(',')+'&qsID='+parseInt(this.qsID);
		$.ajax({
			type: "POST",
			data: postStr,
			url: this.serviceURL+"mode=reorderQuestions",
			success: function(msg){
				miniSurvey.refreshSurvey();
			}
		});
	},
	showRecipient:function(cb){
		if(cb.checked) $('#recipientEmailWrap').css('display','block');
		else $('#recipientEmailWrap').css('display','none');
	}
}
ccmValidateBlockForm = function() { return miniSurvey.validate(); }
//$(document).ready(function(){miniSurvey.init()});
<commit_msg>form block field type fix<commit_after>var miniSurvey ={
	bid:0,
	serviceURL: $("input[name=miniSurveyServices]").val() + '?block=form&',
	init: function(){
			this.tabSetup();
			this.answerTypes=document.forms['ccm-block-form'].answerType;
			this.answerTypesEdit=document.forms['ccm-block-form'].answerTypeEdit;

			for(var i=0;i<this.answerTypes.length;i++){
				this.answerTypes[i].onclick=function(){miniSurvey.optionsCheck(this);miniSurvey.settingsCheck(this);}
				this.answerTypes[i].onchange=function(){miniSurvey.optionsCheck(this);miniSurvey.settingsCheck(this);}
			}
			for(var i=0;i<this.answerTypesEdit.length;i++){
				this.answerTypesEdit[i].onclick=function(){miniSurvey.optionsCheck(this,'Edit');miniSurvey.settingsCheck(this,'Edit');}
				this.answerTypesEdit[i].onchange=function(){miniSurvey.optionsCheck(this,'Edit');miniSurvey.settingsCheck(this,'Edit');}
			}
			$('#refreshButton').click( function(){ miniSurvey.refreshSurvey() } );
			$('#addQuestion').click(   function(){ miniSurvey.addQuestion()   } );
			$('#editQuestion').click(  function(){ miniSurvey.addQuestion('Edit')   } );
			$('#cancelEditQuestion').click(   function(){ $('#editQuestionForm').css('display','none') } );
			this.serviceURL+='cID='+this.cID+'&arHandle='+this.arHandle+'&bID='+this.bID+'&btID='+this.btID+'&';
			miniSurvey.refreshSurvey();
		},
	tabSetup: function(){
		$('ul#ccm-formblock-tabs li a').each( function(num,el){
			el.onclick=function(){
				var pane=this.id.replace('ccm-formblock-tab-','');
				miniSurvey.showPane(pane);
			}
		});
	},
	showPane:function(pane){
		$('ul#ccm-formblock-tabs li').each(function(num,el){ $(el).removeClass('ccm-nav-active') });
		$(document.getElementById('ccm-formblock-tab-'+pane).parentNode).addClass('ccm-nav-active');
		$('div.ccm-formBlockPane').each(function(num,el){ el.style.display='none'; });
		$('#ccm-formBlockPane-'+pane).css('display','block');
	},
	refreshSurvey : function(){
			$.ajax({
					url: this.serviceURL+'mode=refreshSurvey&qsID='+parseInt(this.qsID)+'&hide='+miniSurvey.hideQuestions.join(','),
					success: function(msg){ $('#miniSurveyPreviewWrap').html(msg); }
				});
			$.ajax({
					url: this.serviceURL+'mode=refreshSurvey&qsID='+parseInt(this.qsID)+'&showEdit=1&hide='+miniSurvey.hideQuestions.join(','),
					success: function(msg){	$('#miniSurveyWrap').html(msg); }
				});
		},
	optionsCheck : function(radioButton,mode){
			if(mode!='Edit') mode='';
			if( radioButton.value=='select' || radioButton.value=='radios' || radioButton.value=='checkboxlist'){
				 $('#answerOptionsArea'+mode).css('display','block');
			}else $('#answerOptionsArea'+mode).css('display','none');
		},
	settingsCheck : function(radioButton,mode){
			if(mode!='Edit') mode='';
			if( radioButton.value=='text'){
				 $('#answerSettings'+mode).css('display','block');
			}else $('#answerSettings'+mode).css('display','none');
		},
	addQuestion : function(mode){
			var msqID=0;
			if(mode!='Edit') mode='';
			else msqID=parseInt($('#msqID').val())
			var postStr='question='+encodeURIComponent($('#question'+mode).val())+'&options='+encodeURIComponent($('#answerOptions'+mode).val());
			postStr+='&width='+escape($('#width'+mode).val());
			postStr+='&height='+escape($('#height'+mode).val());
			var req=($('#required'+mode).get(0).checked)?1:0;
			postStr+='&required='+req;
			postStr+='&position='+escape($('#position'+mode).val());
			var form=document.getElementById('ccm-block-form');
			var opts=form['answerType'+mode];
			var answerType='';
			for(var i=0;i<opts.length;i++){
				if(opts[i].checked){
					answerType=opts[i].value;
					break;
				}
			}
			postStr+='&inputType='+answerType;//$('input[@name=answerType'+mode+']:checked').val()
			postStr+='&msqID='+msqID+'&qsID='+parseInt(this.qsID);
			$.ajax({
					type: "POST",
					data: postStr,
					url: this.serviceURL+'mode=addQuestion&qsID='+parseInt(this.qsID),
					success: function(msg){
						eval('var jsonObj='+msg);
						if(!jsonObj){
						   alert(ccm_t('ajax-error'));
						}else if(jsonObj.noRequired){
						   alert(ccm_t('complete-required'));
						}else{
						   if(jsonObj.mode=='Edit'){
							   $('#questionEditedMsg').slideDown('slow');
							   setTimeout("$('#questionEditedMsg').slideUp('slow');",5000);
							   if(jsonObj.hideQID) miniSurvey.hideQuestions.push(jsonObj.hideQID);
						   }else{
							   $('#questionAddedMsg').slideDown('slow');
							   setTimeout("$('#questionAddedMsg').slideUp('slow');",5000);
							   //miniSurvey.saveOrder();
						   }
						   $('#editQuestionForm').css('display','none');
						   miniSurvey.qsID=jsonObj.qsID;
						   miniSurvey.ignoreQuestionId(jsonObj.msqID);
						   $('#qsID').val(jsonObj.qsID);
						   miniSurvey.resetQuestion();
						   miniSurvey.refreshSurvey();
						   //miniSurvey.showPane('preview');
						}
					}
				});
	},
	//prevent duplication of these questions, for block question versioning
	ignoreQuestionId:function(msqID){
		var msqID, ignoreEl=$('#ccm-ignoreQuestionIDs');
		if(ignoreEl.val()) msqIDs=ignoreEl.val().split(',');
		else msqIDs=[];
		msqIDs.push( parseInt(msqID) );
		ignoreEl.val( msqIDs.join(',') );
	},
	reloadQuestion : function(qID){
			$.ajax({
				url: this.serviceURL+"mode=getQuestion&qsID="+parseInt(this.qsID)+'&qID='+parseInt(qID),
				success: function(msg){
						eval('var jsonObj='+msg);
						$('#editQuestionForm').css('display','block')
						$('#questionEdit').val(jsonObj.question);
						$('#answerOptionsEdit').val(jsonObj.optionVals.replace(/%%/g,"\r\n") );
						$('#widthEdit').val(jsonObj.width);
						$('#heightEdit').val(jsonObj.height);
						$('#positionEdit').val(jsonObj.position);
						if( parseInt(jsonObj.required)==1 )
							 $('#requiredEdit').get(0).checked=true;
						else $('#requiredEdit').get(0).checked=false;
						$('#msqID').val(jsonObj.msqID);
						for(var i=0;i<miniSurvey.answerTypesEdit.length;i++){
							if(miniSurvey.answerTypesEdit[i].value==jsonObj.inputType){
								miniSurvey.answerTypesEdit[i].checked=true;
								miniSurvey.optionsCheck(miniSurvey.answerTypesEdit[i],'Edit');
								miniSurvey.settingsCheck(miniSurvey.answerTypesEdit[i],'Edit');
							}
						}
						scroll(0,165);
					}
			});
	},
	//prevent duplication of these questions, for block question versioning
	pendingDeleteQuestionId:function(msqID){
		var msqID, el=$('#ccm-pendingDeleteIDs');
		if(el.val()) msqIDs=ignoreEl.val().split(',');
		else msqIDs=[];
		msqIDs.push( parseInt(msqID) );
		el.val( msqIDs.join(',') );
	},
	hideQuestions : [],
	deleteQuestion : function(el,msqID,qID){
			if(confirm(ccm_t('delete-question'))) {
				$.ajax({
					url: this.serviceURL+"mode=delQuestion&qsID="+parseInt(this.qsID)+'&msqID='+parseInt(msqID),
					success: function(msg){	miniSurvey.resetQuestion(); miniSurvey.refreshSurvey();  }
				});

				miniSurvey.ignoreQuestionId(msqID);
				miniSurvey.hideQuestions.push(qID);
				miniSurvey.pendingDeleteQuestionId(msqID)
			}
	},
	resetQuestion : function(){
			$('#question').val('');
			$('#answerOptions').val('');
			$('#width').val('50');
			$('#height').val('3');
			$('#msqID').val('');
			for(var i=0;i<this.answerTypes.length;i++){
				this.answerTypes[i].checked=false;
			}
			$('#answerOptionsArea').hide();
			$('#answerSettings').hide();
			$('#required').get(0).checked=0;
	},

	validate:function(){
			var failed=0;

			var n=$('#ccmSurveyName');
			if( !n || parseInt(n.val().length)==0 ){
				alert(ccm_t('form-name'));
				this.showPane('options');
				n.focus();
				failed=1;
			}

			var Qs=$('.miniSurveyQuestionRow');
			if( !Qs || parseInt(Qs.length)<1 ){
				alert(ccm_t('form-min-1'));
				failed=1;
			}

			if(failed){
				ccm_isBlockError=1;
				return false;
			}
			return true;
	},

	moveUp:function(el,thisQID){
		var qIDs=this.serialize();
		var previousQID=0;
		for(var i=0;i<qIDs.length;i++){
			if(qIDs[i]==thisQID){
				if(previousQID==0) break;
				$('#miniSurveyQuestionRow'+thisQID).after($('#miniSurveyQuestionRow'+previousQID));
				break;
			}
			previousQID=qIDs[i];
		}
		this.saveOrder();
	},
	moveDown:function(el,thisQID){
		var qIDs=this.serialize();
		var thisQIDfound=0;
		for(var i=0;i<qIDs.length;i++){
			if(qIDs[i]==thisQID){
				thisQIDfound=1;
				continue;
			}
			if(thisQIDfound){
				$('#miniSurveyQuestionRow'+qIDs[i]).after($('#miniSurveyQuestionRow'+thisQID));
				break;
			}
		}
		this.saveOrder();
	},
	serialize:function(){
		var t = document.getElementById("miniSurveyPreviewTable");
		var qIDs=[];
		for(var i=0;i<t.childNodes.length;i++){
			if( t.childNodes[i].className && t.childNodes[i].className.indexOf('miniSurveyQuestionRow')>=0 ){
				var qID=t.childNodes[i].id.substr('miniSurveyQuestionRow'.length);
				qIDs.push(qID);
			}
		}
		return qIDs;
	},
	saveOrder:function(){
		var postStr='qIDs='+this.serialize().join(',')+'&qsID='+parseInt(this.qsID);
		$.ajax({
			type: "POST",
			data: postStr,
			url: this.serviceURL+"mode=reorderQuestions",
			success: function(msg){
				miniSurvey.refreshSurvey();
			}
		});
	},
	showRecipient:function(cb){
		if(cb.checked) $('#recipientEmailWrap').css('display','block');
		else $('#recipientEmailWrap').css('display','none');
	}
}
ccmValidateBlockForm = function() { return miniSurvey.validate(); }
//$(document).ready(function(){miniSurvey.init()});
<|endoftext|>