{"size": 3844, "ext": "js", "max_stars_repo_path": "client/lib/Direction.js", "max_stars_repo_name": "mattcam3r0n/precision", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "client/lib/Direction.js", "max_issues_repo_name": "mattcam3r0n/precision", "max_issues_repo_issues_event_min_datetime": "2019-06-24T00:16:50.000Z", "max_issues_repo_issues_event_max_datetime": "2022-01-15T01:13:19.000Z", "max_forks_repo_path": "client/lib/Direction.js", "max_forks_repo_name": "mattcam3r0n/precision", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": 2, "max_forks_count": null, "avg_line_length": 21.2375690608, "max_line_length": 63, "alphanum_fraction": 0.4700832466}
const directionNames = {
    '-1': 'CM',
    '-2': 'LCM',
    '-3': 'RCM',
    '0': 'N',
    '90': 'E',
    '180': 'S',
    '270': 'W',
    '45': 'NE',
    '135': 'SE',
    '225': 'SW',
    '315': 'NW',
};
class Direction {
    // a special case for countermarch
    static get CM() {
        return -1;
    }

    static get LCM() {
        return -2;
    }

    static get RCM() {
        return -3;
    }

    static get N() {
        return 0;
    }

    static get E() {
        return 90;
    }

    static get S() {
        return 180;
    }

    static get W() {
        return 270;
    }

    static get NE() {
        return 45;
    }

    static get SE() {
        return 135;
    }

    static get SW() {
        return 225;
    }

    static get NW() {
        return 315;
    }

    static getSlope(dir) {
        return slope[dir];
    }

    static getLineSlope(from, to) {
        return (from.y - to.y) / (from.x - to.x);
    }

    static getLineDirection(from, to) {
        let slope = this.getLineSlope(from, to);

        if (slope === -Infinity) {
            return Direction.N;
        }
        if (Object.is(slope, -0)) {
            return Direction.E;
        }
        if (slope === Infinity) {
            return Direction.S;
        }
        if (Object.is(slope, +0)) {
            return Direction.W;
        }
        if (slope === 1 && from.x <= to.x && from.y <= to.y) {
            return Direction.NE;
        }
        if (slope === 1 && from.x >= to.x && from.y >= to.y) {
            return Direction.SW;
        }
        if (slope === -1 && from.x >= to.x && from.y <= to.y) {
            return Direction.NW;
        }
        if (slope === -1 && from.x <= to.x && from.y >= to.y) {
            return Direction.SE;
        }
    }

    static isLineDirection(from, to, dir) {
        return this.getLineDirection(from, to) === dir;
    }

    // is p1 behind p2, with respect to dir
    // not necessarily following directly, but behind on
    // appropriate axis for the direction
    static isBehind(p1, p2, dir) {
        // get x/y delta
        const delta = {
            deltaX: p1.x - p2.x,
            deltaY: p1.y - p2.y,
        };
        if (dir == Direction.N && delta.deltaY > 0) {
            return true;
        }
        if (dir == Direction.S && delta.deltaY < 0) {
            return true;
        }
        if (dir == Direction.E && delta.deltaX < 0) {
            return true;
        }
        if (dir == Direction.W && delta.deltaX > 0) {
            return true;
        }
        return false;
    }

    static leftOf(from) {
        let newDir = from - 90;
        return newDir < 0 ? 360 + newDir : newDir;
    }

    static rightOf(from) {
        let newDir = (from + 90);
        return newDir >= 360 ? newDir - 360 : newDir;
    }

    static aboutFaceFrom(fromDir) {
        return this.rotate180(fromDir);
    }

    static rotate180(fromDir) {
        let newDir = (fromDir + 180);
        return newDir >= 360 ? newDir - 360 : newDir;
    }

    static normalizeDirection(dir) {
        if (dir >= 0 && dir < 360) return dir;

        return dir - (Math.floor(dir / 360) * 360);
    }

    static getDirection(dir) {
        return this[dir] == undefined ? dir : this[dir];
    }

    static getDirectionName(dir) {
        dir = this.getDirection(dir);
        return directionNames[dir];
    }

    static isOblique(dir) {
        dir = this.getDirection(dir);
        return dir == Direction.NW ||
            dir == Direction.NE ||
            dir == Direction.SE ||
            dir == Direction.SW;
    }
}

const slope = {
    [Direction.N]: -Infinity,
    [Direction.E]: -0,
    [Direction.S]: Infinity,
    [Direction.W]: +0,
    [Direction.NE]: -1,
    [Direction.SW]: -1,
    [Direction.SE]: 1,
    [Direction.NW]: 1,
};


export default Direction;
