<commit_before>var creep_work5 = {

    /** @param {Creep} creep **/
    run: function(creep, thisSpawn) {

        //wew lad
        /*if (!creep.room.controller.sign) {
            if(creep.pos.isNearTo(creep.room.controller)) {
                creep.signController(creep.room.controller, 'This is, by far, the most kupo room I\'ve ever seen!');
            }
        }*/

        if (creep.memory.priority == 'miner' || creep.memory.priority == 'minerNearDeath') {
            if (creep.ticksToLive <= 60) {
                creep.memory.priority = 'minerNearDeath';
                creep.memory.jobSpecific = creep.memory.jobSpecific + 'NearDeath';
            }
            //Creep will immediately harvest and store mined materials
            var storageTarget = Game.getObjectById(creep.memory.linkSource);
            var mineTarget = Game.getObjectById(creep.memory.mineSource);
            if (mineTarget && storageTarget) {
                if (creep.harvest(mineTarget) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(mineTarget, {
                        reusePath: 20
                    });
                } else {
                    creep.transfer(storageTarget, RESOURCE_ENERGY)
                }
            }
        } else if (creep.memory.priority == 'upgrader' || creep.memory.priority == 'upgraderNearDeath') {
            if (creep.ticksToLive <= 60) {
                creep.memory.priority = 'upgraderNearDeath';
            }

            if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) {
                creep.moveTo(creep.room.controller, {
                    reusePath: 20
                });
            }

            var linkTarget = Game.getObjectById(creep.memory.linkSource);
            if (linkTarget) {
                if (linkTarget.energy > 0) {
                    if (creep.withdraw(linkTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(linkTarget, {
                            reusePath: 20
                        });
                    }
                } else if (creep.carry.energy == 0) {
                    //Get from storage instead
                    var storageTarget = Game.getObjectById(creep.memory.storageSource);
                    if (storageTarget) {
                        if (storageTarget.store[RESOURCE_ENERGY] >= 150) {
                            if (creep.withdraw(storageTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                                creep.moveTo(storageTarget, {
                                    reusePath: 20
                                });
                            }
                        }
                    }
                }
            } else if (creep.carry.energy == 0) {
                var storageTarget = Game.getObjectById(creep.memory.storageSource);
                if (storageTarget) {
                    if (storageTarget.store[RESOURCE_ENERGY] >= 150) {
                        if (creep.withdraw(storageTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }
                    }
                }
            }
        } else if (creep.memory.priority == 'mule' || creep.memory.priority == 'muleNearDeath') {
            if (creep.ticksToLive <= 60) {
                creep.memory.priority = 'muleNearDeath';
            }
            if (_.sum(creep.carry) == 0) {
                creep.memory.structureTarget = undefined;
                var storageTarget = Game.getObjectById(creep.memory.storageSource);
                if (storageTarget) {
                    if (storageTarget.store[RESOURCE_ENERGY] >= 50) {
                        //Get from container
                        if (creep.withdraw(storageTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }
                    } else {
                        if (!creep.pos.isNearTo(storageTarget)) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }

                    }
                }
            } else if (_.sum(creep.carry) > 0) {
                var savedTarget = Game.getObjectById(creep.memory.structureTarget)

                if (savedTarget) {
                    if (creep.build(savedTarget) == ERR_INVALID_TARGET) {
                        if (savedTarget.structureType != STRUCTURE_CONTAINER && savedTarget.structureType != STRUCTURE_STORAGE && savedTarget.structureType != STRUCTURE_CONTROLLER) {
                            //Storing in spawn/extension/tower
                            if (creep.transfer(savedTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                                creep.moveTo(savedTarget, {
                                    reusePath: 20
                                });
                            } else {
                                //assumed OK, drop target
                                creep.memory.structureTarget = undefined;
                            }
                        } else {
                            //Upgrading controller
                            if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) {
                                creep.moveTo(creep.room.controller, {
                                    reusePath: 20
                                });
                            }
                        }
                    } else {
                        if (creep.build(savedTarget) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(savedTarget, {
                                reusePath: 20
                            });
                        }
                    }
                }
                //Immediately find a new target if previous transfer worked
                if (!creep.memory.structureTarget) {
                    var targets = creep.pos.findClosestByRange(FIND_STRUCTURES, {
                        filter: (structure) => {
                            return (structure.structureType == STRUCTURE_EXTENSION ||
                                structure.structureType == STRUCTURE_SPAWN) && structure.energy < structure.energyCapacity;
                        }
                    });
                    if (targets) {
                        creep.memory.structureTarget = targets.id;
                        if (creep.transfer(targets, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(targets);
                        } else {
                            creep.memory.structureTarget = undefined;
                        }
                    } else {
                        targets3 = creep.pos.findClosestByRange(FIND_STRUCTURES, {
                            filter: (structure) => {
                                return (structure.structureType == STRUCTURE_TOWER) && ((structure.energyCapacity - structure.energy) >= 300);
                            }
                        });
                        if (targets3) {
                            creep.memory.structureTarget = targets3.id;
                            if (creep.transfer(targets3, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                                creep.moveTo(targets3);
                            } else {
                                creep.memory.structureTarget = undefined;
                            }
                        } else {
                            //Store in terminal
                            terminalTarget = Game.getObjectById(creep.memory.terminalID)
                            if (terminalTarget) {
                                if (terminalTarget.store[RESOURCE_ENERGY] < 50000) {
                                    creep.memory.structureTarget = terminalTarget;
                                    if (creep.transfer(terminalTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                                        creep.moveTo(terminalTarget, {
                                            reusePath: 20
                                        });
                                    }
                                } else {
                                    terminalTarget = undefined;
                                }
                            }
                            if (!terminalTarget) {
                                //Build
                                var targets2 = creep.pos.findClosestByRange(FIND_CONSTRUCTION_SITES);
                                if (targets2) {
                                    creep.memory.structureTarget = targets2.id;
                                    if (creep.build(targets2) == ERR_NOT_IN_RANGE) {
                                        creep.moveTo(targets2, {
                                            reusePath: 20
                                        });
                                    }
                                } else {
                                    //Upgrade
                                    creep.memory.structureTarget = creep.room.controller.id;
                                    if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) {
                                        creep.moveTo(creep.room.controller, {
                                            reusePath: 20
                                        });
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } else if (creep.memory.priority == 'repair' || creep.memory.priority == 'repairNearDeath') {
            if (creep.ticksToLive <= 60) {
                creep.memory.priority = 'repairNearDeath';
            }

            if (_.sum(creep.carry) == 0) {
                creep.memory.structureTarget = undefined;
                //Get from storage
                var storageTarget = Game.getObjectById(creep.memory.storageSource);
                if (storageTarget) {
                    if (storageTarget.store[RESOURCE_ENERGY] >= 120) {
                        if (creep.withdraw(storageTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }
                    } else {
                        if (!creep.pos.isNearTo(storageTarget)) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }
                    }
                }
            } else if (creep.memory.structureTarget) {
                var thisStructure = Game.getObjectById(creep.memory.structureTarget);
                if (thisStructure) {
                    if (thisStructure.hits == thisStructure.hitsMax) {
                        creep.memory.structureTarget = undefined;
                    } else {
                        if (creep.repair(thisStructure) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(thisStructure, {
                                reusePath: 20
                            });
                        }
                    }
                }
            } else {
                var closestDamagedStructure = creep.room.find(FIND_STRUCTURES, {
                    filter: (structure) => (structure.structureType != STRUCTURE_ROAD) && (structure.hitsMax - structure.hits >= 200)
                });
                if (closestDamagedStructure.length > 0) {
                    closestDamagedStructure.sort(repairCompare);
                    creep.memory.structureTarget = closestDamagedStructure[0].id;
                    if (creep.repair(closestDamagedStructure[0]) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(closestDamagedStructure[0], {
                            reusePath: 20
                        });
                    }
                }
            }

        } else if (creep.memory.priority == 'mineralMiner') {
            var thisMineral = Game.getObjectById(creep.memory.mineralID);
            if (thisMineral.mineralAmount == 0) {
                //Nothing left to do
                creep.suicide();
            } else {
                //Creep will immediately harvest and store mined materials
                var storageTarget = Game.getObjectById(creep.memory.terminalID);
                var thisExtractor = Game.getObjectById(creep.memory.extractorID);
                if (thisExtractor.cooldown == 0) {
                    if (creep.harvest(thisMineral) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(thisMineral, {
                            reusePath: 20
                        });
                    }
                }
                if (creep.transfer(storageTarget, thisMineral.mineralType) == ERR_NOT_IN_RANGE) {
                    //This should never actually fire, if ideal.
                    creep.moveTo(storageTarget);
                }
            }
        }
    }
};

module.exports = creep_work5;

function repairCompare(a, b) {
    if (a.hits < b.hits)
        return -1;
    if (a.hits > b.hits)
        return 1;
    return 0;
}<commit_msg>hey, a bug<commit_after>var creep_work5 = {

    /** @param {Creep} creep **/
    run: function(creep, thisSpawn) {

        //wew lad
        /*if (!creep.room.controller.sign) {
            if(creep.pos.isNearTo(creep.room.controller)) {
                creep.signController(creep.room.controller, 'This is, by far, the most kupo room I\'ve ever seen!');
            }
        }*/

        if (creep.memory.priority == 'miner' || creep.memory.priority == 'minerNearDeath') {
            if (creep.ticksToLive <= 60) {
                creep.memory.priority = 'minerNearDeath';
                creep.memory.jobSpecific = creep.memory.jobSpecific + 'NearDeath';
            }
            //Creep will immediately harvest and store mined materials
            var storageTarget = Game.getObjectById(creep.memory.linkSource);
            var mineTarget = Game.getObjectById(creep.memory.mineSource);
            if (mineTarget && storageTarget) {
                if (creep.harvest(mineTarget) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(mineTarget, {
                        reusePath: 20
                    });
                } else {
                    if (creep.transfer(storageTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(storageTarget, {
                            reusePath: 20
                        });
                    }
                }
            }
        } else if (creep.memory.priority == 'upgrader' || creep.memory.priority == 'upgraderNearDeath') {
            if (creep.ticksToLive <= 60) {
                creep.memory.priority = 'upgraderNearDeath';
            }

            if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) {
                creep.moveTo(creep.room.controller, {
                    reusePath: 20
                });
            }

            var linkTarget = Game.getObjectById(creep.memory.linkSource);
            if (linkTarget) {
                if (linkTarget.energy > 0) {
                    if (creep.withdraw(linkTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(linkTarget, {
                            reusePath: 20
                        });
                    }
                } else if (creep.carry.energy == 0) {
                    //Get from storage instead
                    var storageTarget = Game.getObjectById(creep.memory.storageSource);
                    if (storageTarget) {
                        if (storageTarget.store[RESOURCE_ENERGY] >= 150) {
                            if (creep.withdraw(storageTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                                creep.moveTo(storageTarget, {
                                    reusePath: 20
                                });
                            }
                        }
                    }
                }
            } else if (creep.carry.energy == 0) {
                var storageTarget = Game.getObjectById(creep.memory.storageSource);
                if (storageTarget) {
                    if (storageTarget.store[RESOURCE_ENERGY] >= 150) {
                        if (creep.withdraw(storageTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }
                    }
                }
            }
        } else if (creep.memory.priority == 'mule' || creep.memory.priority == 'muleNearDeath') {
            if (creep.ticksToLive <= 60) {
                creep.memory.priority = 'muleNearDeath';
            }
            if (_.sum(creep.carry) == 0) {
                creep.memory.structureTarget = undefined;
                var storageTarget = Game.getObjectById(creep.memory.storageSource);
                if (storageTarget) {
                    if (storageTarget.store[RESOURCE_ENERGY] >= 50) {
                        //Get from container
                        if (creep.withdraw(storageTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }
                    } else {
                        if (!creep.pos.isNearTo(storageTarget)) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }

                    }
                }
            } else if (_.sum(creep.carry) > 0) {
                var savedTarget = Game.getObjectById(creep.memory.structureTarget)

                if (savedTarget) {
                    if (creep.build(savedTarget) == ERR_INVALID_TARGET) {
                        if (savedTarget.structureType != STRUCTURE_CONTAINER && savedTarget.structureType != STRUCTURE_STORAGE && savedTarget.structureType != STRUCTURE_CONTROLLER) {
                            //Storing in spawn/extension/tower
                            if (creep.transfer(savedTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                                creep.moveTo(savedTarget, {
                                    reusePath: 20
                                });
                            } else {
                                //assumed OK, drop target
                                creep.memory.structureTarget = undefined;
                            }
                        } else {
                            //Upgrading controller
                            if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) {
                                creep.moveTo(creep.room.controller, {
                                    reusePath: 20
                                });
                            }
                        }
                    } else {
                        if (creep.build(savedTarget) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(savedTarget, {
                                reusePath: 20
                            });
                        }
                    }
                }
                //Immediately find a new target if previous transfer worked
                if (!creep.memory.structureTarget) {
                    var targets = creep.pos.findClosestByRange(FIND_STRUCTURES, {
                        filter: (structure) => {
                            return (structure.structureType == STRUCTURE_EXTENSION ||
                                structure.structureType == STRUCTURE_SPAWN) && structure.energy < structure.energyCapacity;
                        }
                    });
                    if (targets) {
                        creep.memory.structureTarget = targets.id;
                        if (creep.transfer(targets, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(targets);
                        } else {
                            creep.memory.structureTarget = undefined;
                        }
                    } else {
                        targets3 = creep.pos.findClosestByRange(FIND_STRUCTURES, {
                            filter: (structure) => {
                                return (structure.structureType == STRUCTURE_TOWER) && ((structure.energyCapacity - structure.energy) >= 300);
                            }
                        });
                        if (targets3) {
                            creep.memory.structureTarget = targets3.id;
                            if (creep.transfer(targets3, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                                creep.moveTo(targets3);
                            } else {
                                creep.memory.structureTarget = undefined;
                            }
                        } else {
                            //Store in terminal
                            terminalTarget = Game.getObjectById(creep.memory.terminalID)
                            if (terminalTarget) {
                                if (terminalTarget.store[RESOURCE_ENERGY] < 50000) {
                                    creep.memory.structureTarget = terminalTarget;
                                    if (creep.transfer(terminalTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                                        creep.moveTo(terminalTarget, {
                                            reusePath: 20
                                        });
                                    }
                                } else {
                                    terminalTarget = undefined;
                                }
                            }
                            if (!terminalTarget) {
                                //Build
                                var targets2 = creep.pos.findClosestByRange(FIND_CONSTRUCTION_SITES);
                                if (targets2) {
                                    creep.memory.structureTarget = targets2.id;
                                    if (creep.build(targets2) == ERR_NOT_IN_RANGE) {
                                        creep.moveTo(targets2, {
                                            reusePath: 20
                                        });
                                    }
                                } else {
                                    //Upgrade
                                    creep.memory.structureTarget = creep.room.controller.id;
                                    if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) {
                                        creep.moveTo(creep.room.controller, {
                                            reusePath: 20
                                        });
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } else if (creep.memory.priority == 'repair' || creep.memory.priority == 'repairNearDeath') {
            if (creep.ticksToLive <= 60) {
                creep.memory.priority = 'repairNearDeath';
            }

            if (_.sum(creep.carry) == 0) {
                creep.memory.structureTarget = undefined;
                //Get from storage
                var storageTarget = Game.getObjectById(creep.memory.storageSource);
                if (storageTarget) {
                    if (storageTarget.store[RESOURCE_ENERGY] >= 120) {
                        if (creep.withdraw(storageTarget, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }
                    } else {
                        if (!creep.pos.isNearTo(storageTarget)) {
                            creep.moveTo(storageTarget, {
                                reusePath: 20
                            });
                        }
                    }
                }
            } else if (creep.memory.structureTarget) {
                var thisStructure = Game.getObjectById(creep.memory.structureTarget);
                if (thisStructure) {
                    if (thisStructure.hits == thisStructure.hitsMax) {
                        creep.memory.structureTarget = undefined;
                    } else {
                        if (creep.repair(thisStructure) == ERR_NOT_IN_RANGE) {
                            creep.moveTo(thisStructure, {
                                reusePath: 20
                            });
                        }
                    }
                }
            } else {
                var closestDamagedStructure = creep.room.find(FIND_STRUCTURES, {
                    filter: (structure) => (structure.structureType != STRUCTURE_ROAD) && (structure.hitsMax - structure.hits >= 200)
                });
                if (closestDamagedStructure.length > 0) {
                    closestDamagedStructure.sort(repairCompare);
                    creep.memory.structureTarget = closestDamagedStructure[0].id;
                    if (creep.repair(closestDamagedStructure[0]) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(closestDamagedStructure[0], {
                            reusePath: 20
                        });
                    }
                }
            }

        } else if (creep.memory.priority == 'mineralMiner') {
            var thisMineral = Game.getObjectById(creep.memory.mineralID);
            if (thisMineral.mineralAmount == 0) {
                //Nothing left to do
                creep.suicide();
            } else {
                //Creep will immediately harvest and store mined materials
                var storageTarget = Game.getObjectById(creep.memory.terminalID);
                var thisExtractor = Game.getObjectById(creep.memory.extractorID);
                if (thisExtractor.cooldown == 0) {
                    if (creep.harvest(thisMineral) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(thisMineral, {
                            reusePath: 20
                        });
                    }
                }
                if (creep.transfer(storageTarget, thisMineral.mineralType) == ERR_NOT_IN_RANGE) {
                    //This should never actually fire, if ideal.
                    creep.moveTo(storageTarget);
                }
            }
        }
    }
};

module.exports = creep_work5;

function repairCompare(a, b) {
    if (a.hits < b.hits)
        return -1;
    if (a.hits > b.hits)
        return 1;
    return 0;
}<|endoftext|>


<commit_before>"use strict";

const Immutable = require('immutable')
    , apiFetch = require('./utils/api_fetch')
    , handleResponse = require('./utils/handle_response')
    , parseLD = require('./utils/parse_ld')

const {
  REQUEST_API_RESOURCE,
  REQUEST_NAVIGATION,
} = require('./types').actions

const {
  PENDING,
  SUCCESS,
  FAILURE,
} = require('./types').readyStates

function dispatchReadyState(dispatch, type) {
  const started = new Date().getTime()
      , requestID = Math.random().toString(16).slice(2)

  return (readyState, opts) =>
    dispatch(Object.assign({}, opts, {
      requestID,
      type,
      readyState,
      started,
      updated: new Date().getTime(),
    }))
}

function navigateToPath(router, path, req=null) {
  return dispatch => {
    const match = router.match(path)
        , { resource, makeTripleStore } = match.handler
        , apiPath = resource ? resource(path) : null
        , headers = {}

    const updateRequest = dispatchReadyState(dispatch, REQUEST_NAVIGATION);

    if (req) {
      headers.Host = req.headers.host;
      headers.cookie = req.headers.cookie;
    }

    const { requestID } = updateRequest(PENDING, { path, apiPath });

    const promises = [
      dispatch(fetchAPIResource('/me/', { headers })).promise,
      apiPath && dispatch(
        fetchAPIResource(apiPath, { headers }, makeTripleStore)
      ).promise
    ]

    const promise = Promise.all(promises).then(
      () => {
        updateRequest(SUCCESS, { path, apiPath });
      },
      err => {
        updateRequest(FAILURE, { path, apiPath, err });
      }
    )

    return { requestID, promise }
  }
}

const PASSED_HEADERS = [
  'Location',
  'Date',
  'Content-Type',
]

function fetchAPIResource(url, opts={}, parseTriples=false) {
  return (dispatch) => {
    let statusCode
      , responseHeaders = {}

    const updateRequest = dispatchReadyState(dispatch, REQUEST_API_RESOURCE);

    if (!process.browser) {
      url = global.API_URL + url;
    }

    const { requestID } = updateRequest(PENDING, { url });

    opts.headers = Object.assign({}, opts.headers, {
      Accept: 'application/ld+json'
    });

    const promise = apiFetch(url, opts)
      .then(handleResponse)
      .then(resp => {

        statusCode = resp.status;

        PASSED_HEADERS.forEach(header => {
          const value = resp.headers.get(header);

          if (value) {
            responseHeaders[header] = value;
          }
        });

        return resp.json();
      })
      .then(data => Promise.all([
        data,
        Promise.resolve(parseTriples && parseLD(data))
      ]))
      .then(([data, triples]) => {
        updateRequest(SUCCESS, {
          url,
          statusCode,
          responseHeaders,
          responseData: Immutable.fromJS(data),
          responseTriples: triples
        })
      })
      .catch(err => {
        // TODO: Log stacktrace
        updateRequest(FAILURE, {
          url,
          statusCode: err.statusCode,
          responseHeaders,
          responseError: err.data
        });
      });

    return { requestID, promise }
  }
}

function typeFromRecord(record) {
  const Note = require('./records/note')
      , Topic = require('./records/topic')
      , Document = require('./records/document')

  if (record instanceof Document) return 'document';
  if (record instanceof Topic) return 'topic';
  if (record instanceof Note) return 'note';

  throw new Error('Could not detect item type from record.');
}

function saveItem(id, projectURL, record) {
  return dispatch => {
    const isNew = id === null
        , type = typeFromRecord(record)
        , method = isNew ? 'post' : 'put'
        , body = JSON.stringify(record)

    let url = `${projectURL}${type}s/`

    if (!isNew) {
      url += `${id}/`;
    }

    if (type === 'topic' && !isNew) {
      url += 'w/';
    }

    return dispatch(fetchAPIResource(url, { method, body }));
  }
}

module.exports = {
  fetchAPIResource,
  navigateToPath,
  saveItem,
}
<commit_msg>Pass triples in actions as Immutable.List<commit_after>"use strict";

const Immutable = require('immutable')
    , apiFetch = require('./utils/api_fetch')
    , handleResponse = require('./utils/handle_response')
    , parseLD = require('./utils/parse_ld')

const {
  REQUEST_API_RESOURCE,
  REQUEST_NAVIGATION,
} = require('./types').actions

const {
  PENDING,
  SUCCESS,
  FAILURE,
} = require('./types').readyStates

function dispatchReadyState(dispatch, type) {
  const started = new Date().getTime()
      , requestID = Math.random().toString(16).slice(2)

  return (readyState, opts) =>
    dispatch(Object.assign({}, opts, {
      requestID,
      type,
      readyState,
      started,
      updated: new Date().getTime(),
    }))
}

function navigateToPath(router, path, req=null) {
  return dispatch => {
    const match = router.match(path)
        , { resource, makeTripleStore } = match.handler
        , apiPath = resource ? resource(path) : null
        , headers = {}

    const updateRequest = dispatchReadyState(dispatch, REQUEST_NAVIGATION);

    if (req) {
      headers.Host = req.headers.host;
      headers.cookie = req.headers.cookie;
    }

    const { requestID } = updateRequest(PENDING, { path, apiPath });

    const promises = [
      dispatch(fetchAPIResource('/me/', { headers })).promise,
      apiPath && dispatch(
        fetchAPIResource(apiPath, { headers }, makeTripleStore)
      ).promise
    ]

    const promise = Promise.all(promises).then(
      () => {
        updateRequest(SUCCESS, { path, apiPath });
      },
      err => {
        updateRequest(FAILURE, { path, apiPath, err });
      }
    )

    return { requestID, promise }
  }
}

const PASSED_HEADERS = [
  'Location',
  'Date',
  'Content-Type',
]

function fetchAPIResource(url, opts={}, parseTriples=false) {
  return (dispatch) => {
    let statusCode
      , responseHeaders = {}

    const updateRequest = dispatchReadyState(dispatch, REQUEST_API_RESOURCE);

    if (!process.browser) {
      url = global.API_URL + url;
    }

    const { requestID } = updateRequest(PENDING, { url });

    opts.headers = Object.assign({}, opts.headers, {
      Accept: 'application/ld+json'
    });

    const promise = apiFetch(url, opts)
      .then(handleResponse)
      .then(resp => {

        statusCode = resp.status;

        PASSED_HEADERS.forEach(header => {
          const value = resp.headers.get(header);

          if (value) {
            responseHeaders[header] = value;
          }
        });

        return resp.json();
      })
      .then(data => Promise.all([
        data,
        Promise.resolve(parseTriples && parseLD(data))
      ]))
      .then(([data, triples]) => {
        updateRequest(SUCCESS, {
          url,
          statusCode,
          responseHeaders,
          responseData: Immutable.fromJS(data),
          responseTriples: Immutable.fromJS(triples)
        })
      })
      .catch(err => {
        // TODO: Log stacktrace
        updateRequest(FAILURE, {
          url,
          statusCode: err.statusCode,
          responseHeaders,
          responseError: err.data
        });
      });

    return { requestID, promise }
  }
}

function typeFromRecord(record) {
  const Note = require('./records/note')
      , Topic = require('./records/topic')
      , Document = require('./records/document')

  if (record instanceof Document) return 'document';
  if (record instanceof Topic) return 'topic';
  if (record instanceof Note) return 'note';

  throw new Error('Could not detect item type from record.');
}

function saveItem(id, projectURL, record) {
  return dispatch => {
    const isNew = id === null
        , type = typeFromRecord(record)
        , method = isNew ? 'post' : 'put'
        , body = JSON.stringify(record)

    let url = `${projectURL}${type}s/`

    if (!isNew) {
      url += `${id}/`;
    }

    if (type === 'topic' && !isNew) {
      url += 'w/';
    }

    return dispatch(fetchAPIResource(url, { method, body }));
  }
}

module.exports = {
  fetchAPIResource,
  navigateToPath,
  saveItem,
}
<|endoftext|>


<commit_before>'use strict';
angular.module('myApp.controllers.public', [])

// Homepage controller
.controller('PublicCtrl', function($scope, $rootScope, firebaseData, headerService, $http, $location) {
  	$scope.allGroups = [];
	$scope.selected = false;
    $scope.allGroupsRef = firebase.database().ref('groups');
	$scope.clearForm = function(){
		$scope.newName = "";
		$scope.newDesc = "";
		$scope.unlChecked = true;
	}
	$scope.userIDtoname = {};
	$scope.nametoemail = {};
	$scope.currEmails = [];
	$scope.unlChecked = true;
	$scope.groupId;

	$scope.createUserHashMap = function(){
		$http({
			method: 'GET',
			url: 'https://groupgenius-5953b.firebaseio.com/users.json'
		}).then(function successCallback(response) {
			for(var key in response.data){
				$scope.userIDtoname[response.data[key].uid] = response.data[key].firstName + " " + response.data[key].lastName;
				$scope.nametoemail[response.data[key].firstName + " " + response.data[key].lastName] = response.data[key].email;
			}
			for(var c = 0; c < $scope.allGroups.length; c++){
				for(var d= 0; d < $scope.allGroups[c].members.length; ++d){

					$scope.allGroups[c].members[d] = $scope.userIDtoname[$scope.allGroups[c].members[d]];
				}
			}
		});
	}
    //event listener that updates when groups are added to the database
    $scope.allGroupsRef.on('value', function(snapshot) {
    	console.log("groups updated");
    	console.log(snapshot.val());
    	var groupObj = snapshot.val();
	$scope.allGroups = [];
    	for( var key in groupObj) {
    		var group = groupObj[key];
    		group.groupid = key;
    		$scope.allGroups.push(group);
    	}
		$scope.createUserHashMap();
        //Apply causing issues. Commented out for now and everything seems to be working okay.
    	// $scope.$apply();
    	//console.log($scope.allGroups);

	});
	$scope.classes = [];

	$scope.getClasses = function()
	{
		$http.get('https://groupgenius-5953b.firebaseio.com/organizations.json').success(
			function (response) { $scope.classes  = response; $scope.currentClass = $scope.classes[0]});
	}
	$scope.getClasses();
	$scope.currentClass = $scope.classes[0];
	$scope.currentGroupName = "Select a Group!"

	$scope.isActiveClass = function(clas){
		if($scope.currentClass == clas) {
			return true;
		}
		return false;
	}

	$scope.updateGroup = function(group) {
		$scope.selected = true;
		$scope.currentGroup = group;
		$scope.currentGroupName = group.name;
		$scope.currentMembers = $scope.formatMembers(group.members);

		if(group.spots == -1) {
			$scope.openSpots = 'Open Spots: Unlimited';
		} else {
	 		$scope.openSpots = 'Open Spots: ' + group.spots;
		}
		$scope.desc = group.desc;

		$scope.groupId = group.groupId;

	}

	$scope.selCls = function(clas) {
		$scope.currentClass = clas;
	}

	$scope.formatMembers = function(members) {
		var s = ' ';
		for( var i = 0; i < members.length; ++i) {
			s += members[i];
			if( i < members.length - 1) {
				s += ", ";
			}
		}
		return s;
	}

	$scope.createNewGroup = function() {
		console.log("create new group");
		if(!$scope.newName || !$scope.newDesc) {
			alert("You must designate a name and description. Your group has NOT been created!");
			return;
		}

		var numSpots = 0;
		if($scope.unlChecked) {
			numSpots = -1;
		} else {
			numSpots = $("#limitSelect").val();
		}

		$scope.currentClass = document.getElementById("orgSelect").value;
		$scope.writeNewPost($scope.newName, $scope.newDesc, numSpots, document.getElementById("orgSelect").value, $("#approveCheckBox").val());

	}

	$scope.writeNewPost = function(name, desc, spots, org, mustApprove) {

		console.log("writing a new post");

		var members = [];
		//add the creator of the group to the members
		members.push(firebase.auth().currentUser.uid);

		// A post entry.
		var newGroup = {
			name: name,
			desc: desc,
			members: members,
			spots: spots,
			mustApprove: mustApprove,
			org: org,
			groupId: 0 // null at first
		};

	  // Get a key for a new Post.
	  var newPostKey = firebase.database().ref().child('groups').push().key;

	  // Create default chat
	  var chatRef = firebase.database().ref('/chat/' + newPostKey + '/' + 'General');
	  var keyName = chatRef.push({
	  	name: 'Chatbot',
	  	text: 'Welcome to the stream!'
	  });

	  // Write the new post's data simultaneously in the posts list and the user's post list.
	  var updates = {};
	  newGroup['groupId'] = newPostKey; // update groupId
	  //write the group to the group list
	  updates['/groups/' + newPostKey] = newGroup;

	  firebase.database().ref().update(updates);

	  //window.location.href = '/app/#/private?groupId=' + newPostKey;
	}

	$scope.joinGroup = function() {
		var userId = firebase.auth().currentUser.uid;

		// Send join request if group is not open
		if ($scope.currentGroup.mustApprove == "on")
		{
			var newKey = firebase.database().ref().child('groups/' +
				 $scope.groupId + '/notifications/joinRequest').push().key;
			var updateNotif = {};

			updateNotif['/groups/' + $scope.groupId + '/notifications/joinRequest/' + newKey] = userId;
			firebase.database().ref().update(updateNotif);
		}

		else // add and take to private group
		{
			var update = {};
			var newKey = firebase.database().ref().child('groups/' +
				 $scope.groupId + '/members/').push().key;

			update['/groups/' + $scope.groupId + '/members/' + newKey] = userId;
			firebase.database().ref().update(update);
			window.location.href = '/app/#/private?groupId=' + $scope.groupId;
		}
	}

});

/*

/groups (list of groups)
	/groupId (a certain group object)
		/currentMembers (list of user objects)
			/userID (a certain user object)
				/name

*/

<commit_msg>Changed joinRequest key to userId for easy lookup<commit_after>'use strict';
angular.module('myApp.controllers.public', [])

// Homepage controller
.controller('PublicCtrl', function($scope, $rootScope, firebaseData, headerService, $http, $location) {
  	$scope.allGroups = [];
	$scope.selected = false;
    $scope.allGroupsRef = firebase.database().ref('groups');
	$scope.clearForm = function(){
		$scope.newName = "";
		$scope.newDesc = "";
		$scope.unlChecked = true;
	}
	$scope.userIDtoname = {};
	$scope.nametoemail = {};
	$scope.currEmails = [];
	$scope.unlChecked = true;
	$scope.groupId;

	$scope.createUserHashMap = function(){
		$http({
			method: 'GET',
			url: 'https://groupgenius-5953b.firebaseio.com/users.json'
		}).then(function successCallback(response) {
			for(var key in response.data){
				$scope.userIDtoname[response.data[key].uid] = response.data[key].firstName + " " + response.data[key].lastName;
				$scope.nametoemail[response.data[key].firstName + " " + response.data[key].lastName] = response.data[key].email;
			}
			for(var c = 0; c < $scope.allGroups.length; c++){
				for(var d= 0; d < $scope.allGroups[c].members.length; ++d){

					$scope.allGroups[c].members[d] = $scope.userIDtoname[$scope.allGroups[c].members[d]];
				}
			}
		});
	}
    //event listener that updates when groups are added to the database
    $scope.allGroupsRef.on('value', function(snapshot) {
    	console.log("groups updated");
    	console.log(snapshot.val());
    	var groupObj = snapshot.val();
	$scope.allGroups = [];
    	for( var key in groupObj) {
    		var group = groupObj[key];
    		group.groupid = key;
    		$scope.allGroups.push(group);
    	}
		$scope.createUserHashMap();
        //Apply causing issues. Commented out for now and everything seems to be working okay.
    	// $scope.$apply();
    	//console.log($scope.allGroups);

	});
	$scope.classes = [];

	$scope.getClasses = function()
	{
		$http.get('https://groupgenius-5953b.firebaseio.com/organizations.json').success(
			function (response) { $scope.classes  = response; $scope.currentClass = $scope.classes[0]});
	}
	$scope.getClasses();
	$scope.currentClass = $scope.classes[0];
	$scope.currentGroupName = "Select a Group!"

	$scope.isActiveClass = function(clas){
		if($scope.currentClass == clas) {
			return true;
		}
		return false;
	}

	$scope.updateGroup = function(group) {
		$scope.selected = true;
		$scope.currentGroup = group;
		$scope.currentGroupName = group.name;
		$scope.currentMembers = $scope.formatMembers(group.members);

		if(group.spots == -1) {
			$scope.openSpots = 'Open Spots: Unlimited';
		} else {
	 		$scope.openSpots = 'Open Spots: ' + group.spots;
		}
		$scope.desc = group.desc;

		$scope.groupId = group.groupId;

	}

	$scope.selCls = function(clas) {
		$scope.currentClass = clas;
	}

	$scope.formatMembers = function(members) {
		var s = ' ';
		for( var i = 0; i < members.length; ++i) {
			s += members[i];
			if( i < members.length - 1) {
				s += ", ";
			}
		}
		return s;
	}

	$scope.createNewGroup = function() {
		console.log("create new group");
		if(!$scope.newName || !$scope.newDesc) {
			alert("You must designate a name and description. Your group has NOT been created!");
			return;
		}

		var numSpots = 0;
		if($scope.unlChecked) {
			numSpots = -1;
		} else {
			numSpots = $("#limitSelect").val();
		}

		$scope.currentClass = document.getElementById("orgSelect").value;
		$scope.writeNewPost($scope.newName, $scope.newDesc, numSpots, document.getElementById("orgSelect").value, $("#approveCheckBox").val());

	}

	$scope.writeNewPost = function(name, desc, spots, org, mustApprove) {

		console.log("writing a new post");

		var members = [];
		//add the creator of the group to the members
		members.push(firebase.auth().currentUser.uid);

		// A post entry.
		var newGroup = {
			name: name,
			desc: desc,
			members: members,
			spots: spots,
			mustApprove: mustApprove,
			org: org,
			groupId: 0 // null at first
		};

	  // Get a key for a new Post.
	  var newPostKey = firebase.database().ref().child('groups').push().key;

	  // Create default chat
	  var chatRef = firebase.database().ref('/chat/' + newPostKey + '/' + 'General');
	  var keyName = chatRef.push({
	  	name: 'Chatbot',
	  	text: 'Welcome to the stream!'
	  });

	  // Write the new post's data simultaneously in the posts list and the user's post list.
	  var updates = {};
	  newGroup['groupId'] = newPostKey; // update groupId
	  //write the group to the group list
	  updates['/groups/' + newPostKey] = newGroup;

	  firebase.database().ref().update(updates);

	  //window.location.href = '/app/#/private?groupId=' + newPostKey;
	}

	$scope.joinGroup = function() {
		var userId = firebase.auth().currentUser.uid;

		// Send join request if group is not open
		if ($scope.currentGroup.mustApprove == "on")
		{
			var newKey = userId;
			var updateNotif = {};

			updateNotif['/groups/' + $scope.groupId + '/notifications/joinRequest/' + newKey] = userId;
			firebase.database().ref().update(updateNotif);
		}

		else // add and take to private group
		{
			var update = {};
			var newKey = userId;

			update['/groups/' + $scope.groupId + '/members/' + newKey] = userId;
			firebase.database().ref().update(update);
			window.location.href = '/app/#/private?groupId=' + $scope.groupId;
		}
	}

});

/*

/groups (list of groups)
	/groupId (a certain group object)
		/currentMembers (list of user objects)
			/userID (a certain user object)
				/name

*/

<|endoftext|>


<commit_before>import React from "react";
import * as helpers from "../../helpers.js";

//Import menu styles
import "@siimple/css/scss/components/menu.scss";

//Menu component
export const Menu = function (props) {
    return helpers.createMergedElement("div", props, {
        "className": "siimple-menu"
    });
};

//Menu group component
export const MenuGroup = function (props) {
    return helpers.createMergedElement("div", props, {
        "className": "siimple-menu-group"
    });
};

//Menu item
export const MenuItem = function (props) {
    //Clone the properties
    let newProps = helpers.filterProps(props, ["selected", "className"]);
    //Initialize the menu item class list
    let classList = ["siimple-menu-item"];
    //Check the selected attribute
    if (props.selected === true) {
        classList.push("siimple-menu-item--selected");
    }
    //Generate the menu item classname
    newProps.className = helpers.classNames(classList, props.className);
    //Return the menu item element
    return React.createElement("div", newProps, props.children);
};

//Menu item default props
MenuItem.defaultProps = {
    "selected": false
};

//Menu divider
export const MenuDivider = function (props) {
    return helpers.createMergedElement("div", props, {
        "className": "siimple-menu-divider"
    });
};

<commit_msg>neutrine: renamed selected property of menu-item component to active<commit_after>import React from "react";
import * as helpers from "../../helpers.js";
import "@siimple/css/scss/components/menu.scss";

//Menu component
export const Menu = function (props) {
    return helpers.createMergedElement("div", props, {
        "className": "siimple-menu"
    });
};

//Menu group component
export const MenuGroup = function (props) {
    return helpers.createMergedElement("div", props, {
        "className": "siimple-menu-group"
    });
};

//Menu item
export const MenuItem = function (props) {
    let newProps = helpers.filterProps(props, ["active", "className"]);
    Object.assign(newProps, {
        "className": helpers.classNames({
            "siimple-menu-item": true,
            "siimple-menu-item--active": props.active
        }, props.className)
    });
    //Return the menu item element
    return React.createElement("div", newProps, props.children);
};

//Menu item default props
MenuItem.defaultProps = {
    "active": false
};

//Menu divider
export const MenuDivider = function (props) {
    return helpers.createMergedElement("div", props, {
        "className": "siimple-menu-divider"
    });
};

<|endoftext|>


<commit_before>'use strict';

var EventEmitter     = require('events').EventEmitter,
    http             = require('http'),
    propagate        = require('propagate'),
    DelayedBody      = require('./delayed_body'),
    OutgoingMessage  = http.OutgoingMessage,
    ClientRequest    = http.ClientRequest,
    common           = require('./common'),
    Socket           = require('./socket'),
    _                = require('lodash'),
    debug            = require('debug')('nock.request_overrider'),
    timers           = require('timers');

function getHeader(request, name) {
  if (!request._headers) {
    return;
  }

  var key = name.toLowerCase();

  return request._headers[key];
}

function setHeader(request, name, value) {
  debug('setHeader', name, value);
  var key = name.toLowerCase();

  request._headers = request._headers || {};
  request._headerNames = request._headerNames || {};
  request._removedHeader = request._removedHeader || {};

  request._headers[key] = value;
  request._headerNames[key] = name;

  if (name == 'expect' && value == '100-continue') {
    timers.setImmediate(function() {
      debug('continue');
      request.emit('continue');
    });
  }
}

function isStream(obj) {
  var is = obj && (typeof obj !== 'string') && (!Buffer.isBuffer(obj)) && (typeof obj.setEncoding === 'function');
  return is;
}

//  Sets request headers of the given request. This is needed during both matching phase
//  (in case header filters were specified) and mocking phase (to correctly pass mocked
//  request headers).
function setRequestHeaders(req, options, interceptor) {
  //  We mock request headers if these were specified.
  if (interceptor.reqheaders) {
    var reqheaders = interceptor.reqheaders;
    _(interceptor.reqheaders).keys().each(function(key) {
      setHeader(req, key, reqheaders[key]);
    });
  }

  //  If a filtered scope is being used we have to use scope's host
  //  in the header, otherwise 'host' header won't match.
  //  NOTE: We use lower-case header field names throught Nock.
  var HOST_HEADER = 'host';
  if(interceptor.__nock_filteredScope && interceptor.__nock_scopeHost) {
    if(options && options.headers) {
      options.headers[HOST_HEADER] = interceptor.__nock_scopeHost;
    }
    setHeader(req, HOST_HEADER, interceptor.__nock_scopeHost);
  } else {
    //  For all other cases, we always add host header equal to the
    //  requested host unless it was already defined.
    if (options.host && !getHeader(req, HOST_HEADER)) {
      var hostHeader = options.host;

      if (options.port === 80 || options.port === 443) {
        hostHeader = hostHeader.split(':')[0];
      }

      setHeader(req, HOST_HEADER, hostHeader);
    }
  }

}

function RequestOverrider(req, options, interceptors, remove, cb) {

  var response = new OutgoingMessage(new EventEmitter()),
      requestBodyBuffers = [],
      originalInterceptors = interceptors,
      aborted,
      emitError,
      end,
      ended,
      headers,
      keys,
      key,
      i,
      l;

  //  We may be changing the options object and we don't want those
  //  changes affecting the user so we use a clone of the object.
  options = _.clone(options) || {};

  response.req = req;

  if (options.headers) {
    //  We use lower-case header field names throught Nock.
    options.headers = common.headersFieldNamesToLowerCase(options.headers);

    headers = options.headers;
    keys = Object.keys(headers);

    for (i = 0, l = keys.length; i < l; i++) {
      key = keys[i];

      setHeader(req, key, headers[key]);
    }
  }

  /// options.auth
  if (options.auth && (! options.headers || ! options.headers.authorization)) {
    setHeader(req, 'Authorization', 'Basic ' + (new Buffer(options.auth)).toString('base64'));
  }

  // Mock response.connection and request.connection
  // Fixes: https://github.com/flatiron/nock/issues/74
  if (! response.connection) {
    response.connection = new EventEmitter();
  }

  if (! req.connection) {
    req.connection = new EventEmitter();
  }

  req.path = options.path;

  options.getHeader = function(name) {
    return getHeader(req, name);
  };

  req.socket = Socket();

  req.write = function(buffer, encoding) {
    debug('write', arguments);
    if (buffer && !aborted) {
      if (! Buffer.isBuffer(buffer)) {
        buffer = new Buffer(buffer, encoding);
      }
      requestBodyBuffers.push(buffer);
    }
    if (aborted) {
      emitError(new Error('Request aborted'));
    }

    timers.setImmediate(function() {
      req.emit('drain');
    });

    return false;
  };

  req.end = function(buffer, encoding) {
    debug('req.end');
    if (!aborted && !ended) {
      req.write(buffer, encoding);
      end(cb);
      req.emit('finish');
      req.emit('end');
    }
    if (aborted) {
      emitError(new Error('Request aborted'));
    }
  };

  req.abort = function() {
    debug('req.abort');
    aborted = true;
    if (!ended) {
      end();
    }
    var err = new Error();
    err.code = 'aborted';
    response.emit('close', err);

    req.socket.destroy();
  };

  // restify listens for a 'socket' event to
  // be emitted before calling end(), which causes
  // nock to hang with restify. The following logic
  // fakes the socket behavior for restify,
  // Fixes: https://github.com/pgte/nock/issues/79
  req.once = req.on = function(event, listener) {
    // emit a fake socket.
    if (event == 'socket') {
      listener(req.socket);
      req.socket.emit('connect', req.socket);
      req.socket.emit('secureConnect', req.socket);
    }

    EventEmitter.prototype.on.call(this, event, listener);
    return this;
  };

  emitError = function(error) {
    process.nextTick(function () {
      req.emit('error', error);
    });
  };

  end = function(cb) {
    debug('ending');
    ended = true;
    var encoding,
        requestBody,
        responseBody,
        responseBuffers,
        interceptor,
        paused,
        mockEmits = [];

    //  When request body is a binary buffer we internally use in its hexadecimal representation.
    var requestBodyBuffer = common.mergeChunks(requestBodyBuffers);
    var isBinaryRequestBodyBuffer = common.isBinaryBuffer(requestBodyBuffer);
    if(isBinaryRequestBodyBuffer) {
      requestBody = requestBodyBuffer.toString('hex');
    } else {
      requestBody = requestBodyBuffer.toString('utf8');
    }

    /// put back the path into options
    /// because bad behaving agents like superagent
    /// like to change request.path in mid-flight.
    options.path = req.path;
    interceptors = interceptors.filter(function(interceptor) {
      //  For correct matching we need to have correct request headers - if these were specified.
      setRequestHeaders(req, options, interceptor);

      return interceptor.match(options, requestBody);
    });

    if (interceptors.length < 1) {
      // Try to find a hostname match
      interceptors = originalInterceptors.filter(function(interceptor) {
        return interceptor.match(options, requestBody, true);
      });
      if (interceptors.length && req instanceof ClientRequest) {
        interceptor = interceptors[0];
        if (interceptor.options.allowUnmocked) {
          var newReq = new ClientRequest(options, cb);
          propagate(newReq, req);
          //  We send the raw buffer as we received it, not as we interpreted it.
          newReq.end(requestBodyBuffer);
          return;
        }
      }

      emitError(new Error("Nock: No match for request " + common.stringifyRequest(options, requestBody)));
      return;
    }

    debug('interceptor identified, starting mocking');

    interceptor = interceptors.shift();

    response.statusCode = interceptor.statusCode || 200;
    response.headers = interceptor.headers || {};

    //  We again set request headers, now for our matched interceptor.
    setRequestHeaders(req, options, interceptor);

    if (typeof interceptor.body === 'function') {
      // In case we are waiting for a callback
      if (interceptor.body.length === 3) {
        return interceptor.body(options.path, requestBody || '', continueWithResponseBody);
      }
      responseBody = interceptor.body(options.path, requestBody) || '';

    } else {

      //  If the content is encoded we know that the response body *must* be an array
      //  of response buffers which should be mocked one by one.
      //  (otherwise decompressions after the first one fails as unzip expects to receive
      //  buffer by buffer and not one single merged buffer)
      if(common.isContentEncoded(response.headers) && ! isStream(interceptor.body)) {

        if (interceptor.delayInMs) {
          emitError(new Error('Response delay is currently not supported with content-encoded responses.'));
          return;
        }

        var buffers = interceptor.body;
        if(!_.isArray(buffers)) {
          emitError(
            new Error(
              'content-encoded response must be an array of binary buffers and not ' + typeof(buffers)));
          return;
        }

        responseBuffers = _.map(buffers, function(buffer) {
          return new Buffer(buffer, 'hex');
        });

      } else {

        responseBody = interceptor.body;

        //  If the request was binary then we assume that the response will be binary as well.
        //  In that case we send the response as a Buffer object as that's what the client will expect.
        if(isBinaryRequestBodyBuffer && typeof(responseBody) === 'string') {
          //  Try to create the buffer from the interceptor's body response as hex.
          try {
            responseBody = new Buffer(responseBody, 'hex');
          } catch(err) {
            debug('exception during Buffer construction from hex data:', responseBody, '-', err);
          }

          // Creating buffers does not necessarily throw errors, check for difference in size
          if (!responseBody || (interceptor.body.length > 0 && responseBody.length === 0)) {
            //  We fallback on constructing buffer from utf8 representation of the body.
            responseBody = new Buffer(interceptor.body, 'utf8');
          }
        }

      }
    }
    return continueWithResponseBody(null, responseBody);

    function continueWithResponseBody(err, responseBody) {
      if (err) {
        response.statusCode = 500;
        responseBody = err.stack;

      }

      //  Transform the response body if it exists (it may not exist
      //  if we have `responseBuffers` instead)

      if (responseBody) {
        debug('transform the response body');

        if (!Buffer.isBuffer(responseBody) && !isStream(responseBody)) {
          if (typeof responseBody === 'string') {
            responseBody = new Buffer(responseBody);
          } else {
            responseBody = JSON.stringify(responseBody);
          }
        }

        if (interceptor.delayInMs) {
          debug('delaying the response for', interceptor.delayInMs, 'milliseconds');
          responseBody = new DelayedBody(interceptor.delayInMs, responseBody);
        }

        if (isStream(responseBody)) {
          debug('response body is a stream');
          responseBody.pause();
          responseBody.on('data', function(d) {
            response.emit('data', d);
          });
          responseBody.on('end', function() {
            response.emit('end');
          });
          responseBody.on('error', function(err) {
            response.emit('error', err);
          });
        } else if (responseBody && !Buffer.isBuffer(responseBody)) {
          if (typeof responseBody === 'string') {
            responseBody = new Buffer(responseBody);
          } else {
            responseBody = JSON.stringify(responseBody);
            response.headers['content-type'] = 'application/json';
          }
        }
      }

      remove(interceptor);
      interceptor.discard();

      if (aborted) { return; }

      response.setEncoding = function(newEncoding) {
        encoding = newEncoding;
      };

      response.pause = function() {
        debug('pausing mocking');
        paused = true;
        if (isStream(responseBody)) {
          responseBody.pause();
        }
      };

      response.resume = function() {
        debug('resuming mocking');
        paused = false;
        if (isStream(responseBody)) {
          responseBody.resume();
        }
        mockNextEmit();
      };

      var read = false;
      response.read = function() {
        debug('reading response body');
        if (isStream(responseBody) && responseBody.read) {
          return responseBody.read();
        } else {
          if (! read) {
            read = true;
            return responseBody;
          } else {
            return null;
          }
        }
      };

      //  HACK: Flag our response object as readable so that it can be automatically
      //    resumed by Node when drain happens. This enables working with some agents
      //    that behave differently than built-in agent (e.g. needle, superagent).
      //    The correct way to implement this would be to use IncomingMessage instead
      //    of OutgoingMessage class to mock responses.
      response.readable = true;

      /// response.client.authorized = true
      /// fixes https://github.com/pgte/nock/issues/158
      response.client = _.extend(response.client || {}, {
        authorized: true
      });

      //  `mockEmits` is an array of emits to be performed during mocking.
      if (typeof responseBody !== "undefined") {
        mockEmits.push(function() {
          if (encoding) {
            debug('transforming body per its encoding');
            if (isStream(responseBody)) {
              responseBody.setEncoding(encoding);
            } else {
              responseBody = responseBody.toString(encoding);
            }
          }
          if (! isStream(responseBody)) {
            debug('emitting response body');
            response.emit('data', responseBody);
            response.emit('readable');
          }
        });
      } else {
        //  We will emit response buffers one by one.
        _.each(responseBuffers, function(buffer) {
          mockEmits.push(function() {
            debug('emitting response buffer');
            response.emit('data', buffer);
            response.emit('readable');
          });
        });
      }

      if (!isStream(responseBody)) {
        mockEmits.push(function() {
          debug('emitting end');
          response.emit('end');
        });
      }

      function mockNextEmit() {
        debug('mocking next emit');

        //  We don't use `process.nextTick` because we *want* (very much so!)
        //  for I/O to happen before the next `emit` since we are precisely mocking I/O.
        //  Otherwise the writing to output pipe may stall invoking pause()
        //  without ever calling resume() (the observed was behavior on superagent
        //  with Node v0.10.26)
        timers.setImmediate(function() {
          if (paused || mockEmits.length === 0 || aborted) {
            debug('mocking paused, aborted or finished');
            return;
          }

          var nextMockEmit = mockEmits.shift();
          nextMockEmit();

          //  Recursively invoke to mock the next emit after the last one was handled.
          mockNextEmit();
        });
      }

      debug('mocking', mockEmits.length, 'emits');

      process.nextTick(function() {
        var respond = function() {
          debug('emitting response');

          if (typeof cb === 'function') {
            debug('callback with response');
            cb(response);
          }

          if (aborted) {
            emitError(new Error('Request aborted'));
          }
          else {
            req.emit('response', response);
          }

          if (isStream(responseBody)) {
            debug('resuming response stream');
            responseBody.resume();
          }

          mockNextEmit();
        };

        if (interceptor.socketDelayInMs && interceptor.socketDelayInMs > 0) {
          req.socket._checkTimeout(interceptor.socketDelayInMs);
        }

        if (interceptor.delayConnectionInMs && interceptor.delayConnectionInMs > 0) {
          setTimeout(respond, interceptor.delayConnectionInMs);
        } else {
          respond();
        }
      });
    }
  };

  return req;
}

module.exports = RequestOverrider;
<commit_msg>setting 404 as status code in no match errors to help some server defaults<commit_after>'use strict';

var EventEmitter     = require('events').EventEmitter,
    http             = require('http'),
    propagate        = require('propagate'),
    DelayedBody      = require('./delayed_body'),
    OutgoingMessage  = http.OutgoingMessage,
    ClientRequest    = http.ClientRequest,
    common           = require('./common'),
    Socket           = require('./socket'),
    _                = require('lodash'),
    debug            = require('debug')('nock.request_overrider'),
    timers           = require('timers');

function getHeader(request, name) {
  if (!request._headers) {
    return;
  }

  var key = name.toLowerCase();

  return request._headers[key];
}

function setHeader(request, name, value) {
  debug('setHeader', name, value);
  var key = name.toLowerCase();

  request._headers = request._headers || {};
  request._headerNames = request._headerNames || {};
  request._removedHeader = request._removedHeader || {};

  request._headers[key] = value;
  request._headerNames[key] = name;

  if (name == 'expect' && value == '100-continue') {
    timers.setImmediate(function() {
      debug('continue');
      request.emit('continue');
    });
  }
}

function isStream(obj) {
  var is = obj && (typeof obj !== 'string') && (!Buffer.isBuffer(obj)) && (typeof obj.setEncoding === 'function');
  return is;
}

//  Sets request headers of the given request. This is needed during both matching phase
//  (in case header filters were specified) and mocking phase (to correctly pass mocked
//  request headers).
function setRequestHeaders(req, options, interceptor) {
  //  We mock request headers if these were specified.
  if (interceptor.reqheaders) {
    var reqheaders = interceptor.reqheaders;
    _(interceptor.reqheaders).keys().each(function(key) {
      setHeader(req, key, reqheaders[key]);
    });
  }

  //  If a filtered scope is being used we have to use scope's host
  //  in the header, otherwise 'host' header won't match.
  //  NOTE: We use lower-case header field names throught Nock.
  var HOST_HEADER = 'host';
  if(interceptor.__nock_filteredScope && interceptor.__nock_scopeHost) {
    if(options && options.headers) {
      options.headers[HOST_HEADER] = interceptor.__nock_scopeHost;
    }
    setHeader(req, HOST_HEADER, interceptor.__nock_scopeHost);
  } else {
    //  For all other cases, we always add host header equal to the
    //  requested host unless it was already defined.
    if (options.host && !getHeader(req, HOST_HEADER)) {
      var hostHeader = options.host;

      if (options.port === 80 || options.port === 443) {
        hostHeader = hostHeader.split(':')[0];
      }

      setHeader(req, HOST_HEADER, hostHeader);
    }
  }

}

function RequestOverrider(req, options, interceptors, remove, cb) {

  var response = new OutgoingMessage(new EventEmitter()),
      requestBodyBuffers = [],
      originalInterceptors = interceptors,
      aborted,
      emitError,
      end,
      ended,
      headers,
      keys,
      key,
      i,
      l;

  //  We may be changing the options object and we don't want those
  //  changes affecting the user so we use a clone of the object.
  options = _.clone(options) || {};

  response.req = req;

  if (options.headers) {
    //  We use lower-case header field names throught Nock.
    options.headers = common.headersFieldNamesToLowerCase(options.headers);

    headers = options.headers;
    keys = Object.keys(headers);

    for (i = 0, l = keys.length; i < l; i++) {
      key = keys[i];

      setHeader(req, key, headers[key]);
    }
  }

  /// options.auth
  if (options.auth && (! options.headers || ! options.headers.authorization)) {
    setHeader(req, 'Authorization', 'Basic ' + (new Buffer(options.auth)).toString('base64'));
  }

  // Mock response.connection and request.connection
  // Fixes: https://github.com/flatiron/nock/issues/74
  if (! response.connection) {
    response.connection = new EventEmitter();
  }

  if (! req.connection) {
    req.connection = new EventEmitter();
  }

  req.path = options.path;

  options.getHeader = function(name) {
    return getHeader(req, name);
  };

  req.socket = Socket();

  req.write = function(buffer, encoding) {
    debug('write', arguments);
    if (buffer && !aborted) {
      if (! Buffer.isBuffer(buffer)) {
        buffer = new Buffer(buffer, encoding);
      }
      requestBodyBuffers.push(buffer);
    }
    if (aborted) {
      emitError(new Error('Request aborted'));
    }

    timers.setImmediate(function() {
      req.emit('drain');
    });

    return false;
  };

  req.end = function(buffer, encoding) {
    debug('req.end');
    if (!aborted && !ended) {
      req.write(buffer, encoding);
      end(cb);
      req.emit('finish');
      req.emit('end');
    }
    if (aborted) {
      emitError(new Error('Request aborted'));
    }
  };

  req.abort = function() {
    debug('req.abort');
    aborted = true;
    if (!ended) {
      end();
    }
    var err = new Error();
    err.code = 'aborted';
    response.emit('close', err);

    req.socket.destroy();
  };

  // restify listens for a 'socket' event to
  // be emitted before calling end(), which causes
  // nock to hang with restify. The following logic
  // fakes the socket behavior for restify,
  // Fixes: https://github.com/pgte/nock/issues/79
  req.once = req.on = function(event, listener) {
    // emit a fake socket.
    if (event == 'socket') {
      listener(req.socket);
      req.socket.emit('connect', req.socket);
      req.socket.emit('secureConnect', req.socket);
    }

    EventEmitter.prototype.on.call(this, event, listener);
    return this;
  };

  emitError = function(error) {
    process.nextTick(function () {
      req.emit('error', error);
    });
  };

  end = function(cb) {
    debug('ending');
    ended = true;
    var encoding,
        requestBody,
        responseBody,
        responseBuffers,
        interceptor,
        paused,
        mockEmits = [];

    //  When request body is a binary buffer we internally use in its hexadecimal representation.
    var requestBodyBuffer = common.mergeChunks(requestBodyBuffers);
    var isBinaryRequestBodyBuffer = common.isBinaryBuffer(requestBodyBuffer);
    if(isBinaryRequestBodyBuffer) {
      requestBody = requestBodyBuffer.toString('hex');
    } else {
      requestBody = requestBodyBuffer.toString('utf8');
    }

    /// put back the path into options
    /// because bad behaving agents like superagent
    /// like to change request.path in mid-flight.
    options.path = req.path;
    interceptors = interceptors.filter(function(interceptor) {
      //  For correct matching we need to have correct request headers - if these were specified.
      setRequestHeaders(req, options, interceptor);

      return interceptor.match(options, requestBody);
    });

    if (interceptors.length < 1) {
      // Try to find a hostname match
      interceptors = originalInterceptors.filter(function(interceptor) {
        return interceptor.match(options, requestBody, true);
      });
      if (interceptors.length && req instanceof ClientRequest) {
        interceptor = interceptors[0];
        if (interceptor.options.allowUnmocked) {
          var newReq = new ClientRequest(options, cb);
          propagate(newReq, req);
          //  We send the raw buffer as we received it, not as we interpreted it.
          newReq.end(requestBodyBuffer);
          return;
        }
      }

      var err = new Error("Nock: No match for request " + common.stringifyRequest(options, requestBody));
      err.statusCode = err.status = 404;
      emitError(err);
      return;
    }

    debug('interceptor identified, starting mocking');

    interceptor = interceptors.shift();

    response.statusCode = interceptor.statusCode || 200;
    response.headers = interceptor.headers || {};

    //  We again set request headers, now for our matched interceptor.
    setRequestHeaders(req, options, interceptor);

    if (typeof interceptor.body === 'function') {
      // In case we are waiting for a callback
      if (interceptor.body.length === 3) {
        return interceptor.body(options.path, requestBody || '', continueWithResponseBody);
      }
      responseBody = interceptor.body(options.path, requestBody) || '';

    } else {

      //  If the content is encoded we know that the response body *must* be an array
      //  of response buffers which should be mocked one by one.
      //  (otherwise decompressions after the first one fails as unzip expects to receive
      //  buffer by buffer and not one single merged buffer)
      if(common.isContentEncoded(response.headers) && ! isStream(interceptor.body)) {

        if (interceptor.delayInMs) {
          emitError(new Error('Response delay is currently not supported with content-encoded responses.'));
          return;
        }

        var buffers = interceptor.body;
        if(!_.isArray(buffers)) {
          emitError(
            new Error(
              'content-encoded response must be an array of binary buffers and not ' + typeof(buffers)));
          return;
        }

        responseBuffers = _.map(buffers, function(buffer) {
          return new Buffer(buffer, 'hex');
        });

      } else {

        responseBody = interceptor.body;

        //  If the request was binary then we assume that the response will be binary as well.
        //  In that case we send the response as a Buffer object as that's what the client will expect.
        if(isBinaryRequestBodyBuffer && typeof(responseBody) === 'string') {
          //  Try to create the buffer from the interceptor's body response as hex.
          try {
            responseBody = new Buffer(responseBody, 'hex');
          } catch(err) {
            debug('exception during Buffer construction from hex data:', responseBody, '-', err);
          }

          // Creating buffers does not necessarily throw errors, check for difference in size
          if (!responseBody || (interceptor.body.length > 0 && responseBody.length === 0)) {
            //  We fallback on constructing buffer from utf8 representation of the body.
            responseBody = new Buffer(interceptor.body, 'utf8');
          }
        }

      }
    }
    return continueWithResponseBody(null, responseBody);

    function continueWithResponseBody(err, responseBody) {
      if (err) {
        response.statusCode = 500;
        responseBody = err.stack;

      }

      //  Transform the response body if it exists (it may not exist
      //  if we have `responseBuffers` instead)

      if (responseBody) {
        debug('transform the response body');

        if (!Buffer.isBuffer(responseBody) && !isStream(responseBody)) {
          if (typeof responseBody === 'string') {
            responseBody = new Buffer(responseBody);
          } else {
            responseBody = JSON.stringify(responseBody);
          }
        }

        if (interceptor.delayInMs) {
          debug('delaying the response for', interceptor.delayInMs, 'milliseconds');
          responseBody = new DelayedBody(interceptor.delayInMs, responseBody);
        }

        if (isStream(responseBody)) {
          debug('response body is a stream');
          responseBody.pause();
          responseBody.on('data', function(d) {
            response.emit('data', d);
          });
          responseBody.on('end', function() {
            response.emit('end');
          });
          responseBody.on('error', function(err) {
            response.emit('error', err);
          });
        } else if (responseBody && !Buffer.isBuffer(responseBody)) {
          if (typeof responseBody === 'string') {
            responseBody = new Buffer(responseBody);
          } else {
            responseBody = JSON.stringify(responseBody);
            response.headers['content-type'] = 'application/json';
          }
        }
      }

      remove(interceptor);
      interceptor.discard();

      if (aborted) { return; }

      response.setEncoding = function(newEncoding) {
        encoding = newEncoding;
      };

      response.pause = function() {
        debug('pausing mocking');
        paused = true;
        if (isStream(responseBody)) {
          responseBody.pause();
        }
      };

      response.resume = function() {
        debug('resuming mocking');
        paused = false;
        if (isStream(responseBody)) {
          responseBody.resume();
        }
        mockNextEmit();
      };

      var read = false;
      response.read = function() {
        debug('reading response body');
        if (isStream(responseBody) && responseBody.read) {
          return responseBody.read();
        } else {
          if (! read) {
            read = true;
            return responseBody;
          } else {
            return null;
          }
        }
      };

      //  HACK: Flag our response object as readable so that it can be automatically
      //    resumed by Node when drain happens. This enables working with some agents
      //    that behave differently than built-in agent (e.g. needle, superagent).
      //    The correct way to implement this would be to use IncomingMessage instead
      //    of OutgoingMessage class to mock responses.
      response.readable = true;

      /// response.client.authorized = true
      /// fixes https://github.com/pgte/nock/issues/158
      response.client = _.extend(response.client || {}, {
        authorized: true
      });

      //  `mockEmits` is an array of emits to be performed during mocking.
      if (typeof responseBody !== "undefined") {
        mockEmits.push(function() {
          if (encoding) {
            debug('transforming body per its encoding');
            if (isStream(responseBody)) {
              responseBody.setEncoding(encoding);
            } else {
              responseBody = responseBody.toString(encoding);
            }
          }
          if (! isStream(responseBody)) {
            debug('emitting response body');
            response.emit('data', responseBody);
            response.emit('readable');
          }
        });
      } else {
        //  We will emit response buffers one by one.
        _.each(responseBuffers, function(buffer) {
          mockEmits.push(function() {
            debug('emitting response buffer');
            response.emit('data', buffer);
            response.emit('readable');
          });
        });
      }

      if (!isStream(responseBody)) {
        mockEmits.push(function() {
          debug('emitting end');
          response.emit('end');
        });
      }

      function mockNextEmit() {
        debug('mocking next emit');

        //  We don't use `process.nextTick` because we *want* (very much so!)
        //  for I/O to happen before the next `emit` since we are precisely mocking I/O.
        //  Otherwise the writing to output pipe may stall invoking pause()
        //  without ever calling resume() (the observed was behavior on superagent
        //  with Node v0.10.26)
        timers.setImmediate(function() {
          if (paused || mockEmits.length === 0 || aborted) {
            debug('mocking paused, aborted or finished');
            return;
          }

          var nextMockEmit = mockEmits.shift();
          nextMockEmit();

          //  Recursively invoke to mock the next emit after the last one was handled.
          mockNextEmit();
        });
      }

      debug('mocking', mockEmits.length, 'emits');

      process.nextTick(function() {
        var respond = function() {
          debug('emitting response');

          if (typeof cb === 'function') {
            debug('callback with response');
            cb(response);
          }

          if (aborted) {
            emitError(new Error('Request aborted'));
          }
          else {
            req.emit('response', response);
          }

          if (isStream(responseBody)) {
            debug('resuming response stream');
            responseBody.resume();
          }

          mockNextEmit();
        };

        if (interceptor.socketDelayInMs && interceptor.socketDelayInMs > 0) {
          req.socket._checkTimeout(interceptor.socketDelayInMs);
        }

        if (interceptor.delayConnectionInMs && interceptor.delayConnectionInMs > 0) {
          setTimeout(respond, interceptor.delayConnectionInMs);
        } else {
          respond();
        }
      });
    }
  };

  return req;
}

module.exports = RequestOverrider;
<|endoftext|>


<commit_before>(function(){

    module.exports = MouseEvents(
        require('../events-queue/events-queue.js'),
        require('../throttle/throttle.js')
    );

    function MouseEvents(_eventsQueue, _throttle){

        /*----------------------------------------------------------------------
            PRIVATE VARIABLES
         ----------------------------------------------------------------------*/
        var _root              = {},
            _dragSubscribers   = [],
            _onDownSubscribers = [],
            _onUpSubscribers   = [],
            _isHeld            = false,
            _isMoving          = false,
            _isDragging        = false,
            _mouseMoveData     = {},
            _startEvent;

        /*----------------------------------------------------------------------
            PUBLIC METHODS
        ----------------------------------------------------------------------*/

        _root.isHeld  = isHeld;
        _root.onDrag  = subscribeToDrag;
        _root.onDown  = subscribeToDown;
        _root.onUp    = subscribeToUp;

        /*----------------------------------------------------------------------
            INIT
        ----------------------------------------------------------------------*/

        init();
        return _root;

        /*----------------------------------------------------------------------
            PRIVATE METHODS
         ----------------------------------------------------------------------*/

        function init(){
            _eventsQueue.subscribe("mousedown", window, mouseDownHandler);
            _eventsQueue.subscribe("mouseup",   window, mouseUpHandler);
            _eventsQueue.subscribe("mousemove", window, onMouseMoveHandler);
            _eventsQueue.subscribe("dragstart", window, onDragStartHandler);
            _eventsQueue.subscribe("dragend",   window, onDragEndHandler);
            _eventsQueue.subscribe("drag",      window, _throttle(onDragHandler, 100));
        }

        function subscribeToDrag(fn){
            _dragSubscribers.push(fn);
        }

        function subscribeToDown(fn){
            _onDownSubscribers.push(fn);
        }

        function subscribeToUp(fn){
            _onUpSubscribers.push(fn);
        }

        function notifyDragSubscribers(){
            for(var i = 0; i < _dragSubscribers.length; i++){
                _dragSubscribers[i](_mouseMoveData)
            }
        }

        function notifyDownSubscribers(e){
            for(var i = 0; i < _onDownSubscribers.length; i++){
                _onDownSubscribers[i](e);
            }
        }

        function notifyUpSubscribers(e){
            for(var i = 0; i < _onUpSubscribers.length; i++){
                _onUpSubscribers[i](e);
            }
        }

        function isHeld(){
            return _isHeld;
        }

        function mouseDownHandler(e){
            onDown(e);
            _isHeld    = true;
            _isMoving  = true
        }

        function onDragStartHandler(e){
            onDown(e);
            _isHeld     = true;
            _isDragging = true;
        }

        function onDown(e){
            if(!_startEvent){
                _startEvent = e;
                notifyDownSubscribers(e);
            }
        }

        function mouseUpHandler(e){
            _isMoving = false;
            if(!_isDragging){
                onUp(e);
            }
        }

        function onDragEndHandler(e){
            _isDragging = false;
            if(!_isMoving){
                onUp(e);
            }
        }

        function onUp(e){
            _startEvent = null;
            _isHeld     = false;
            notifyUpSubscribers(e);
        }

        function onDragHandler(e){
            onMove(e);
        }

        function onMouseMoveHandler(e){
            if(!_isDragging){
                onMove(e);
            }
        }

        function onMove(e){
            if(_isHeld){
                updateMouseMoveData(_startEvent, e);
                notifyDragSubscribers(e);
            }
        }

        function updateMouseMoveData(startData, eventData){

            var newMouseMoveData = {};

            startData = startData || {};
            eventData = eventData || {};

            newMouseMoveData['x']       = eventData.x - startData.x;
            newMouseMoveData['y']       = eventData.y - startData.y;
            newMouseMoveData['clientX'] = eventData.clientX - startData.clientX;
            newMouseMoveData['clientY'] = eventData.clientY - startData.clientY;

            _mouseMoveData = newMouseMoveData;
        }
    }
})();<commit_msg>Fixed bug with mouse events that causes drag end not to work correctly. Fixed bug with drag event incorrectly triggering a 0,0 measurement on mouse x,y coordinates.<commit_after>(function(){

    module.exports = MouseEvents(
        require('../events-queue/events-queue.js'),
        require('../throttle/throttle.js')
    );

    function MouseEvents(_eventsQueue, _throttle){

        /*----------------------------------------------------------------------
            PRIVATE VARIABLES
         ----------------------------------------------------------------------*/
        var _root              = {},
            _dragSubscribers   = [],
            _onDownSubscribers = [],
            _onUpSubscribers   = [],
            _isHeld            = false,
            _isMoving          = false,
            _isDragging        = false,
            _mouseMoveData     = {},
            _startEvent;

        /*----------------------------------------------------------------------
            PUBLIC METHODS
        ----------------------------------------------------------------------*/

        _root.isHeld  = isHeld;
        _root.onDrag  = subscribeToDrag;
        _root.onDown  = subscribeToDown;
        _root.onUp    = subscribeToUp;

        /*----------------------------------------------------------------------
            INIT
        ----------------------------------------------------------------------*/

        init();
        return _root;

        /*----------------------------------------------------------------------
            PRIVATE METHODS
         ----------------------------------------------------------------------*/

        function init(){
            _eventsQueue.subscribe("mousedown", window, mouseDownHandler);
            _eventsQueue.subscribe("mouseup",   window, mouseUpHandler);
            _eventsQueue.subscribe("mousemove", window, onMouseMoveHandler);
            _eventsQueue.subscribe("dragstart", window, onDragStartHandler);
            _eventsQueue.subscribe("dragend",   window, onDragEndHandler);
            _eventsQueue.subscribe("drag",      window, _throttle(onDragHandler, 50));
        }

        function subscribeToDrag(fn){
            _dragSubscribers.push(fn);
        }

        function subscribeToDown(fn){
            _onDownSubscribers.push(fn);
        }

        function subscribeToUp(fn){
            _onUpSubscribers.push(fn);
        }

        function notifyDragSubscribers(){
            for(var i = 0; i < _dragSubscribers.length; i++){
                _dragSubscribers[i](_mouseMoveData)
            }
        }

        function notifyDownSubscribers(e){
            for(var i = 0; i < _onDownSubscribers.length; i++){
                _onDownSubscribers[i](e);
            }
        }

        function notifyUpSubscribers(e){
            for(var i = 0; i < _onUpSubscribers.length; i++){
                _onUpSubscribers[i](e);
            }
        }

        function isHeld(){
            return _isHeld;
        }

        function mouseDownHandler(e){
            onDown(e);
            _isHeld    = true;
            _isMoving  = true
        }

        function onDragStartHandler(e){
            onDown(e);
            _isHeld     = true;
            _isDragging = true;
        }

        function onDown(e){
            if(!_startEvent){
                _startEvent         = e;
                notifyDownSubscribers(e);
            }
        }

        function mouseUpHandler(e){
            _isMoving = false;
            if(!_isDragging){
                onUp(e);
            }
        }

        function onDragEndHandler(e){
            _isMoving   = false;
            _isDragging = false;
            onUp(e);
        }

        function onUp(e){
            _startEvent = null;
            _isHeld     = false;
            notifyUpSubscribers(e);
        }

        function onDragHandler(e){
            onMove(e);
        }

        function onMouseMoveHandler(e){
            if(!_isDragging){
                onMove(e);
            }
        }

        function onMove(e){
            if(_isHeld){
                updateMouseMoveData(_startEvent, e);
                notifyDragSubscribers(e);
            }
        }

        function updateMouseMoveData(startData, eventData){
            if(eventData.x !== 0){
                _mouseMoveData = {
                    x:eventData.x - startData.x,
                    y:eventData.y - startData.y
                }
            }
        }
    }
})();<|endoftext|>


<commit_before>import { push } from 'react-router-redux'
import * as types from './actiontypes'
import fetch from 'isomorphic-fetch'
import 'promise'
import Config from './config'
import {store} from './persist'

export function setQuery(query) {
  return {type: types.SET_QUERY, query}
}

export function nextPage() {
  return (dispatch, getState) => {
    const offset = getState().app.get('offset')
    const nextOffset = offset+25
    dispatch(giphySearch({offset: nextOffset}))
    return {type: types.SET_OFFSET, offset: nextOffset}
  }
}

export function prevPage() {
  return (dispatch, getState) => {
    const offset = getState().app.get('offset')
    let nextOffset = offset-25
    if (nextOffset < 0) {
      nextOffset = 0
    }
    if (nextOffset !== offset) {
      dispatch(giphySearch({offset: nextOffset}))
    }
    return {type: types.SET_OFFSET, offset: nextOffset}
  }
}

function realGiphySearch(dispatch, query, offset) {
  return fetch(`http://api.giphy.com/v1/gifs/search?q=${query}&api_key=${Config.api_key}&offset=${offset}`)
    .then(response => {
      const json = response.json().then(resp2 => {
        dispatch(fetchGifsSuccess(resp2.data, query, offset))
      })
    }, response => {
      dispatch(fetchGifsFailure(response.message))
    })
}

const gif1 = {
  id: 1, images: {fixed_height_small: {url: require('../static/fake/small1.jpg')},
    original: {url: require('../static/fake/big1.jpg')}},
  };
const gif2 = {
  id: 2, images: {fixed_height_small: {url: require('../static/fake/small2.jpg')},
    original: {url: require('../static/fake/big2.jpg')}},
  };
const gif3 = {
  id: 3, images: {fixed_height_small: {url: require('../static/fake/small3.jpg')},
    original: {url: require('../static/fake/big3.jpg')}},
  };

function fakeGiphySearch(dispatch, query, offset) {
  let promise = new Promise((resolve, reject) => {
    const data = [
      Object.assign({}, gif1, {id: 10}),
      Object.assign({}, gif2, {id: 11}),
      Object.assign({}, gif3, {id: 12}),
      Object.assign({}, gif1, {id: 13}),
      Object.assign({}, gif2, {id: 14}),
      Object.assign({}, gif3, {id: 15}),
      Object.assign({}, gif2, {id: 16}),
      Object.assign({}, gif3, {id: 17}),
      Object.assign({}, gif1, {id: 18}),
      Object.assign({}, gif2, {id: 19}),
    ]
    resolve({data: data}
    )
  }).then(json => {
      dispatch(fetchGifsSuccess(json.data, query, offset))
      }
    )
  return promise
}

export function giphySearch(options) {
  options = options || {}
  return (dispatch, getState) => {
    let query = options.query
    if (query === undefined) {
      query = getState().app.get('query')
    }
    var offset
    if (options.offset !== undefined) {
      offset = options.offset
    } else {
      offset = getState().app.get('offset')
    }
    if (query === '') {
      offset = 0
      dispatch(fetchGifsSuccess([], query, offset))
    } else {
      const fake = getState().app.get('fake')
      let method
      if (fake) {
        method = fakeGiphySearch
      } else {
        method = realGiphySearch
      }
      dispatch({type: types.SET_SEARCHED_QUERY, searchedQuery: query})
      method(dispatch, query, offset)
      dispatch({type: types.FETCH_GIFS_REQUEST})
    }
    let url = '/' + query
    if (offset) {
      url += '/' + offset
    }
    dispatch(push(url))
  }
}

export function fetchGifsSuccess(results, query, offset) {
  return {type: types.FETCH_GIFS_SUCCESS, results: results, query: query, offset: offset}
}

export function fetchGifsFailure(error) {
  return {type: types.FETCH_GIFS_FAILURE, error: error}
}

export function fake(fakeStatus) {
  return dispatch => {
    store('fake', fakeStatus)
    dispatch({type: types.FAKE_CHANGE, fake: fakeStatus})
  }
}

export function showQueryBox() {
  return {type: types.SHOW_QUERY_BOX}
}

export function hideQueryBox() {
  return {type: types.HIDE_QUERY_BOX}
}

export function setImageLoadedTime(imageLoadedTime) {
  return {type: types.IMAGE_LOADED_TIME, imageLoadedTime: imageLoadedTime}
}

export function overflow() {
  return {type: types.OVERFLOW}
}

export function clearOverflow() {
  return {type: types.CLEAR_OVERFLOW}
}

export function setHoveredImageBoundingBox(bounds) {
  return {type: types.SET_HOVERED_IMAGE_BOUNDING_BOX, hoveredImageBoundingBox: bounds}
}
<commit_msg>use https<commit_after>import { push } from 'react-router-redux'
import * as types from './actiontypes'
import fetch from 'isomorphic-fetch'
import 'promise'
import Config from './config'
import {store} from './persist'

export function setQuery(query) {
  return {type: types.SET_QUERY, query}
}

export function nextPage() {
  return (dispatch, getState) => {
    const offset = getState().app.get('offset')
    const nextOffset = offset+25
    dispatch(giphySearch({offset: nextOffset}))
    return {type: types.SET_OFFSET, offset: nextOffset}
  }
}

export function prevPage() {
  return (dispatch, getState) => {
    const offset = getState().app.get('offset')
    let nextOffset = offset-25
    if (nextOffset < 0) {
      nextOffset = 0
    }
    if (nextOffset !== offset) {
      dispatch(giphySearch({offset: nextOffset}))
    }
    return {type: types.SET_OFFSET, offset: nextOffset}
  }
}

function realGiphySearch(dispatch, query, offset) {
  return fetch(`https://api.giphy.com/v1/gifs/search?q=${query}&api_key=${Config.api_key}&offset=${offset}`)
    .then(response => {
      const json = response.json().then(resp2 => {
        dispatch(fetchGifsSuccess(resp2.data, query, offset))
      })
    }, response => {
      dispatch(fetchGifsFailure(response.message))
    })
}

const gif1 = {
  id: 1, images: {fixed_height_small: {url: require('../static/fake/small1.jpg')},
    original: {url: require('../static/fake/big1.jpg')}},
  };
const gif2 = {
  id: 2, images: {fixed_height_small: {url: require('../static/fake/small2.jpg')},
    original: {url: require('../static/fake/big2.jpg')}},
  };
const gif3 = {
  id: 3, images: {fixed_height_small: {url: require('../static/fake/small3.jpg')},
    original: {url: require('../static/fake/big3.jpg')}},
  };

function fakeGiphySearch(dispatch, query, offset) {
  let promise = new Promise((resolve, reject) => {
    const data = [
      Object.assign({}, gif1, {id: 10}),
      Object.assign({}, gif2, {id: 11}),
      Object.assign({}, gif3, {id: 12}),
      Object.assign({}, gif1, {id: 13}),
      Object.assign({}, gif2, {id: 14}),
      Object.assign({}, gif3, {id: 15}),
      Object.assign({}, gif2, {id: 16}),
      Object.assign({}, gif3, {id: 17}),
      Object.assign({}, gif1, {id: 18}),
      Object.assign({}, gif2, {id: 19}),
    ]
    resolve({data: data}
    )
  }).then(json => {
      dispatch(fetchGifsSuccess(json.data, query, offset))
      }
    )
  return promise
}

export function giphySearch(options) {
  options = options || {}
  return (dispatch, getState) => {
    let query = options.query
    if (query === undefined) {
      query = getState().app.get('query')
    }
    var offset
    if (options.offset !== undefined) {
      offset = options.offset
    } else {
      offset = getState().app.get('offset')
    }
    if (query === '') {
      offset = 0
      dispatch(fetchGifsSuccess([], query, offset))
    } else {
      const fake = getState().app.get('fake')
      let method
      if (fake) {
        method = fakeGiphySearch
      } else {
        method = realGiphySearch
      }
      dispatch({type: types.SET_SEARCHED_QUERY, searchedQuery: query})
      method(dispatch, query, offset)
      dispatch({type: types.FETCH_GIFS_REQUEST})
    }
    let url = '/' + query
    if (offset) {
      url += '/' + offset
    }
    dispatch(push(url))
  }
}

export function fetchGifsSuccess(results, query, offset) {
  return {type: types.FETCH_GIFS_SUCCESS, results: results, query: query, offset: offset}
}

export function fetchGifsFailure(error) {
  return {type: types.FETCH_GIFS_FAILURE, error: error}
}

export function fake(fakeStatus) {
  return dispatch => {
    store('fake', fakeStatus)
    dispatch({type: types.FAKE_CHANGE, fake: fakeStatus})
  }
}

export function showQueryBox() {
  return {type: types.SHOW_QUERY_BOX}
}

export function hideQueryBox() {
  return {type: types.HIDE_QUERY_BOX}
}

export function setImageLoadedTime(imageLoadedTime) {
  return {type: types.IMAGE_LOADED_TIME, imageLoadedTime: imageLoadedTime}
}

export function overflow() {
  return {type: types.OVERFLOW}
}

export function clearOverflow() {
  return {type: types.CLEAR_OVERFLOW}
}

export function setHoveredImageBoundingBox(bounds) {
  return {type: types.SET_HOVERED_IMAGE_BOUNDING_BOX, hoveredImageBoundingBox: bounds}
}
<|endoftext|>