/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });

// CONCATENATED MODULE: ./src/cgt/utils/canvas2d.js
const defaultOptions = {
    autoresize: true
    // aspectratio: false
};

const canvas2d = (canvas, options) => {
    const opts = Object.assign({}, defaultOptions, options);
    const ctx = canvas.getContext('2d');

    const resize = () => {
        const rect = canvas.getBoundingClientRect();

        canvas.width = rect.width;
        canvas.height = rect.height;
    };

    if (opts.autoresize) {
        resize();
        window.addEventListener('resize', () => resize());
    }

    return ctx;
};

/* harmony default export */ var utils_canvas2d = (canvas2d);
// CONCATENATED MODULE: ./src/cgt/utils/looper.js
const looper = cb => {
    let lastTime = Date.now();

    const fn = time => {
        cb(time - lastTime);
        lastTime = time;
        requestAnimationFrame(fn);
    };

    fn(lastTime);
};

/* harmony default export */ var utils_looper = (looper);
// CONCATENATED MODULE: ./src/scenes/state.js
class State {

    constructor(data) {
        this.events = {};
        this.init(data);
    }

    init() {}
    update() {}
    draw() {}

    on(event, cb) {
        if (!this.events[event]) this.events[event] = [];
        this.events[event].push(cb);
    }

    emit(event, data) {
        if (this.events[event]) {
            this.events[event].forEach(ev => ev(data));
        }
    }
}
// CONCATENATED MODULE: ./src/scenes/scene.js


class scene_Scene {
    constructor(cb) {
        this.cb = cb;

        this.state = new State();

        this.init();
    }

    init() {}

    setScene(scene) {
        this.cb('set-scene', scene);
    }

    draw(ctx) {
        this.state.draw(ctx);
    }

    update(dt) {
        this.state.update(dt);
    }

    setState(state) {
        this.state = state;
        return state;
    }
}
// CONCATENATED MODULE: ./src/config/enemies.js
const enemies = [{}];

/* harmony default export */ var config_enemies = (enemies);
// CONCATENATED MODULE: ./src/config/map.js
class Level {
    constructor(data) {
        this.data = data;
    }

    get(x, y) {
        const isUndefined = this.data.cells === undefined || this.data.cells[y] === undefined || this.data.cells[y][x] === undefined;
        return isUndefined ? null : this.data.cells[y][x];
    }

    action(x, y) {
        const result = this.data.actions.find(item => item.x === x && item.y === y);
        return result ? result.value : {};
    }

    initialPosition() {
        return this.data.initialPosition;
    }

    cells() {
        return this.data.cells;
    }

    update(x, y, val) {
        this.data.cells[y][x] = val;
    }
}

const data = {
    'level1': new Level({
        initialPosition: {
            x: 10,
            y: 20
        },
        cells: [[15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 14, -1, -1, -1, 15, 12, 12, 12, 12, 14], [10, 0, 0, 40, 0, 0, 2, 41, 0, 0, 0, 0, 0, 0, 10, -1, -1, -1, 10, 0, 0, 0, 0, 10], [41, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 19, 0, 0, 10, -1, -1, -1, 10, 0, 15, 14, 0, 10], [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 11, 12, 12, 12, 13, 0, 10, 10, 0, 10], [10, 32, 0, 0, 0, 31, 32, 0, 0, 0, 31, 18, 0, 0, 41, 0, 0, 0, 0, 0, 10, 10, 0, 10], [10, 32, 0, 0, 0, 31, 32, 0, 0, 0, 31, 18, 0, 0, 15, 12, 12, 12, 12, 12, 13, 10, 44, 10], [10, 32, 0, 0, 0, 31, 32, 0, 0, 0, 31, 18, 0, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1], [10, 32, 0, 0, 0, 31, 32, 0, 0, 0, 31, 18, 0, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1], [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1], [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 43, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1], [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1], [11, 12, 14, 17, 17, 0, 0, 0, 17, 17, 15, 12, 12, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, 10, 0, 0, 0, 0, 0, 0, 31, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, 10, 0, 0, 0, 0, 0, 0, 31, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, 10, 34, 34, 34, 0, 0, 0, 31, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, 11, 12, 12, 14, 0, 0, 15, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, 39, 39, 39, 39, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, 39, 0, 0, 0, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, 39, 0, 0, 0, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, 39, 37, 0, 37, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, 39, 0, 0, 0, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 0, 0, 0, 0, 0, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, 39, 0, 0, 0, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, 39, 38, 38, 38, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, 39, 0, 0, 0, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 10, 0, 0, 10, 39, 0, 0, 0, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, 11, 12, 12, 13, 39, 39, 39, 39, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
        width: 24,
        height: 29,
        actions: [{ x: 22, y: 5, value: 'level2' }, { x: 6, y: 1, value: { x: 7, y: 1, value: 42 } }, { x: 13, y: 9, value: { x: 14, y: 4, value: 42 } }]
    }),

    'level2': new Level({
        cells: [[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 12, 12, 12, 12, 12, 12, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 0, 0, 0, 41, 2, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 17, 0, 0, 12, 14, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 0, 0, 0, 0, 10, 0, 10, -1, 15, 12, 12, 12, 12, 12, 12, 12, 14], [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 0, 0, 0, 0, 10, 0, 10, -1, 10, 0, 0, 0, 1, 1, 1, 0, 10], [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 0, 0, 0, 0, 10, 0, 11, 12, 13, 0, 15, 12, 16, 12, 45, 12, 20], [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 17, 0, 0, 0, 10, 0, 0, 41, 2, 0, 10, 33, 18, 0, 2, 0, 10], [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 0, 0, 0, 35, 10, 0, 15, 12, 12, 12, 20, 3, 18, 0, 0, 0, 10], [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 0, 0, 0, 35, 10, 0, 10, -1, -1, -1, 10, 0, 18, 0, 0, 0, 10], [-1, 10, 29, 29, 29, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 0, 0, 0, 35, 10, 0, 10, -1, -1, -1, 10, 0, 18, 0, 0, 0, 10], [-1, 10, 1, 1, 1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 17, 0, 0, 0, 21, 12, 13, -1, -1, -1, 10, 0, 0, 0, 0, 0, 10], [-1, 10, 1, 1, 1, 1, 15, 12, 12, 12, 12, 14, -1, -1, -1, 18, 0, 0, 0, 0, 10, -1, -1, -1, -1, -1, 10, 0, 0, 0, 0, 0, 10], [-1, 10, 0, 0, 1, 1, 10, 3, 0, 0, 0, 10, -1, -1, -1, 18, 0, 0, 0, 0, 10, -1, -1, -1, -1, -1, 11, 12, 12, 12, 44, 12, 13], [-1, 10, 0, 0, 15, 12, 20, 1, 0, 0, 0, 10, -1, -1, -1, 18, 0, 2, 0, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, 0, 41, 2, 0, 0, 0, 15, 12, 12, 12, 22, 12, 45, 12, 12, 22, 12, 12, 12, 14, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, 0, 10, 1, 0, 0, 0, 10, 2, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 10, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, 0, 10, 0, 0, 0, 0, 21, 45, 16, 12, 12, 12, 12, 12, 12, 12, 12, 14, 1, 10, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, 0, 10, 0, 0, 0, 0, 10, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, 10, 29, 10, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, 0, 10, 0, 0, 0, 0, 10, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, 0, 10, 0, 0, 0, 0, 10, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [12, 13, 0, 0, 15, 12, 20, 0, 0, 0, 0, 41, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [29, 1, 0, 0, 10, -1, 10, 0, 0, 0, 0, 21, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [12, 14, 0, 0, 10, -1, 10, 1, 1, 1, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, -1, 10, 1, 1, 1, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, -1, 11, 12, 12, 12, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 0, 0, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 1, 1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 1, 1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 10, 29, 29, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
        initialPosition: {
            x: 30,
            y: 12
        },
        actions: [{ x: 27, y: 7, value: 'плазменный резак' }, { x: 30, y: 6, value: { x: 30, y: 5, value: 46 } }, { x: 24, y: 6, value: { x: 23, y: 6, value: 42 } }, { x: 21, y: 1, value: 'аптечка' }, { x: 20, y: 1, value: { x: 19, y: 1, value: 42 } }, { x: 17, y: 13, value: { x: 17, y: 14, value: 46 } }, { x: 12, y: 15, value: { x: 12, y: 16, value: 46 } }, { x: 12, y: 21, value: { x: 11, y: 21, value: 42 } }, { x: 7, y: 14, value: { x: 6, y: 14, value: 42 } }, { x: 7, y: 12, value: 'стазис модуль' }]
    })
};

/* harmony default export */ var map = (data);
// CONCATENATED MODULE: ./src/config/index.js
let resources = {
    startImg: 'img/start1.png',
    all: [{
        type: 'image',
        name: 'font',
        path: 'img/fnt.png'
    }, {
        type: 'image',
        name: 'mapitems',
        path: 'img/mapitems.png'
    }, {
        type: 'image',
        name: 'person',
        path: 'img/person.png'
    }, {
        type: 'image',
        name: 'battle',
        path: 'img/battle.png'
    }]
};

let keybindings = {
    keyboard: {
        'LEFT': 'KeyA',
        'DOWN': 'KeyS',
        'RIGHT': 'KeyD',
        'UP': 'KeyW',
        'A': 'Enter',
        'B': 'Backspace',
        'START': 'Space',
        'SELECT': 'Escape'
    }
};

let player = {
    level: 'level1',
    dir: 4,
    lastItem: '',
    position: {
        x: 11,
        y: 21
    },
    health: 100,
    items: []
};





class config_Config {
    resources() {
        return resources;
    }

    keybindings() {
        return keybindings;
    }

    player() {
        return player;
    }

    enemies() {
        return config_enemies;
    }

    map(level) {
        return level ? map[level] : map[player.level];
    }

    startGame() {
        this.loadLevel('level1');
        player.health = 100;
        player.items = [];
    }

    loadLevel(level) {
        player.level = level;
        const initialPosition = this.map().initialPosition();
        player.position = {
            x: initialPosition.x,
            y: initialPosition.y
        };
    }
}

/* harmony default export */ var config = (new config_Config());
// CONCATENATED MODULE: ./src/cgt/resources/atlas.js
/* global Image */

const newResourceItem = (resources, name, data) => {
    return new Promise((resolve, reject) => {
        const newImage = new Image();
        newImage.onload = () => {
            resources[name] = {
                type: 'image',
                data: newImage
            };
            resolve(resources[name]);
        };
        newImage.onerror = reject;

        newImage.src = data;
    });
};

const cutImage = (img, { x, y, w, h }) => {
    const canvas = document.createElement('canvas');
    let ctx = canvas.getContext('2d');

    canvas.width = w;
    canvas.height = h;
    ctx.clearRect(0, 0, w, h);
    ctx.drawImage(img, x, y, w, h, 0, 0, w, h);

    const data = canvas.toDataURL('image/png');

    ctx = null;
    canvas.remove();

    return data;
};

const loadAtlas = (path, data, resources) => {
    return new Promise((resolve, reject) => {
        const img = new Image();

        img.onload = () => {
            const promises = data.map(item => {
                const imgcut = cutImage(img, item);
                return newResourceItem(resources, item.name, imgcut);
            });

            const result = Promise.all(promises);
            resolve(result);
        };

        img.onerror = reject;

        img.src = path;
    });
};

/* harmony default export */ var atlas = (loadAtlas);
// CONCATENATED MODULE: ./src/cgt/resources/image.js
const loadImage = (name, path, resources) => {
    return new Promise((resolve, reject) => {
        const img = new Image();

        img.onload = () => {
            resources[name] = {
                type: 'image',
                data: img
            };

            resolve(img);
        };

        img.onerror = reject;

        img.src = path;
    });
};

/* harmony default export */ var resources_image = (loadImage);
// CONCATENATED MODULE: ./src/cgt/resources/index.js



let resources_resources = {};

const loadAll = arr => {
    const promises = arr.map(item => {
        if (item.type === 'image') return resources_image(item.name, item.path, resources_resources);
        if (item.type === 'atlas') return atlas(item.path, item.items, resources_resources);
    });
    return Promise.all(promises);
};

const load = {
    image: (name, path) => resources_image(name, path, resources_resources),
    atlas: (path, items) => atlas(path, items, resources_resources),
    all: loadAll
};

const get = name => {
    return resources_resources[name].data;
};

/* harmony default export */ var cgt_resources = ({
    load,
    get
});
// CONCATENATED MODULE: ./src/cgt/font/imgfont.js
const alphabet = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхц' + 'чшщъыьэюяABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + '0123456789()!?.,:;" ';

class ImgFont {

    constructor(img, letterWidth, lineHeight) {
        this.img = img;
        this.letterWidth = letterWidth;
        this.lineHeight = lineHeight;
    }

    draw(ctx, text, x, y) {
        const letters = text.split('');

        const img = this.img;
        const cy = y + this.lineHeight;
        const sy = 2; // ?
        const w = this.letterWidth;
        const h = this.lineHeight;

        letters.forEach((letter, i) => {
            const cx = x + i * this.letterWidth;
            const sx = alphabet.indexOf(letter) * this.letterWidth;
            ctx.drawImage(img, sx, sy, w, h, cx, cy, w, h);
        });
    }

    drawPage(ctx, text, x, y, page = 0, pageSize = 308, lineWidth = 22) {
        const letters = text.split('').slice(page * pageSize, (page + 1) * pageSize);

        const img = this.img;
        const sy = 2; // ?
        const w = this.letterWidth;
        const h = this.lineHeight;

        letters.forEach((letter, i) => {
            const cx = x + i * this.letterWidth % lineWidth;
            const cy = (~~(i / lineWidth) + 1) * this.lineHeight + y;
            const sx = alphabet.indexOf(letter) * this.letterWidth;
            ctx.drawImage(img, sx, sy, w, h, cx, cy, w, h);
        });
    }
}

/*
const letterWidth = 7
const lineHeight = 9
const color = '#a4d695'

const letters = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюяABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()!?.,:;"'.split('')

const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')

canvas.width = letterWidth * letters.length
canvas.height = lineHeight
  
setTimeout(() => {
  ctx.font = '9px monaco'
  ctx.fillStyle = color
 
	letters.forEach((letter, i) => {
  	const x = i * letterWidth
     ctx.fillText(letter, x, lineHeight)
  })
}, 500)
*/
// CONCATENATED MODULE: ./src/scenes/font.js


let font = null;

/* harmony default export */ var scenes_font = ({
    get: () => font,
    init: (img, w, h) => font = new ImgFont(img, w, h)
});
// CONCATENATED MODULE: ./src/scenes/start/state-loading.js


class LoadingState extends State {
    init(img) {
        this.img = img;
    }

    draw(ctx) {
        ctx.drawImage(this.img, 0, 0);
    }
}

/* harmony default export */ var state_loading = (LoadingState);
// CONCATENATED MODULE: ./src/cgt/inputs/keyboard.js
let _keys = {};
let _map = null;

window.addEventListener('keydown', evt => {
    _keys[evt.code] = true;
});

window.addEventListener('keyup', evt => {
    _keys[evt.code] = false;
});

/* harmony default export */ var keyboard = ({
    get: key => _map ? _keys[_map[key]] : _keys[key],
    map: data => _map = data,
    all: () => _map ? Object.keys(_map).filter(key => _keys[_map[key]]) : Object.keys(_keys).filter(key => _keys[key])
});
// CONCATENATED MODULE: ./src/cgt/utils/tact.js
const create_tact = interval => {
    let start = Date.now();

    return () => {
        const diff = Date.now() - start;
        if (diff > interval) {
            start += ~~(diff / interval) * interval;
            return true;
        }

        return false;
    };
};

/* harmony default export */ var tact = (create_tact);

/*
const everySecond = create_tact(1000)

let i = 0
while (i < 10) {
    if (everySecond()) {
        console.log(i++)
    }
}

*/
// CONCATENATED MODULE: ./src/scenes/start/state-ready.js






class state_ready_ReadyState extends State {
    init(img) {
        this.img = img;
        this.showText = false;

        this.font = scenes_font.get();

        this.tact = tact(500);

        keyboard.map(config.keybindings().keyboard);
    }

    draw(ctx) {
        ctx.drawImage(this.img, 0, 0);
        if (this.showText) {
            this.font.draw(ctx, 'Press START', 80, 70);
        }
    }

    update() {
        if (this.tact()) {
            this.showText = !this.showText;
        }

        if (keyboard.get('START')) {
            this.emit('start');
        }
    }
}
// CONCATENATED MODULE: ./src/scenes/start/index.js










class start_StartScene extends scene_Scene {
    init() {
        let bgImg;
        cgt_resources.load.image('start', config.resources().startImg).then(img => {
            bgImg = img;
            this.setState(new state_loading(bgImg));
            return cgt_resources.load.all(config.resources().all);
        }).then(() => {
            scenes_font.init(cgt_resources.get('font'), 7, 10);
            this.setState(new state_ready_ReadyState(bgImg)).on('start', () => this.startGame());
        }).catch(() => {
            throw 'Error during loading';
        });
    }

    startGame() {
        config.startGame();
        this.setScene('map');
    }
}
// CONCATENATED MODULE: ./src/scenes/map/screen.js



let maptiles = null;
let person = null;
const init = () => {
    maptiles = cgt_resources.get('mapitems');
    person = cgt_resources.get('person');
};

const mapScreenCellsX = 20;
const mapScreenCellsY = 18;

const mapCellSizeX = 8;
const mapCellSizeY = 8;

const getCell = (x, y) => {
    const n = config.map().get(x, y);
    return n === null ? null : {
        x: n % 10 * mapCellSizeX,
        y: ~~(n / 10) * mapCellSizeY,
        w: mapCellSizeX,
        h: mapCellSizeY
    };
};

let pOffset = { x: 0, y: 0 };
const setPlayerOffset = offset => {
    pOffset = offset;
};

const drawSprite = ctx => {
    ctx.drawImage(person, (config.player().dir - 1) * 8, 0, 8, 8, 10 * 8, 9 * 8, 8, 8);
};

const render = ctx => {
    for (let y = -1; y < mapScreenCellsY + 2; y++) {
        for (let x = -1; x < mapScreenCellsX + 2; x++) {
            const cellX = x + config.player().position.x - 10;
            const cellY = y + config.player().position.y - 9;
            const cell = getCell(cellX, cellY);
            if (cell != null) {
                ctx.drawImage(maptiles, cell.x, cell.y, cell.w, cell.h, x * mapCellSizeX - pOffset.x, y * mapCellSizeY - pOffset.y, mapCellSizeX, mapCellSizeY);
            }
        }
    }

    drawSprite(ctx);
};

/* harmony default export */ var screen = ({
    init,
    render,
    setPlayerOffset
});
// CONCATENATED MODULE: ./src/scenes/map/actions.js


const getAction = (x, y) => {
    const cell = config.map().get(x, y);
    const toggler = config.map().action(x, y);

    if (cell === 1) {
        const v = Math.random() > .8;
        if (v) {
            const enemyId = Math.floor(Math.random() * config.enemies().length);
            const enemy = config.enemies()[enemyId];
            const health = 100;
            config.player().battle = {
                enemy,
                health
            };
            return 'battle';
        }
    }
    // if (cell === 40) return 'save' // TODO: ??????
    if (cell === 44) {
        config.loadLevel(toggler);
        return 'lift';
    }
    if (cell === 3) {
        config.player().items.push(toggler);
        config.map().update(x, y, 0);
        config.player().lastItem = toggler;
        return 'item';
    }
    // if (cell === 46) return 'shop' // TODO: ??????

    if (cell === 2) {
        config.map().update(toggler.x, toggler.y, toggler.value);
        return 'door';
    }

    return null;
};

const cellsToMove = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 42, 44, 46];
const canMoveTo = (x, y) => {
    const cell = config.map().get(x, y);
    return cellsToMove.indexOf(cell) >= 0;
};

/* harmony default export */ var actions = ({
    getAction,
    canMoveTo
});
// CONCATENATED MODULE: ./src/scenes/map/state-standing.js




class state_standing_StandingState extends State {
    draw(ctx) {
        screen.render(ctx);
    }

    update() {
        const buttons = keyboard.all();
        if (buttons.length) {
            this.emit('action', buttons[0]);
        }
    }
}
// CONCATENATED MODULE: ./src/scenes/map/state-moving.js





const movingTime = 200;

class state_moving_MovingState extends State {
    init() {
        this.dir = 0;
    }

    setDirection(dir) {
        this.dir = dir;
        this.offset = { x: 0, y: 0 };

        if (this.dir === 4) this.dtMove = { x: 0, y: -1 };else if (this.dir === 2) this.dtMove = { x: 1, y: 0 };else if (this.dir === 1) this.dtMove = { x: 0, y: 1 };else if (this.dir === 3) this.dtMove = { x: -1, y: 0 };else this.dtMove = { x: 0, y: 0 };

        this.startTime = Date.now();
    }

    newPlayerPos(dt) {
        const k = 8 * dt / movingTime;
        this.offset.x = this.dtMove.x * k;
        this.offset.y = this.dtMove.y * k;
    }

    draw(ctx) {
        screen.setPlayerOffset(this.offset);
        screen.render(ctx);
    }

    update() {
        const dt = Date.now() - this.startTime;

        if (dt >= movingTime) {
            this.newPlayerPos(movingTime);
            this.dir = 0;
            config.player().position.x += this.dtMove.x;
            config.player().position.y += this.dtMove.y;
            this.offset = { x: 0, y: 0 };
            screen.setPlayerOffset(this.offset);
            this.emit('endmoving');
        } else {
            this.newPlayerPos(dt);
        }
    }
}

/* harmony default export */ var state_moving = (state_moving_MovingState);
// CONCATENATED MODULE: ./src/scenes/map/state-save.js





class state_save_SaveState extends State {
    init() {}

    draw(ctx) {
        screen.render(ctx);
    }

    update() {
        this.emit('done');
    }
}

/* harmony default export */ var state_save = (state_save_SaveState);
// CONCATENATED MODULE: ./src/scenes/map/state-pickup.js







class state_pickup_PickupState extends State {
    init() {
        this.font = scenes_font.get();
    }

    draw(ctx) {
        screen.render(ctx);

        ctx.fillStyle = '#61b946';
        ctx.fillRect(10, 60, 140, 44);

        ctx.fillStyle = '#376928';
        ctx.fillRect(12, 62, 136, 40);

        this.font.draw(ctx, 'Вы подобрали', 15, 55);
        this.font.draw(ctx, config.player().lastItem, 15, 65);
        this.font.draw(ctx, 'A: закрыть', 70, 80);
    }

    update() {
        if (keyboard.get('A')) {
            this.emit('done');
        }
    }
}

/* harmony default export */ var state_pickup = (state_pickup_PickupState);
// CONCATENATED MODULE: ./src/scenes/map/index.js
// https://www.google.ru/search?q=gameboy+pokemon+red&safe=off&tbm=isch&tbs=rimg:CXTmNgcAHy4DIjiEm9CsqxNDeXroGI4LSXUf6gXW_1Wi609Gyj7WLRa_1BgSSkzcnAUgiaRJPD5ovfKkWnuckoGKVWGyoSCYSb0KyrE0N5EQIx-f9JJJqkKhIJeugYjgtJdR8RA4Ud3kuZjn4qEgnqBdb9aLrT0RFmO4KQjqfs4CoSCbKPtYtFr8GBEYgHDY6lZ-oCKhIJJKTNycBSCJoR7_12MaOUPpZYqEglEk8Pmi98qRRFo_1ph9m42VIyoSCae5ySgYpVYbEarPJZemfip6&tbo=u&sa=X&ved=0ahUKEwjvws3uxMnVAhUmGZoKHTOgCh8Q9C8IHw&biw=1586&bih=892&dpr=1#imgrc=nr-GzjyOoi-H0M:
// http://orig03.deviantart.net/1d20/f/2011/024/a/a/dead_space_sprite___isaac_by_digitaleva-d37zk8j.png
// https://www.pond5.com/sound-effects/1/dead-space.html#1

/*
dead
https://www.google.ru/imgres?imgurl=http%3A%2F%2Fwww.gameland.ru%2Fpost%2F49257%2Fimg%2Fdead_space_2_05.jpg&imgrefurl=http%3A%2F%2Fwww.gameland.ru%2Fxbox360%2Fdead-space-2%2Fpreviews%2F49257%2F&docid=u8Ka6HLfTq0cWM&tbnid=lX74cTwxnxfPKM%3A&vet=10ahUKEwjFnOOl38zVAhXLvBoKHX2jCR8QMwhFKBUwFQ..i&w=1280&h=720&safe=off&bih=870&biw=1703&q=dead%20space%20%D1%81%D0%BC%D0%B5%D1%80%D1%82%D1%8C&ved=0ahUKEwjFnOOl38zVAhXLvBoKHX2jCR8QMwhFKBUwFQ&iact=mrc&uact=8
https://www.google.ru/imgres?imgurl=http%3A%2F%2Fstatic.diary.ru%2Fuserdir%2F2%2F5%2F1%2F6%2F2516458%2F77684686.jpg&imgrefurl=http%3A%2F%2Fdiary.ru%2F~grell777%2F%3Ffrom%3D80&docid=IGGMYPc7nhrEIM&tbnid=Qd2YOgRazNAQbM%3A&vet=10ahUKEwjFnOOl38zVAhXLvBoKHX2jCR8QMwhfKC8wLw..i&w=640&h=360&safe=off&bih=870&biw=1703&q=dead%20space%20%D1%81%D0%BC%D0%B5%D1%80%D1%82%D1%8C&ved=0ahUKEwjFnOOl38zVAhXLvBoKHX2jCR8QMwhfKC8wLw&iact=mrc&uact=8


https://youtu.be/Rmtshr1IglI?list=PLC2B435402E18BEC5&t=92
http://www.newgrounds.com/audio/listen/353073

40	save
41	closed door
42	opened door
43	trigger
44	лифт
45	item
46	shop
*/












class map_StartScene extends scene_Scene {
    init() {
        screen.init();

        this.standing = new state_standing_StandingState();
        this.standing.on('action', act => this.action(act));

        this.moving = new state_moving();
        this.moving.on('endmoving', () => this.endmoving());

        this.save = new state_save();
        this.save.on('done', () => this.setState(this.standing));

        this.pickup = new state_pickup();
        this.pickup.on('done', () => this.setState(this.standing));

        this.setState(this.standing);
    }

    action(act) {
        const directions = {
            'DOWN': 1,
            'RIGHT': 2,
            'LEFT': 3,
            'UP': 4
        };

        const dir = directions[act];
        if (dir) {
            let x = config.player().position.x;
            let y = config.player().position.y;
            config.player().dir = dir;
            if (dir === 4) y -= 1;else if (dir === 2) x += 1;else if (dir === 1) y += 1;else if (dir === 3) x -= 1;

            if (actions.canMoveTo(x, y)) {
                this.moving.setDirection(dir);
                this.setState(this.moving);
            }
        }
    }

    endmoving() {
        const x = config.player().position.x;
        const y = config.player().position.y;
        const action = actions.getAction(x, y);
        switch (action) {
            // case 'save':
            //    this.setState(this.save)
            case 'battle':
                this.setScene('battle');
                break;
            case 'item':
                this.setState(this.pickup);
                break;
            case 'lift':
                this.setScene('map');
                break;
            default:
                this.setState(this.standing);
        }
    }
}
// CONCATENATED MODULE: ./src/scenes/battle/timeline.js
class Timeline {
    constructor() {
        this.actions = [];
        this.time = 0;
    }

    add(unit, action, delay) {
        this.actions.push({
            unit,
            action,
            time: this.time + delay
        });

        this.actions.sort((a, b) => +(a.time > b.time) || +(a.time === b.time) - 1);
    }

    next() {
        const action = this.actions.shift();
        const timeDif = action.time - this.time;
        this.time += timeDif;
        return action;
    }

    unitNextAction(unit) {
        return this.actions.find(item => item.unit === unit);
    }
}
// CONCATENATED MODULE: ./src/scenes/battle/screen.js
/*
http://squarefaction.ru/files/game/680/gallery/13b2c9fb8129cf2916bd1145d17e4fff.jpg
*/





let screen_font;
const screen_init = () => {
    screen_font = scenes_font.get();
};

let texts = [];
const setText = _texts => {
    texts = _texts;
};

let marker = -1;
const setMarker = _marker => {
    marker = _marker;
};

const screen_render = ctx => {
    ctx.drawImage(cgt_resources.get('battle'), 0, 0);

    ctx.fillStyle = '#61b946';
    ctx.fillRect(5, 5, 94, 28);

    ctx.fillStyle = '#376928';
    ctx.fillRect(7, 7, 90, 24);

    screen_font.draw(ctx, 'Некроморф', 10, 0);
    screen_font.draw(ctx, 'Здоровье ' + config.player().battle.health, 10, 10);

    ctx.fillStyle = '#61b946';
    ctx.fillRect(60, 80, 94, 28);

    ctx.fillStyle = '#376928';
    ctx.fillRect(62, 82, 90, 24);

    screen_font.draw(ctx, 'Айзек', 65, 75);
    screen_font.draw(ctx, 'Здоровье ' + config.player().health, 65, 85);

    ctx.fillStyle = '#61b946';
    ctx.fillRect(0, 110, 160, 34);

    ctx.fillStyle = '#376928';
    ctx.fillRect(2, 112, 156, 30);

    texts.forEach((text, i) => {
        screen_font.draw(ctx, text, 15, 105 + i * 9);
    });

    if (texts[marker]) {
        ctx.fillStyle = '#c1e3b6';
        ctx.fillRect(6, 117 + marker * 9, 4, 4);
    }
};

/* harmony default export */ var battle_screen = ({
    render: screen_render,
    init: screen_init,
    setText,
    setMarker
});
// CONCATENATED MODULE: ./src/scenes/battle/state-user.js





const userHas = item => {
    return config.player().items.indexOf(item) >= 0;
};

let CheckKey = null;

class state_user_UserState extends State {
    init() {}

    draw(ctx) {
        battle_screen.render(ctx);
    }

    update() {
        if (CheckKey) {
            if (keyboard.get(CheckKey)) {
                return;
            }
            CheckKey = null;
        }
        // this.emit('done')

        if (keyboard.get('DOWN')) {
            CheckKey = 'DOWN';
            if (!this.items.length) {
                this.selected = -1;
            } else {
                this.selected++;
                if (!this.items[this.selected]) this.selected = 0;
            }
            return;
        }

        if (keyboard.get('UP')) {
            CheckKey = 'UP';
            if (!this.items.length) {
                this.selected = -1;
            } else {
                this.selected--;
                if (!this.items[this.selected]) this.selected = this.items.length - 1;
            }
            return;
        }

        if (keyboard.get('A')) {
            CheckKey = 'A';

            const action = this.items[this.selected];
            if (action === 'Выстрелить') {
                this.emit('done', {
                    action: 'fire',
                    delay: 5
                });
            }

            if (action === 'Иcпользовать аптечку') {
                this.emit('done', {
                    action: 'health',
                    delay: 2
                });
            }

            if (action === 'Замедлить') {
                this.emit('done', {
                    action: 'slow',
                    delay: 10
                });
            }

            if (action === 'Убежать') {
                this.emit('done', {
                    action: 'run',
                    delay: 7
                });
            }

            return;
        }

        battle_screen.setMarker(this.selected);
    }

    prepare() {
        this.items = [];

        if (userHas('плазменный резак')) this.items.push('Выстрелить');

        if (userHas('аптечка')) this.items.push('Иcпользовать аптечку');

        if (userHas('стазис модуль')) this.items.push('Замедлить');

        this.items.push('Убежать');

        battle_screen.setText(this.items);

        this.selected = this.items.length ? 0 : -1;
        battle_screen.setMarker(this.selected);
    }
}

/* harmony default export */ var state_user = (state_user_UserState);
// CONCATENATED MODULE: ./src/scenes/battle/state-enemy.js





class state_enemy_EnemyState extends State {
    init() {}

    prepare() {
        battle_screen.setText(['Враг готовится', 'нанести удар', 'A: далее']);
        battle_screen.setMarker(-1);

        this.waitKeyA = keyboard.get('A');
    }

    draw(ctx) {
        battle_screen.render(ctx);
    }

    update() {
        if (this.waitKeyA) {
            if (keyboard.get('A')) return;
            this.waitKeyA = false;
        }

        if (keyboard.get('A')) {
            this.emit('done');
        }
    }
}

/* harmony default export */ var state_enemy = (state_enemy_EnemyState);
// CONCATENATED MODULE: ./src/scenes/battle/state-start.js





class state_start_StartState extends State {
    init() {}

    draw(ctx) {
        battle_screen.render(ctx);
    }

    prepare() {
        battle_screen.setText(['Поражение']);
        battle_screen.setMarker(-1);
    }

    update() {}
}

/* harmony default export */ var state_start = (state_start_StartState);
// CONCATENATED MODULE: ./src/scenes/battle/state-action.js





class state_action_ActionState extends State {
    init() {}

    prepare(action) {
        this.waitKeyA = keyboard.get('A');

        let text = [];

        if (action === 'attack') {
            const a = ~~(Math.random() * 20 + 10);
            config.player().health = Math.max(0, config.player().health - a);
            text.push('Получен урон: ' + a);
        }

        if (action === 'fire') {
            const a = ~~(Math.random() * 40 + 20);
            config.player().battle.health = Math.max(0, config.player().battle.health - a);
            if (config.player().battle.health === 0) {
                text.push('Противник мертв');
            } else {
                text.push('Нанесен урон: ' + a);
            }
        }

        if (action === 'health') {
            config.player().health = Math.min(100, config.player().health + 50);
            text.push('Использована', 'аптечка');
        }

        if (action === 'slow') {
            text.push('Стазис модуль не заряжен');
        }

        if (action === 'run') {
            if (Math.random() > .2) {
                text.push('Побег удался');
                this.emit('run');
            } else {
                text.push('Не удалось убежать');
            }
        }

        text.push('A: далее');

        battle_screen.setText(text);
        battle_screen.setMarker(-1);
    }

    draw(ctx) {
        battle_screen.render(ctx);
    }

    update() {
        if (this.waitKeyA) {
            if (keyboard.get('A')) return;
            this.waitKeyA = false;
        }

        if (keyboard.get('A')) {
            this.emit('done');
        }
    }
}

/* harmony default export */ var state_action = (state_action_ActionState);
// CONCATENATED MODULE: ./src/scenes/battle/index.js











class battle_Battle extends scene_Scene {
    init() {
        battle_screen.init();

        this.user = new state_user();
        this.user.on('done', ({ action, delay }) => {
            this.timeline.add('player', action, delay);
            this.setNextState();
        });

        this.enemy = new state_enemy();
        this.enemy.on('done', () => {
            this.timeline.add('npc', 'attack', 10);
            this.setNextState();
        });

        this.end = new state_start();

        this.action = new state_action();
        this.action.on('done', () => {
            if (config.player().health === 0) {
                this.end.prepare();
                this.setState(this.end);
            } else if (config.player().battle.health === 0) {
                this.setScene('map');
            } else {
                this.setNextState();
            }
        });
        this.action.on('run', () => {
            this.setScene('map');
        });

        this.timeline = new Timeline();

        this.setNextState();
    }

    setNextState() {

        const playerNextAction = this.timeline.unitNextAction('player');
        if (!playerNextAction) {
            this.user.prepare();
            this.setState(this.user);
            return;
        }

        const npcNextAction = this.timeline.unitNextAction('npc');
        if (!npcNextAction) {
            this.enemy.prepare();
            this.setState(this.enemy);
            return;
        }

        const action = this.timeline.next();
        this.action.prepare(action.action);
        this.setState(this.action);
    }
}
// CONCATENATED MODULE: ./src/scenes/index.js




let currentScene;

const draw = ctx => currentScene.draw(ctx);
const update = dt => currentScene.update(dt);

const callback = (event, data) => {
    if (event === 'set-scene') {
        setScene(data);
    }
};

const getSceneByName = name => {
    if (name === 'start') return new start_StartScene(callback);
    if (name === 'map') return new map_StartScene(callback);
    if (name === 'battle') return new battle_Battle(callback);
};

const setScene = scene => {
    currentScene = getSceneByName(scene);
};

setScene('start');

/* harmony default export */ var scenes = ({
    draw,
    update
});
// CONCATENATED MODULE: ./src/main.js




if (false) {
    navigator.serviceWorker.register('./service-worker.js');
}

const main_ctx = utils_canvas2d(document.getElementById('canvas'), {
    autoresize: false
});

utils_looper(dt => {
    scenes.update(dt);

    main_ctx.fillStyle = '#000';
    main_ctx.fillRect(0, 0, 160, 144);

    scenes.draw(main_ctx);
});

/***/ })
/******/ ]);