From 233dc5f01fd4c9fe056b23827ff072c526534862 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 24 Dec 2024 18:27:52 +0100 Subject: [PATCH] flake reorg, nix integration testing --- .github/workflows/ci.yaml | 211 +- .gitignore | 1 + README.md | 2 +- composer.json | 40 +- docker.nix | 53 - flake.lock | 118 +- flake.nix | 83 +- nix/api-test.nix | 26 + nix/integration-tests.nix | 127 + nix/overlay.nix | 18 + nix/package.nix | 24 + nix/parser.nix | 24 + nix/unit-tests.nix | 53 + overlay.nix | 5 - package.nix | 20 - parser-Cargo.lock | 1624 ------------- parser.nix | 32 - test/Providers/UploadProviderTest.php | 36 +- test/data/product-analyse.json | 3192 ++++++++++++------------- test/data/product-raw.json | 1599 ++++++++++++- 20 files changed, 3565 insertions(+), 3723 deletions(-) delete mode 100644 docker.nix create mode 100644 nix/api-test.nix create mode 100644 nix/integration-tests.nix create mode 100644 nix/overlay.nix create mode 100644 nix/package.nix create mode 100644 nix/parser.nix create mode 100644 nix/unit-tests.nix delete mode 100644 overlay.nix delete mode 100644 package.nix delete mode 100644 parser-Cargo.lock delete mode 100644 parser.nix diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 64fa14d..52a25c5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,209 +1,32 @@ -on: [push, pull_request] - -name: CI +name: "CI" +on: + pull_request: + push: jobs: - php-cs-fixer: - name: PHP-CS-Fixer - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@master - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - extensions: apcu - - name: PHP-CS-Fixer - uses: OskarStark/php-cs-fixer-ga@3.25.0 - with: - args: --diff --dry-run --allow-risky yes --stop-on-violation --using-cache=no --path-mode=intersection - - phpstan: - name: PHPStan Static Analysis - runs-on: ubuntu-22.04 - - steps: - - uses: actions/checkout@v4 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - extensions: apcu - - name: Composer - run: composer install - - name: phpstan - run: | - ./vendor/bin/phpstan analyse --level 6 src - - phpunit: - runs-on: ubuntu-22.04 - name: Unit tests - - services: - db: - image: demostf/db - env: - POSTGRES_PASSWORD: test - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - ports: - - 5432:5432 - - steps: - - uses: actions/checkout@v4 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - extensions: apcu - - name: Composer - run: composer install - - name: PHPUnit Tests - env: - DB_PORT: 5432 - DB_TYPE: pgsql - DB_HOST: localhost - DB_USERNAME: postgres - DB_PASSWORD: test - DB_DATABASE: postgres - run: | - php ./vendor/bin/phpunit test - - api: - runs-on: ubuntu-22.04 - name: Integration tests - - services: - db: - image: demostf/db - env: - POSTGRES_PASSWORD: test - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - ports: - - 5432:5432 - api: - image: demostf/api - env: - BASE_HOST: localhost - DEMO_ROOT: /tmp - DEMO_HOST: localhost - DB_TYPE: pgsql - DB_HOST: db - DB_PORT: 5432 - DB_DATABASE: postgres - DB_USERNAME: postgres - DB_PASSWORD: test - APP_ROOT: https://localhost - EDIT_SECRET: edit - volumes: - - src:/app - nginx: - image: demostf/api-nginx-test - ports: - - 80:80 - - steps: - - uses: actions/checkout@v4 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - extensions: apcu - - name: Composer - run: composer install - - name: copy code - run: | - docker run -v src:/data --name helper busybox true - docker cp src helper:/data/ - docker cp vendor helper:/data/ - docker rm helper - - env: - DB_URL: postgres://postgres:test@db:5432/postgres - BASE_URL: http://nginx - EDIT_KEY: edit - uses: docker://demostf/api-test - - build-parser: - runs-on: ubuntu-latest - strategy: - matrix: - machine: - - platform: x86_64-linux - - platform: aarch64-linux - steps: - - uses: actions/checkout@v4 - - if: matrix.machine.platform != 'x86_64-linux' - uses: docker/setup-qemu-action@v3 - - uses: cachix/install-nix-action@v26 - with: - extra_nix_config: | - extra-platforms = aarch64-linux - - uses: icewind1991/attic-action@v1 - with: - name: ci - instance: https://cache.icewind.me - authToken: '${{ secrets.ATTIC_TOKEN }}' - - run: nix build --option system ${{ matrix.machine.platform }} .#demostf-parser - - build: + matrix: runs-on: ubuntu-latest - strategy: - matrix: - machine: - - platform: x86_64-linux - - platform: aarch64-linux + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - uses: actions/checkout@v4 - - if: matrix.machine.platform != 'x86_64-linux' - uses: docker/setup-qemu-action@v3 - - uses: cachix/install-nix-action@v26 - with: - extra_nix_config: | - extra-platforms = aarch64-linux - - uses: icewind1991/attic-action@v1 - with: - name: ci - instance: https://cache.icewind.me - authToken: '${{ secrets.ATTIC_TOKEN }}' - - run: nix build --option system ${{ matrix.machine.platform }} - + - uses: cachix/install-nix-action@v27 + - id: set-matrix + run: echo "matrix={\"check\":$(nix eval --json '.#checks.x86_64-linux' --apply 'builtins.attrNames')}" | tee -a $GITHUB_OUTPUT - build-docker: + checks: runs-on: ubuntu-latest - needs: [build, build-parser] + needs: [matrix] strategy: - matrix: - machine: - - platform: x86_64-linux - - platform: aarch64-linux + fail-fast: false + matrix: ${{fromJson(needs.matrix.outputs.matrix)}} + name: ${{ matrix.check }} steps: - uses: actions/checkout@v4 - - if: matrix.machine.platform != 'x86_64-linux' - uses: docker/setup-qemu-action@v3 - - uses: cachix/install-nix-action@v26 - with: - extra_nix_config: | - extra-platforms = aarch64-linux - - uses: icewind1991/attic-action@v1 - with: - name: ci - instance: https://cache.icewind.me - authToken: '${{ secrets.ATTIC_TOKEN }}' - - run: nix build --option system ${{ matrix.machine.platform }} .#demostf-api-docker - - docker: - runs-on: ubuntu-latest - needs: [build-docker, api, phpunit] - steps: - - name: Checkout code - uses: actions/checkout@v4 - uses: cachix/install-nix-action@v26 - uses: icewind1991/attic-action@v1 with: name: ci instance: https://cache.icewind.me - - run: nix run .#dockerManifest - if: github.ref == 'refs/heads/master' - env: - VERSION: "1.0.0" - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + authToken: "${{ secrets.ATTIC_TOKEN }}" + - run: nix build .#checks.x86_64-linux.${{ matrix.check }} diff --git a/.gitignore b/.gitignore index 6ae940f..ae19353 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ node_modules *.cache .direnv result +demos \ No newline at end of file diff --git a/README.md b/README.md index 022edb9..8a553cc 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ composer install ## Deploying -Deploying the api requires php7.1 or later, +Deploying the api requires php7.1 or later, the webserver needs to be configured to server all requests to `public/index.php` execept for request to `/upload` which needs to be handled by `public/upload.php`. diff --git a/composer.json b/composer.json index 0b08bfa..7e45ae2 100644 --- a/composer.json +++ b/composer.json @@ -3,32 +3,32 @@ "description": "api implementation for demos.tf", "license": "MIT", "require": { - "mikecao/flight": "^3.6", - "vlucas/phpdotenv": "^v5.4.1", - "ircmaxell/random-lib": "^v1.2.0", - "ehesp/steam-login": "^1.2", - "koraktor/steam-condenser": "dev-master#92dde9e3b462e93cc498fe795a712c61eec7051e", - "doctrine/dbal": "^3.3.6", - "ext-pdo": "*", - "ext-json": "*", - "ext-apcu": "*" + "mikecao/flight": "^3.6", + "vlucas/phpdotenv": "^v5.4.1", + "ircmaxell/random-lib": "^v1.2.0", + "ehesp/steam-login": "^1.2", + "koraktor/steam-condenser": "dev-master#92dde9e3b462e93cc498fe795a712c61eec7051e", + "doctrine/dbal": "^3.3.6", + "ext-pdo": "*", + "ext-json": "*", + "ext-apcu": "*" }, "repositories": [ - { - "type": "vcs", - "url": "https://github.com/koraktor/steam-condenser-php" - } + { + "type": "vcs", + "url": "https://github.com/koraktor/steam-condenser-php" + } ], "autoload": { - "psr-4": { - "Demostf\\API\\": "src/", - "Demostf\\API\\Test\\": "test/" - } + "psr-4": { + "Demostf\\API\\": "src/", + "Demostf\\API\\Test\\": "test/" + } }, "require-dev": { - "phpunit/phpunit": "^9.5.20", - "friendsofphp/php-cs-fixer": "^v3.3.0", - "phpstan/phpstan": "^1.6.8" + "phpunit/phpunit": "^9.5.20", + "friendsofphp/php-cs-fixer": "^v3.3.0", + "phpstan/phpstan": "^1.6.8" }, "config": { "allow-plugins": { diff --git a/docker.nix b/docker.nix deleted file mode 100644 index d7a06e6..0000000 --- a/docker.nix +++ /dev/null @@ -1,53 +0,0 @@ -{ - demostf-api, - demostf-parser, - php, - runtimeShell, - writeScriptBin, - fakeNss, - coreutils, - bash, - dockerTools -}: let - phpWithExtensions = php.buildEnv { - extensions = ({ enabled, all }: enabled ++ (with all; [pdo apcu])); - extraConfig = '' - post_max_size = 150M - upload_max_filesize = 150M - ''; - }; -in dockerTools.buildLayeredImage { - name = "demostf/api"; - tag = "latest"; - maxLayers = 10; - - contents = [ - demostf-api - demostf-parser - phpWithExtensions - dockerTools.caCertificates - coreutils - bash - fakeNss - (writeScriptBin "start-server" '' - #!${runtimeShell} - php-fpm -F -y ${./php-fpm.conf} - '') - ]; - - extraCommands = '' - mkdir -p tmp - chmod 1777 tmp - ln -s ${demostf-api}/share/php/demostf-api app - ''; - - config = { - Cmd = [ "start-server" ]; - Env = [ - "PARSER_PATH=${demostf-parser}/bin/parse_demo" - ]; - ExposedPorts = { - "9000/tcp" = {}; - }; - }; - } \ No newline at end of file diff --git a/flake.lock b/flake.lock index 113bf72..41ec342 100644 --- a/flake.lock +++ b/flake.lock @@ -1,132 +1,44 @@ { "nodes": { - "flake-parts": { + "flakelight": { "inputs": { - "nixpkgs-lib": "nixpkgs-lib" - }, - "locked": { - "lastModified": 1701473968, - "narHash": "sha256-YcVE5emp1qQ8ieHUnxt1wCZCC3ZfAS+SRRWZ2TMda7E=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "34fed993f1674c8d06d58b37ce1e0fe5eebcb9f5", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flocken": { - "inputs": { - "flake-parts": "flake-parts", "nixpkgs": [ "nixpkgs" - ], - "systems": "systems" + ] }, "locked": { - "lastModified": 1704105102, - "narHash": "sha256-c4VWO9plhINjQzYPHSKURWgQ2D2q24aI3OIN0MTPjz0=", - "owner": "mirkolenz", - "repo": "flocken", - "rev": "3a846dfca17f989805d9f4177de85c96dc0f8542", + "lastModified": 1734957624, + "narHash": "sha256-RbvX9lf9lWQwG9vTXkscOiWTrKf8lzjyeOvW/v8IuBY=", + "owner": "nix-community", + "repo": "flakelight", + "rev": "8c226ea0166784b02d4a58fbb015f9c01250221e", "type": "github" }, "original": { - "owner": "mirkolenz", - "ref": "v2", - "repo": "flocken", + "owner": "nix-community", + "repo": "flakelight", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1710523508, - "narHash": "sha256-cyaeYdWG+RQOFPn1DHgO/lerVI4dxHWwF4EJ0dYcu5g=", + "lastModified": 1734875076, + "narHash": "sha256-Pzyb+YNG5u3zP79zoi8HXYMs15Q5dfjDgwCdUI5B0nY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a3b22bfd2906b8c028d115f2ab4a1cc4ac806a9d", + "rev": "1807c2b91223227ad5599d7067a61665c52d1295", "type": "github" }, "original": { "id": "nixpkgs", - "ref": "release-23.11", + "ref": "nixos-24.11", "type": "indirect" } }, - "nixpkgs-lib": { - "locked": { - "dir": "lib", - "lastModified": 1701253981, - "narHash": "sha256-ztaDIyZ7HrTAfEEUt9AtTDNoCYxUdSd6NrRHaYOIxtk=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "e92039b55bcd58469325ded85d4f58dd5a4eaf58", - "type": "github" - }, - "original": { - "dir": "lib", - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "root": { "inputs": { - "flocken": "flocken", - "nixpkgs": "nixpkgs", - "utils": "utils" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "utils": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" + "flakelight": "flakelight", + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index 572dc81..2f92145 100644 --- a/flake.nix +++ b/flake.nix @@ -1,73 +1,30 @@ { inputs = { - nixpkgs.url = "nixpkgs/release-23.11"; - utils.url = "github:numtide/flake-utils"; - flocken = { - url = "github:mirkolenz/flocken/v2"; + nixpkgs.url = "nixpkgs/nixos-24.11"; + flakelight = { + url = "github:nix-community/flakelight"; inputs.nixpkgs.follows = "nixpkgs"; }; }; - - outputs = { - self, - nixpkgs, - utils, - flocken, - }: - utils.lib.eachDefaultSystem (system: let - inherit (builtins) getEnv; - overlays = [ - (import ./overlay.nix) - ]; - pkgs = import nixpkgs { - inherit system overlays; - }; - npmLd = pkgs.writeShellScriptBin "npm" '' - PATH="$PATH ${pkgs.nodejs_20}/bin" LD=$CC ${pkgs.nodejs_20}/bin/npm $@ - ''; - nodeLd = pkgs.writeShellScriptBin "node" '' - LD=$CC ${pkgs.nodejs_20}/bin/node $@ - ''; - inherit (flocken.legacyPackages.${system}) mkDockerManifest; - - phpVersion = "php82"; - phpPackages = pkgs."${phpVersion}Packages"; - phpPackage = pkgs.${phpVersion}.buildEnv { - extraConfig = "memory_limit = 2G"; - extensions = ({ enabled, all }: enabled ++ (with all; [ - xdebug smbclient - ])); + outputs = {flakelight, ...}: + flakelight ./. { + withOverlays = [(import ./nix/overlay.nix)]; + packages = { + api = pkgs: pkgs.demostf-api; + api-dev = pkgs: pkgs.demostf-api-dev; + api-test = pkgs: pkgs.demostf-api-test; }; - in rec { - packages = rec { - inherit (pkgs) demostf-api demostf-api-docker demostf-parser; - docker = demostf-api-docker; - default = demostf-api; - - dockerManifest = mkDockerManifest { - tags = ["latest"]; - registries = { - "docker.io" = { - enable = true; - repo = "demostf/api"; - username = "$DOCKERHUB_USERNAME"; - password = "$DOCKERHUB_TOKEN"; - }; - }; - version = "1.0.0"; - images = with self.packages; [x86_64-linux.demostf-api-docker aarch64-linux.demostf-api-docker]; - }; + checks = { + integration-tests = pkgs: pkgs.nixosTest (import ./nix/integration-tests.nix); + unit-tests = pkgs: pkgs.nixosTest (import ./nix/unit-tests.nix); }; - devShells.default = pkgs.mkShell { - nativeBuildInputs = with pkgs; [ - gnumake - phpPackage - phpPackages.composer - npmLd - nodeLd - ]; + formatters = pkgs: { + "*.nix" = pkgs.lib.getExe pkgs.alejandra; }; - }) // { - overlays.default = import ./overlay.nix; + devShell.packages = pkgs: [ + pkgs.demostf-api-php.packages.composer + pkgs.demostf-api-php + pkgs.nodejs + ]; }; } diff --git a/nix/api-test.nix b/nix/api-test.nix new file mode 100644 index 0000000..a14a49d --- /dev/null +++ b/nix/api-test.nix @@ -0,0 +1,26 @@ +{ + rustPlatform, + fetchgit, + pkg-config, + openssl, +}: +rustPlatform.buildRustPackage { + pname = "demostf-api-test"; + version = "0.1.4"; + + src = fetchgit { + url = "https://github.com/demostf/api-test"; + rev = "b2a8446e9b12c84d2c9228e4babe5d34132d3298"; + hash = "sha256-Zn6P4ukhoxqP+16ZkLBbqzM9DsTLmSNa4zrkhmyzy/I"; + fetchLFS = true; + }; + + buildInputs = [openssl]; + + nativeBuildInputs = [pkg-config]; + + doCheck = false; + + cargoHash = "sha256-Irv6atngsh0hPJ256tMxer3nR0PjBcaOJLVldnPnwUs="; + meta.mainProgram = "api-test"; +} diff --git a/nix/integration-tests.nix b/nix/integration-tests.nix new file mode 100644 index 0000000..13dea59 --- /dev/null +++ b/nix/integration-tests.nix @@ -0,0 +1,127 @@ +{ + pkgs, + lib, + ... +}: { + name = "demostf-api-client-test"; + nodes.machine = {config, ...}: let + fpmCfg = config.services.phpfpm.pools.demostf-api; + in { + config = { + environment.systemPackages = [pkgs.demostf-api-test]; + + users.groups.demostf = {}; + users.users.demostf = { + group = "demostf"; + isSystemUser = true; + }; + + services.postgresql = { + enable = true; + ensureDatabases = ["demostf"]; + ensureUsers = [ + { + name = "demostf"; + ensureDBOwnership = true; + } + ]; + initialScript = pkgs.writeText "init-sql-script" '' + CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public; + ''; + }; + + services.nginx = { + enable = true; + virtualHosts."localhost" = { + root = "/var/empty"; + extraConfig = '' + try_files $uri /index.php?$query_string /index.php; + ''; + locations = { + "~ ^(.+?\\.php)(/.*)?$" = { + extraConfig = '' + fastcgi_param PATH_INFO $2; + fastcgi_pass unix:${fpmCfg.socket}; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME ${pkgs.demostf-api}/share/php/demostf-api/src/public/index.php; + include ${pkgs.nginx}/conf/fastcgi_params; + client_max_body_size 250m; + ''; + }; + "= /upload" = { + extraConfig = '' + fastcgi_pass unix:${fpmCfg.socket}; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME ${pkgs.demostf-api}/share/php/demostf-api/src/public/upload.php; + include ${pkgs.nginx}/conf/fastcgi_params; + client_max_body_size 250m; + ''; + }; + "/static/" = { + alias = "/demos/"; + }; + }; + }; + }; + + services.phpfpm.pools.demostf-api = { + phpPackage = pkgs.php.buildEnv { + extensions = { + enabled, + all, + }: + enabled ++ (with all; [pdo apcu]); + extraConfig = '' + post_max_size = 150M + upload_max_filesize = 150M + ''; + }; + settings = { + "clear_env" = "no"; + "pm" = "dynamic"; + "pm.max_children" = "25"; + "pm.start_servers" = "5"; + "pm.min_spare_servers" = "5"; + "pm.max_spare_servers" = "15"; + "catch_workers_output" = "yes"; + "listen.owner" = "nginx"; + "listen.group" = "nginx"; + }; + phpEnv = { + BASE_HOST = "demos.tf"; + DEMO_ROOT = "/demos"; + DEMO_HOST = "localhost"; + DB_TYPE = "pgsql"; + DB_HOST = "/run/postgresql"; + DB_PORT = "5432"; + DB_DATABASE = "demostf"; + DB_USERNAME = "demostf"; + APP_ROOT = "http://localhost"; + EDIT_SECRET = "edit"; + PARSER_PATH = lib.getExe pkgs.demostf-parser; + }; + user = "demostf"; + group = "demostf"; + }; + }; + }; + + testScript = let + initSql = pkgs.fetchurl { + url = "https://github.com/demostf/db/raw/refs/heads/master/schema.sql"; + hash = "sha256-AwXN9mh9CRk6HWdvyUR+YdBkpmExNIDOIeDMz6XqjEQ="; + }; + in '' + machine.succeed("mkdir /demos && chmod 0777 /demos"); + machine.wait_for_unit("postgresql") + machine.succeed("sudo -u demostf psql demostf demostf < ${initSql}"); + machine.succeed("sudo -u postgres psql postgres postgres -c \"alter user demostf with password 'demostf';\""); + machine.wait_for_unit("phpfpm-demostf-api") + machine.wait_for_unit("nginx") + machine.wait_until_succeeds("curl http://127.0.0.1", timeout=45) + machine.succeed("DB_URL='postgres://demostf:demostf@localhost/demostf'\ + BASE_URL='http://localhost/'\ + EDIT_KEY='edit'\ + api-test", timeout=180) + ''; +} diff --git a/nix/overlay.nix b/nix/overlay.nix new file mode 100644 index 0000000..3328a95 --- /dev/null +++ b/nix/overlay.nix @@ -0,0 +1,18 @@ +final: prev: { + demostf-parser = final.callPackage ./parser.nix {}; + demostf-api = final.callPackage ./package.nix {}; + demostf-api-dev = final.callPackage ./package.nix {dev = true;}; + demostf-api-test = final.callPackage ./api-test.nix {}; + demostf-api-php = final.php82.buildEnv { + extraConfig = "memory_limit = 2G"; + extensions = { + enabled, + all, + }: + enabled + ++ (with all; [ + pdo + apcu + ]); + }; +} diff --git a/nix/package.nix b/nix/package.nix new file mode 100644 index 0000000..0d5aea0 --- /dev/null +++ b/nix/package.nix @@ -0,0 +1,24 @@ +{ + lib, + demostf-api-php, + dev ? false, +}: let + inherit (lib.sources) sourceByRegex; +in + demostf-api-php.buildComposerProject (finalAttrs: { + pname = "demostf-api"; + version = "0.1.0"; + + composerNoDev = !dev; + + src = sourceByRegex ../. ["composer.*" "(src|test)(/.*)?"]; + + vendorHash = + if dev + then "sha256-PBp2PHoKfM66BjWxbEt5suKlkUxDxXdxhhCVzfRbJdo=" + else "sha256-EYWCR2aJAoyWvEX+SML4Fb3F3KGcUtwCgqhAGT6ZjZ4="; + + composerStrictValidation = false; + + doCheck = false; + }) diff --git a/nix/parser.nix b/nix/parser.nix new file mode 100644 index 0000000..e0dd8c2 --- /dev/null +++ b/nix/parser.nix @@ -0,0 +1,24 @@ +{ + rustPlatform, + fetchFromGitHub, +}: +rustPlatform.buildRustPackage { + pname = "demostf-parser"; + version = "0.5.1"; + + src = fetchFromGitHub { + owner = "demostf"; + repo = "parser"; + rev = "0cd87a8a40e2a6af637d831b272c2758cebd2f9c"; + hash = "sha256-bKcc0hWTkdYUDMI/DjUh45abuBeQEvkn6TsuAz02H5Y="; + }; + + cargoBuildFlags = '' + --bin parse_demo + ''; + + doCheck = false; + + cargoHash = "sha256-/Fnw6l2fznrBK780E4q1PKFOkT0eiL+dE+UuhFA+V9M="; + meta.mainProgram = "parse_demo"; +} diff --git a/nix/unit-tests.nix b/nix/unit-tests.nix new file mode 100644 index 0000000..f674b9e --- /dev/null +++ b/nix/unit-tests.nix @@ -0,0 +1,53 @@ +{ + pkgs, + lib, + ... +}: { + name = "demostf-api-unit-tests"; + nodes.machine = {config, ...}: { + config = { + users.groups.demostf = {}; + users.users.demostf = { + group = "demostf"; + isSystemUser = true; + }; + + services.postgresql = { + enable = true; + ensureDatabases = ["demostf"]; + ensureUsers = [ + { + name = "demostf"; + ensureDBOwnership = true; + } + ]; + initialScript = pkgs.writeText "init-sql-script" '' + CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public; + ''; + }; + }; + }; + + testScript = let + php = lib.getExe pkgs.demostf-api-php; + api = pkgs.demostf-api-dev; + initSql = pkgs.fetchurl { + url = "https://github.com/demostf/db/raw/refs/heads/master/schema.sql"; + hash = "sha256-AwXN9mh9CRk6HWdvyUR+YdBkpmExNIDOIeDMz6XqjEQ="; + }; + in '' + machine.succeed("mkdir /demos && chmod 0777 /demos"); + machine.wait_for_unit("postgresql") + machine.succeed("sudo -u demostf psql demostf demostf < ${initSql}"); + machine.succeed("sudo -u postgres psql postgres postgres -c \"alter user demostf with password 'demostf';\""); + machine.succeed("cd ${api}/share/php/demostf-api; DB_HOST='localhost'\ + DB_TYPE='pgsql'\ + DB_PORT='5432'\ + DB_USERNAME='demostf'\ + DB_PASSWORD='demostf'\ + DB_DATABASE='demostf'\ + BASE_URL='http://localhost/'\ + EDIT_KEY='edit'\ + ${php} ./vendor/bin/phpunit test", timeout=180) + ''; +} diff --git a/overlay.nix b/overlay.nix deleted file mode 100644 index 7908fae..0000000 --- a/overlay.nix +++ /dev/null @@ -1,5 +0,0 @@ -final: prev: { - demostf-parser = final.callPackage ./parser.nix {}; - demostf-api = final.callPackage ./package.nix {}; - demostf-api-docker = final.callPackage ./docker.nix {}; -} \ No newline at end of file diff --git a/package.nix b/package.nix deleted file mode 100644 index 6c7f32a..0000000 --- a/package.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - stdenv, - php, - lib, -}: let - inherit (lib.sources) sourceByRegex; - phpWithExtensions = php.withExtensions ({ enabled, all }: enabled ++ (with all; [pdo apcu])); -in - phpWithExtensions.buildComposerProject (finalAttrs: { - pname = "demostf-api"; - version = "0.1.0"; - - src = sourceByRegex ./. ["composer.*" "(src|test)(/.*)?"]; - - vendorHash = "sha256-EYWCR2aJAoyWvEX+SML4Fb3F3KGcUtwCgqhAGT6ZjZ4="; - - composerStrictValidation = false; - - doCheck = false; - }) \ No newline at end of file diff --git a/parser-Cargo.lock b/parser-Cargo.lock deleted file mode 100644 index ac1e517..0000000 --- a/parser-Cargo.lock +++ /dev/null @@ -1,1624 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "better-panic" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa9e1d11a268684cbd90ed36370d7577afb6c62d912ddff5c15fc34343e5036" -dependencies = [ - "backtrace", - "console", -] - -[[package]] -name = "bitbuffer" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525586993a118417512a49bada2d143319310891f48b0b116c8f64fbb6486c87" -dependencies = [ - "bitbuffer_derive", - "err-derive", - "memchr", - "num-traits 0.2.17", - "schemars", - "serde", -] - -[[package]] -name = "bitbuffer_derive" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052a5a614540ae9bb7de25c2c86a94b6de7374cb7e3230f3128955bdaea62c3f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "syn_util", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "ciborium" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" - -[[package]] -name = "ciborium-ll" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" -dependencies = [ - "ciborium-io", - "half", -] - -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "bitflags 1.3.2", - "clap_lex", - "indexmap 1.9.3", - "textwrap", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "console" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "windows-sys 0.45.0", -] - -[[package]] -name = "criterion" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" -dependencies = [ - "anes", - "atty", - "cast", - "ciborium", - "clap", - "criterion-plot", - "itertools", - "lazy_static", - "num-traits 0.2.17", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "dyn-clone" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "enum_primitive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" -dependencies = [ - "num-traits 0.1.43", -] - -[[package]] -name = "enumflags2" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" -dependencies = [ - "enumflags2_derive", - "serde", -] - -[[package]] -name = "enumflags2_derive" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "err-derive" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34a887c8df3ed90498c1c437ce21f211c8e27672921a8ffa293cb8d6d4caa9e" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", - "synstructure", -] - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "iai" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71a816c97c42258aa5834d07590b718b4c9a598944cd39a52dc25b351185d678" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" -dependencies = [ - "equivalent", - "hashbrown 0.14.3", -] - -[[package]] -name = "insta" -version = "1.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc" -dependencies = [ - "console", - "lazy_static", - "linked-hash-map", - "serde", - "similar", - "yaml-rust", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "jemalloc-sys" -version = "0.5.4+5.3.0-patched" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "jemallocator" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc" -dependencies = [ - "jemalloc-sys", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "main_error" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155db5e86c6e45ee456bf32fad5a290ee1f7151c2faca27ea27097568da67d1a" - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "memchr" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "no-panic" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc56831a2ae584dc43a8b0b33f496e71fb4d43cf8c1c0a3fd932e6340bea1f81" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits 0.2.17", -] - -[[package]] -name = "num-bigint" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" -dependencies = [ - "autocfg", - "num-integer", - "num-traits 0.2.17", -] - -[[package]] -name = "num-complex" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" -dependencies = [ - "num-traits 0.2.17", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits 0.2.17", -] - -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits 0.2.17", -] - -[[package]] -name = "num-rational" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits 0.2.17", -] - -[[package]] -name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -dependencies = [ - "num-traits 0.2.17", -] - -[[package]] -name = "num-traits" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_enum" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parse-display" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6509d08722b53e8dafe97f2027b22ccbe3a5db83cb352931e9716b0aa44bc5c" -dependencies = [ - "once_cell", - "parse-display-derive", - "regex", -] - -[[package]] -name = "parse-display-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68517892c8daf78da08c0db777fcc17e07f2f63ef70041718f8a7630ad84f341" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "regex", - "regex-syntax 0.7.5", - "structmeta", - "syn 2.0.47", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "plotters" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" -dependencies = [ - "num-traits 0.2.17", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" - -[[package]] -name = "plotters-svg" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "pretty_assertions" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" -dependencies = [ - "diff", - "yansi", -] - -[[package]] -name = "prettyplease" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" -dependencies = [ - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rayon" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "regex" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustix" -version = "0.38.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" -dependencies = [ - "bitflags 2.4.2", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - -[[package]] -name = "ryu" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schemars" -version = "0.8.16" -source = "git+https://github.com/icewind1991/schemars?branch=simplify-generated-enum-code#1a82a9f045bc0b1ebd7e9466877ffbb7d45a6eef" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.16" -source = "git+https://github.com/icewind1991/schemars?branch=simplify-generated-enum-code#1a82a9f045bc0b1ebd7e9466877ffbb7d45a6eef" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 1.0.109", -] - -[[package]] -name = "serde" -version = "1.0.194" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.194" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "serde_derive_internals" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "serde_json" -version = "1.0.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "similar" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" - -[[package]] -name = "smallvec" -version = "1.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" - -[[package]] -name = "snap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" - -[[package]] -name = "steamid-ng" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb049f8faa2cba570c5366dbaf88ee5849725b16edb771848639fac92e33673" -dependencies = [ - "enum_primitive", - "lazy_static", - "num", - "regex", - "serde", - "serde_derive", - "thiserror", -] - -[[package]] -name = "structmeta" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ad9e09554f0456d67a69c1584c9798ba733a5b50349a6c0d0948710523922d" -dependencies = [ - "proc-macro2", - "quote", - "structmeta-derive", - "syn 2.0.47", -] - -[[package]] -name = "structmeta-derive" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn_util" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6754c4559b79657554e9d8a0d56e65e490c76d382b9c23108364ec4125dea23c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - -[[package]] -name = "tempfile" -version = "3.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "test-case" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21d6cf5a7dffb3f9dceec8e6b8ca528d9bd71d36c9f074defb548ce161f598c0" -dependencies = [ - "test-case-macros", -] - -[[package]] -name = "test-case-macros" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e45b7bf6e19353ddd832745c8fcf77a17a93171df7151187f26623f2b75b5b26" -dependencies = [ - "cfg-if", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - -[[package]] -name = "tf-demo-parser" -version = "0.5.1" -dependencies = [ - "Inflector", - "better-panic", - "bitbuffer", - "criterion", - "enumflags2", - "err-derive", - "fnv", - "iai", - "insta", - "itertools", - "jemallocator", - "lazy_static", - "main_error", - "no-panic", - "num-traits 0.2.17", - "num_enum", - "parse-display", - "pretty_assertions", - "prettyplease", - "proc-macro2", - "quote", - "schemars", - "serde", - "serde_json", - "serde_repr", - "snap", - "steamid-ng", - "syn 1.0.109", - "tempfile", - "test-case", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "thiserror" -version = "1.0.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.47", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" - -[[package]] -name = "web-sys" -version = "0.3.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" - -[[package]] -name = "winnow" -version = "0.5.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434aeec7b290e8da5c3f0d628cb0eac6cabcb31d14bb74f779a08109a5914d6" -dependencies = [ - "memchr", -] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/parser.nix b/parser.nix deleted file mode 100644 index 91ae36b..0000000 --- a/parser.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - stdenv, - rustPlatform, - fetchFromGitHub, - lib, -}: let - inherit (lib.sources) sourceByRegex; -in - rustPlatform.buildRustPackage rec { - pname = "demostf-parser"; - version = "0.1.0"; - - src = fetchFromGitHub { - owner = "demostf"; - repo = "parser"; - rev = "2449c9666019a99b791f84d3c0c38b6b7c71ad20"; - hash = "sha256-V0rm9pVfZUGPrD3raOJ7O6EQkbxVG6cIquWvdFkGPgM="; - }; - - cargoBuildFlags = '' - --bin parse_demo - ''; - - doCheck = false; - - cargoLock = { - lockFile = ./parser-Cargo.lock; - outputHashes = { - "schemars-0.8.16" = "sha256-mQR56Ym76gSRulZrThmZHHw2JfhEgYhWXabwaYmyMYs="; - }; - }; - } \ No newline at end of file diff --git a/test/Providers/UploadProviderTest.php b/test/Providers/UploadProviderTest.php index a964575..af22556 100644 --- a/test/Providers/UploadProviderTest.php +++ b/test/Providers/UploadProviderTest.php @@ -273,14 +273,8 @@ private function saveSteamId($steamId, $name) { $this->userProvider->store($steamId, $name); } - public function testUpload() { - copy(__DIR__ . '/../data/product.dem', $this->tmpDir . '/foo.dem'); - copy(__DIR__ . '/../data/product-raw.json', $this->tmpDir . '/foo-raw.json'); - - $steamId = $this->getSteamId('123', 'a'); - $token = $this->userProvider->store($steamId, 'a'); - - // pre-save the names so we dont have to get them from steam + private function preloadNames() { + // pre-save the names so we don't have to get them from steam $this->saveSteamId('[U:1:64229260]', 'Icewind'); $this->saveSteamId('[U:1:115748435]', 'Foz'); $this->saveSteamId('[U:1:115754284]', 'Deity'); @@ -299,6 +293,26 @@ public function testUpload() { $this->saveSteamId('[U:1:92096346]', 'Fish'); $this->saveSteamId('[U:1:143626373]', 'Pendulum'); $this->saveSteamId('[U:1:30220936]', 'Jedi'); + $this->saveSteamId('[U:1:1104797071]', 'Katsu'); + } + + public function uploadProvider(): array { + return [ + [__DIR__ . '/../data/product.dem', __DIR__ . '/../data/product-raw.json', 'koth_product_rc8', 0, 3], + ]; + } + + /** + * @dataProvider uploadProvider + */ + public function testUpload(string $demo, string $parsed, string $map, int $blue, int $red) { + copy($demo, $this->tmpDir . '/foo.dem'); + copy($parsed, $this->tmpDir . '/foo-raw.json'); + + $steamId = $this->getSteamId('123', 'a'); + $token = $this->userProvider->store($steamId, 'a'); + + $this->preloadNames(); $result = $this->uploadProvider->upload($token, 'RED', 'BLU', 'foodemo', $this->tmpDir . '/foo.dem'); $this->assertStringStartsWith('STV available at: http://example.com/', $result); @@ -309,8 +323,8 @@ public function testUpload() { $this->assertNotNull($demo); - $this->assertEquals('koth_product_rc8', $demo->getMap()); - $this->assertEquals(0, $demo->getBlueScore()); - $this->assertEquals(3, $demo->getRedScore()); + $this->assertEquals($map, $demo->getMap()); + $this->assertEquals($blue, $demo->getBlueScore()); + $this->assertEquals($red, $demo->getRedScore()); } } diff --git a/test/data/product-analyse.json b/test/data/product-analyse.json index 15985a0..3b8007b 100644 --- a/test/data/product-analyse.json +++ b/test/data/product-analyse.json @@ -1,1597 +1,1597 @@ { - "score": { - "red": 3, - "blue": 0 - }, - "chat": [ - { - "time": 926, - "from": "Foz", - "text": "gg" - }, - { - "time": 769, - "from": "\uff2d\uff41\uff53\uff4f\uff4e\u2727", - "text": "gg" - }, - { - "time": 770, - "from": "Kireek", - "text": "gg" - }, - { - "time": 770, - "from": "Sketis", - "text": "wp" - }, - { - "time": 771, - "from": "Vinegar", - "text": "gg" - }, - { - "time": 771, - "from": "Pendulum", - "text": "gg in chat" - }, - { - "time": 772, - "from": "Icewind | demos.tf", - "text": "gg" - }, - { - "time": 773, - "from": "Solar", - "text": "gg" - }, - { - "time": 775, - "from": "magikarp", - "text": "gg" - } - ], - "players": [ - { - "name": "Icewind | demos.tf", - "demo_user_id": 30, - "steam_id": "[U:1:64229260]", - "team": "red", - "class": "medic" - }, - { - "name": "Foz", - "demo_user_id": 32, - "steam_id": "[U:1:115748435]", - "team": "red", - "class": "soldier" - }, - { - "name": "Chicken Meatballs, FOZ", - "demo_user_id": 36, - "steam_id": "[U:1:115754284]", - "team": "red", - "class": "sniper" - }, - { - "name": "Kireek", - "demo_user_id": 39, - "steam_id": "[U:1:92428736]", - "team": "red", - "class": "engineer" - }, - { - "name": "Vinegar", - "demo_user_id": 42, - "steam_id": "[U:1:22958903]", - "team": "red", - "class": "spy" - }, - { - "name": "[GC]Kimo", - "demo_user_id": 43, - "steam_id": "[U:1:32061783]", - "team": "red", - "class": "scout" - }, - { - "name": "magikarp", - "demo_user_id": 44, - "steam_id": "[U:1:67502510]", - "team": "blue", - "class": "sniper" - }, - { - "name": "Solar", - "demo_user_id": 45, - "steam_id": "[U:1:55128465]", - "team": "blue", - "class": "demoman" - }, - { - "name": "ztreak", - "demo_user_id": 46, - "steam_id": "[U:1:301587080]", - "team": "blue", - "class": "scout" - }, - { - "name": "TheMasterOfDisaster", - "demo_user_id": 47, - "steam_id": "[U:1:22162172]", - "team": "blue", - "class": "pyro" - }, - { - "name": "Sage Luke", - "demo_user_id": 48, - "steam_id": "[U:1:13559571]", - "team": "blue", - "class": "medic" - }, - { - "name": "Sketis", - "demo_user_id": 50, - "steam_id": "[U:1:71706948]", - "team": "blue", - "class": "engineer" - }, - { - "name": "Pyla", - "demo_user_id": 51, - "steam_id": "[U:1:157204170]", - "team": "blue", - "class": "spy" - }, - { - "name": "\uff2d\uff41\uff53\uff4f\uff4e\u2727", - "demo_user_id": 52, - "steam_id": "[U:1:30838206]", - "team": "blue", - "class": "heavyweapons" - }, - { - "name": "\uff52\uff41\uff4e\uff45", - "demo_user_id": 53, - "steam_id": "[U:1:174774002]", - "team": "blue", - "class": "soldier" - }, - { - "name": "Old Billy Riley", - "demo_user_id": 54, - "steam_id": "[U:1:92096346]", - "team": "red", - "class": "demoman" - }, - { - "name": "Pendulum", - "demo_user_id": 55, - "steam_id": "[U:1:143626373]", - "team": "red", - "class": "heavyweapons" - }, - { - "name": "Jedi(fla)master", - "demo_user_id": 56, - "steam_id": "[U:1:30220936]", - "team": "red", - "class": "pyro" - } - ], - "kills": [ - { - "killer": 36, - "assister": null, - "victim": 50, - "weapon": "sniperrifle", - "tick": 10651 - }, - { - "killer": 55, - "assister": null, - "victim": 44, - "weapon": "minigun", - "tick": 10687 - }, - { - "killer": 39, - "assister": null, - "victim": 46, - "weapon": "shotgun_primary", - "tick": 10711 - }, - { - "killer": 32, - "assister": null, - "victim": 45, - "weapon": "quake_rl", - "tick": 10814 - }, - { - "killer": 32, - "assister": null, - "victim": 48, - "weapon": "quake_rl", - "tick": 10814 - }, - { - "killer": 55, - "assister": null, - "victim": 53, - "weapon": "minigun", - "tick": 10834 - }, - { - "killer": 45, - "assister": null, - "victim": 42, - "weapon": "tf_projectile_pipe_remote", - "tick": 12037 - }, - { - "killer": 36, - "assister": 43, - "victim": 46, - "weapon": "sniperrifle", - "tick": 12152 - }, - { - "killer": 44, - "assister": null, - "victim": 56, - "weapon": "machina", - "tick": 12428 - }, - { - "killer": 51, - "assister": null, - "victim": 55, - "weapon": "spy_cicle", - "tick": 12450 - }, - { - "killer": 32, - "assister": 56, - "victim": 53, - "weapon": "quake_rl", - "tick": 12524 - }, - { - "killer": 44, - "assister": null, - "victim": 32, - "weapon": "machina", - "tick": 12736 - }, - { - "killer": 47, - "assister": null, - "victim": 42, - "weapon": "degreaser", - "tick": 12898 - }, - { - "killer": 39, - "assister": null, - "victim": 47, - "weapon": "obj_minisentry", - "tick": 13042 - }, - { - "killer": 51, - "assister": 47, - "victim": 39, - "weapon": "spy_cicle", - "tick": 13096 - }, - { - "killer": 44, - "assister": null, - "victim": 30, - "weapon": "machina", - "tick": 13696 - }, - { - "killer": 54, - "assister": 43, - "victim": 52, - "weapon": "tf_projectile_pipe_remote", - "tick": 13800 - }, - { - "killer": 46, - "assister": 48, - "victim": 42, - "weapon": "scattergun", - "tick": 13992 - }, - { - "killer": 45, - "assister": 48, - "victim": 43, - "weapon": "iron_bomber", - "tick": 14272 - }, - { - "killer": 36, - "assister": null, - "victim": 46, - "weapon": "sniperrifle", - "tick": 14529 - }, - { - "killer": 44, - "assister": 48, - "victim": 56, - "weapon": "machina", - "tick": 14830 - }, - { - "killer": 45, - "assister": null, - "victim": 54, - "weapon": "iron_bomber", - "tick": 14918 - }, - { - "killer": 39, - "assister": null, - "victim": 51, - "weapon": "shotgun_primary", - "tick": 15509 - }, - { - "killer": 42, - "assister": 55, - "victim": 44, - "weapon": "revolver", - "tick": 15738 - }, - { - "killer": 42, - "assister": null, - "victim": 47, - "weapon": "revolver", - "tick": 15900 - }, - { - "killer": 43, - "assister": null, - "victim": 45, - "weapon": "world", - "tick": 15991 - }, - { - "killer": 53, - "assister": 48, - "victim": 42, - "weapon": "blackbox", - "tick": 16105 - }, - { - "killer": 50, - "assister": 46, - "victim": 42, - "weapon": "rescue_ranger", - "tick": 16358 - }, - { - "killer": 54, - "assister": 39, - "victim": 46, - "weapon": "tf_projectile_pipe_remote", - "tick": 16935 - }, - { - "killer": 43, - "assister": 55, - "victim": 52, - "weapon": "scattergun", - "tick": 17825 - }, - { - "killer": 53, - "assister": null, - "victim": 42, - "weapon": "blackbox", - "tick": 18178 - }, - { - "killer": 53, - "assister": 48, - "victim": 42, - "weapon": "blackbox", - "tick": 18791 - }, - { - "killer": 43, - "assister": 42, - "victim": 44, - "weapon": "scattergun", - "tick": 18936 - }, - { - "killer": 39, - "assister": 43, - "victim": 46, - "weapon": "obj_minisentry", - "tick": 19416 - }, - { - "killer": 36, - "assister": 54, - "victim": 52, - "weapon": "sniperrifle", - "tick": 19736 - }, - { - "killer": 43, - "assister": null, - "victim": 50, - "weapon": "scattergun", - "tick": 20060 - }, - { - "killer": 51, - "assister": null, - "victim": 42, - "weapon": "spy_cicle", - "tick": 20224 - }, - { - "killer": 36, - "assister": null, - "victim": 44, - "weapon": "sniperrifle", - "tick": 20521 - }, - { - "killer": 43, - "assister": 39, - "victim": 47, - "weapon": "scattergun", - "tick": 20730 - }, - { - "killer": 53, - "assister": null, - "victim": 42, - "weapon": "blackbox", - "tick": 20735 - }, - { - "killer": 50, - "assister": null, - "victim": 42, - "weapon": "obj_minisentry", - "tick": 21844 - }, - { - "killer": 32, - "assister": null, - "victim": 51, - "weapon": "quake_rl", - "tick": 21870 - }, - { - "killer": 45, - "assister": 48, - "victim": 56, - "weapon": "iron_bomber", - "tick": 21896 - }, - { - "killer": 47, - "assister": 50, - "victim": 42, - "weapon": "degreaser", - "tick": 22199 - }, - { - "killer": 53, - "assister": 52, - "victim": 43, - "weapon": "blackbox", - "tick": 22275 - }, - { - "killer": 39, - "assister": 55, - "victim": 53, - "weapon": "shotgun_primary", - "tick": 22464 - }, - { - "killer": 36, - "assister": 54, - "victim": 50, - "weapon": "sniperrifle", - "tick": 22520 - }, - { - "killer": 39, - "assister": 32, - "victim": 46, - "weapon": "obj_minisentry", - "tick": 22631 - }, - { - "killer": 42, - "assister": null, - "victim": 44, - "weapon": "world", - "tick": 22661 - }, - { - "killer": 39, - "assister": 55, - "victim": 47, - "weapon": "obj_minisentry", - "tick": 22835 - }, - { - "killer": 50, - "assister": null, - "victim": 42, - "weapon": "obj_minisentry", - "tick": 22855 - }, - { - "killer": 39, - "assister": 54, - "victim": 45, - "weapon": "shotgun_primary", - "tick": 23389 - }, - { - "killer": 44, - "assister": 46, - "victim": 36, - "weapon": "machina", - "tick": 24391 - }, - { - "killer": 53, - "assister": null, - "victim": 32, - "weapon": "blackbox", - "tick": 25148 - }, - { - "killer": 54, - "assister": 30, - "victim": 46, - "weapon": "tf_projectile_pipe_remote", - "tick": 25196 - }, - { - "killer": 54, - "assister": 30, - "victim": 52, - "weapon": "tf_projectile_pipe_remote", - "tick": 25196 - }, - { - "killer": 56, - "assister": 39, - "victim": 51, - "weapon": "degreaser", - "tick": 25264 - }, - { - "killer": 42, - "assister": null, - "victim": 53, - "weapon": "revolver", - "tick": 25358 - }, - { - "killer": 43, - "assister": 39, - "victim": 47, - "weapon": "scattergun", - "tick": 25397 - }, - { - "killer": 55, - "assister": 30, - "victim": 50, - "weapon": "minigun", - "tick": 25529 - }, - { - "killer": 42, - "assister": null, - "victim": 44, - "weapon": "spy_cicle", - "tick": 26007 - }, - { - "killer": 46, - "assister": 48, - "victim": 42, - "weapon": "scattergun", - "tick": 26411 - }, - { - "killer": 51, - "assister": null, - "victim": 55, - "weapon": "spy_cicle", - "tick": 26848 - }, - { - "killer": 42, - "assister": 39, - "victim": 50, - "weapon": "spy_cicle", - "tick": 27080 - }, - { - "killer": 46, - "assister": null, - "victim": 42, - "weapon": "scattergun", - "tick": 27450 - }, - { - "killer": 43, - "assister": 39, - "victim": 53, - "weapon": "scattergun", - "tick": 27955 - }, - { - "killer": 32, - "assister": 39, - "victim": 47, - "weapon": "quake_rl", - "tick": 28013 - }, - { - "killer": 44, - "assister": null, - "victim": 39, - "weapon": "machina", - "tick": 28049 - }, - { - "killer": 50, - "assister": null, - "victim": 42, - "weapon": "shotgun_primary", - "tick": 28311 - }, - { - "killer": 56, - "assister": null, - "victim": 51, - "weapon": "degreaser", - "tick": 28390 - }, - { - "killer": 54, - "assister": 32, - "victim": 46, - "weapon": "tf_projectile_pipe_remote", - "tick": 28889 - }, - { - "killer": 32, - "assister": 54, - "victim": 48, - "weapon": "quake_rl", - "tick": 28896 - }, - { - "killer": 30, - "assister": null, - "victim": 45, - "weapon": "crusaders_crossbow", - "tick": 28970 - }, - { - "killer": 54, - "assister": null, - "victim": 52, - "weapon": "iron_bomber", - "tick": 28980 - }, - { - "killer": 50, - "assister": 52, - "victim": 32, - "weapon": "obj_minisentry", - "tick": 29040 - }, - { - "killer": 44, - "assister": 50, - "victim": 56, - "weapon": "machina", - "tick": 29090 - }, - { - "killer": 43, - "assister": 56, - "victim": 50, - "weapon": "scattergun", - "tick": 29314 - }, - { - "killer": 44, - "assister": null, - "victim": 56, - "weapon": "machina", - "tick": 31127 - }, - { - "killer": 32, - "assister": 43, - "victim": 47, - "weapon": "quake_rl", - "tick": 31559 - }, - { - "killer": 51, - "assister": null, - "victim": 55, - "weapon": "kunai", - "tick": 31673 - }, - { - "killer": 42, - "assister": null, - "victim": 52, - "weapon": "kunai", - "tick": 31675 - }, - { - "killer": 44, - "assister": 52, - "victim": 32, - "weapon": "machina", - "tick": 31717 - }, - { - "killer": 43, - "assister": 32, - "victim": 53, - "weapon": "scattergun", - "tick": 31726 - }, - { - "killer": 53, - "assister": null, - "victim": 43, - "weapon": "blackbox", - "tick": 31730 - }, - { - "killer": 54, - "assister": 39, - "victim": 50, - "weapon": "iron_bomber", - "tick": 31839 - }, - { - "killer": 36, - "assister": null, - "victim": 46, - "weapon": "sniperrifle", - "tick": 32125 - }, - { - "killer": 44, - "assister": 48, - "victim": 39, - "weapon": "machina", - "tick": 32651 - }, - { - "killer": 54, - "assister": null, - "victim": 45, - "weapon": "iron_bomber", - "tick": 32811 - }, - { - "killer": 42, - "assister": null, - "victim": 48, - "weapon": "letranger", - "tick": 33017 - }, - { - "killer": 56, - "assister": 43, - "victim": 51, - "weapon": "flaregun", - "tick": 33061 - }, - { - "killer": 54, - "assister": null, - "victim": 44, - "weapon": "iron_bomber", - "tick": 33203 - }, - { - "killer": 50, - "assister": 47, - "victim": 42, - "weapon": "shotgun_primary", - "tick": 34179 - }, - { - "killer": 36, - "assister": null, - "victim": 44, - "weapon": "sniperrifle", - "tick": 34920 - }, - { - "killer": 32, - "assister": null, - "victim": 51, - "weapon": "quake_rl", - "tick": 35322 - }, - { - "killer": 54, - "assister": 30, - "victim": 46, - "weapon": "iron_bomber", - "tick": 35465 - }, - { - "killer": 32, - "assister": 39, - "victim": 53, - "weapon": "quake_rl", - "tick": 36017 - }, - { - "killer": 39, - "assister": 55, - "victim": 47, - "weapon": "shotgun_primary", - "tick": 36265 - }, - { - "killer": 54, - "assister": 36, - "victim": 52, - "weapon": "tf_projectile_pipe_remote", - "tick": 36441 - }, - { - "killer": 42, - "assister": null, - "victim": 44, - "weapon": "kunai", - "tick": 36717 - }, - { - "killer": 54, - "assister": 55, - "victim": 50, - "weapon": "tf_projectile_pipe_remote", - "tick": 37567 - }, - { - "killer": 51, - "assister": null, - "victim": 32, - "weapon": "kunai", - "tick": 37571 - }, - { - "killer": 51, - "assister": null, - "victim": 30, - "weapon": "kunai", - "tick": 38117 - }, - { - "killer": 44, - "assister": null, - "victim": 42, - "weapon": "machina", - "tick": 38131 - }, - { - "killer": 54, - "assister": 43, - "victim": 51, - "weapon": "tf_projectile_pipe_remote", - "tick": 38255 - }, - { - "killer": 46, - "assister": null, - "victim": 55, - "weapon": "scattergun", - "tick": 38683 - }, - { - "killer": 43, - "assister": 54, - "victim": 52, - "weapon": "scattergun", - "tick": 38703 - }, - { - "killer": 39, - "assister": 55, - "victim": 46, - "weapon": "obj_minisentry", - "tick": 38787 - }, - { - "killer": 44, - "assister": null, - "victim": 54, - "weapon": "machina", - "tick": 38797 - }, - { - "killer": 45, - "assister": 48, - "victim": 43, - "weapon": "tf_projectile_pipe_remote", - "tick": 38809 - }, - { - "killer": 32, - "assister": null, - "victim": 45, - "weapon": "quake_rl", - "tick": 39291 - }, - { - "killer": 56, - "assister": null, - "victim": 44, - "weapon": "flaregun", - "tick": 39351 - }, - { - "killer": 56, - "assister": null, - "victim": 48, - "weapon": "flaregun", - "tick": 39591 - }, - { - "killer": 36, - "assister": 32, - "victim": 47, - "weapon": "sniperrifle", - "tick": 39611 - }, - { - "killer": 56, - "assister": null, - "victim": 51, - "weapon": "degreaser", - "tick": 39747 - }, - { - "killer": 53, - "assister": null, - "victim": 56, - "weapon": "blackbox", - "tick": 39753 - }, - { - "killer": 36, - "assister": null, - "victim": 50, - "weapon": "sniperrifle", - "tick": 39775 - }, - { - "killer": 53, - "assister": null, - "victim": 32, - "weapon": "blackbox", - "tick": 40053 - }, - { - "killer": 39, - "assister": 55, - "victim": 53, - "weapon": "shotgun_primary", - "tick": 40183 - }, - { - "killer": 36, - "assister": 30, - "victim": 44, - "weapon": "sniperrifle", - "tick": 41360 - }, - { - "killer": 42, - "assister": 39, - "victim": 50, - "weapon": "kunai", - "tick": 41393 - }, - { - "killer": 55, - "assister": null, - "victim": 51, - "weapon": "minigun", - "tick": 41761 - }, - { - "killer": 36, - "assister": 54, - "victim": 47, - "weapon": "sniperrifle", - "tick": 42213 - }, - { - "killer": 45, - "assister": 52, - "victim": 42, - "weapon": "tf_projectile_pipe_remote", - "tick": 42481 - }, - { - "killer": 43, - "assister": null, - "victim": 53, - "weapon": "scattergun", - "tick": 42735 - }, - { - "killer": 36, - "assister": null, - "victim": 44, - "weapon": "sniperrifle", - "tick": 42884 - }, - { - "killer": 43, - "assister": null, - "victim": 46, - "weapon": "scattergun", - "tick": 42912 - }, - { - "killer": 43, - "assister": 32, - "victim": 51, - "weapon": "scattergun", - "tick": 43261 - }, - { - "killer": 42, - "assister": null, - "victim": 47, - "weapon": "kunai", - "tick": 44809 - }, - { - "killer": 36, - "assister": 30, - "victim": 52, - "weapon": "sniperrifle", - "tick": 44963 - }, - { - "killer": 54, - "assister": 30, - "victim": 48, - "weapon": "tf_projectile_pipe_remote", - "tick": 45381 - }, - { - "killer": 55, - "assister": 36, - "victim": 50, - "weapon": "minigun", - "tick": 45381 - }, - { - "killer": 51, - "assister": 50, - "victim": 56, - "weapon": "kunai", - "tick": 45551 - }, - { - "killer": 53, - "assister": null, - "victim": 42, - "weapon": "blackbox", - "tick": 45651 - }, - { - "killer": 45, - "assister": 50, - "victim": 32, - "weapon": "iron_bomber", - "tick": 45665 - }, - { - "killer": 32, - "assister": null, - "victim": 45, - "weapon": "quake_rl", - "tick": 45667 - }, - { - "killer": 39, - "assister": 43, - "victim": 51, - "weapon": "shotgun_primary", - "tick": 45729 - }, - { - "killer": 39, - "assister": 43, - "victim": 53, - "weapon": "obj_minisentry", - "tick": 45865 - }, - { - "killer": 39, - "assister": null, - "victim": 46, - "weapon": "obj_minisentry", - "tick": 46049 - }, - { - "killer": 54, - "assister": 43, - "victim": 45, - "weapon": "tf_projectile_pipe_remote", - "tick": 47557 - }, - { - "killer": 53, - "assister": null, - "victim": 42, - "weapon": "blackbox", - "tick": 47775 - }, - { - "killer": 48, - "assister": null, - "victim": 32, - "weapon": "crusaders_crossbow", - "tick": 47827 - }, - { - "killer": 54, - "assister": 55, - "victim": 47, - "weapon": "iron_bomber", - "tick": 47953 - }, - { - "killer": 39, - "assister": 56, - "victim": 51, - "weapon": "shotgun_primary", - "tick": 47991 - }, - { - "killer": 52, - "assister": null, - "victim": 54, - "weapon": "tomislav", - "tick": 48053 - }, - { - "killer": 36, - "assister": null, - "victim": 52, - "weapon": "sniperrifle", - "tick": 48437 - }, - { - "killer": 43, - "assister": null, - "victim": 46, - "weapon": "scattergun", - "tick": 48509 - }, - { - "killer": 39, - "assister": 56, - "victim": 50, - "weapon": "obj_minisentry", - "tick": 48527 - }, - { - "killer": 44, - "assister": 48, - "victim": 36, - "weapon": "machina", - "tick": 48607 - }, - { - "killer": 39, - "assister": 43, - "victim": 53, - "weapon": "obj_minisentry", - "tick": 48773 - }, - { - "killer": 48, - "assister": null, - "victim": 43, - "weapon": "crusaders_crossbow", - "tick": 49049 - }, - { - "killer": 44, - "assister": 48, - "victim": 39, - "weapon": "machina", - "tick": 49121 - }, - { - "killer": 42, - "assister": 55, - "victim": 47, - "weapon": "kunai", - "tick": 49923 - }, - { - "killer": 32, - "assister": 55, - "victim": 44, - "weapon": "quake_rl", - "tick": 50659 - }, - { - "killer": 51, - "assister": null, - "victim": 55, - "weapon": "kunai", - "tick": 50825 - }, - { - "killer": 42, - "assister": null, - "victim": 45, - "weapon": "kunai", - "tick": 50845 - }, - { - "killer": 46, - "assister": 48, - "victim": 42, - "weapon": "scattergun", - "tick": 51071 - }, - { - "killer": 36, - "assister": null, - "victim": 52, - "weapon": "sniperrifle", - "tick": 51293 - }, - { - "killer": 56, - "assister": null, - "victim": 51, - "weapon": "degreaser", - "tick": 51801 - }, - { - "killer": 44, - "assister": 50, - "victim": 54, - "weapon": "machina", - "tick": 52481 - }, - { - "killer": 44, - "assister": null, - "victim": 43, - "weapon": "machina", - "tick": 52817 - }, - { - "killer": 36, - "assister": null, - "victim": 46, - "weapon": "sniperrifle", - "tick": 52849 - }, - { - "killer": 55, - "assister": 39, - "victim": 47, - "weapon": "minigun", - "tick": 52921 - }, - { - "killer": 52, - "assister": null, - "victim": 42, - "weapon": "tomislav", - "tick": 53161 - }, - { - "killer": 44, - "assister": null, - "victim": 56, - "weapon": "machina", - "tick": 53266 - }, - { - "killer": 36, - "assister": null, - "victim": 48, - "weapon": "sniperrifle", - "tick": 53406 - }, - { - "killer": 55, - "assister": 30, - "victim": 45, - "weapon": "minigun", - "tick": 53410 - }, - { - "killer": 32, - "assister": null, - "victim": 50, - "weapon": "quake_rl", - "tick": 53593 - }, - { - "killer": 32, - "assister": null, - "victim": 51, - "weapon": "quake_rl", - "tick": 53717 - }, - { - "killer": 42, - "assister": null, - "victim": 44, - "weapon": "ambassador", - "tick": 53846 - }, - { - "killer": 52, - "assister": null, - "victim": 42, - "weapon": "tomislav", - "tick": 54068 - }, - { - "killer": 54, - "assister": 30, - "victim": 53, - "weapon": "iron_bomber", - "tick": 54109 - }, - { - "killer": 47, - "assister": 46, - "victim": 42, - "weapon": "degreaser", - "tick": 54366 - }, - { - "killer": 36, - "assister": null, - "victim": 52, - "weapon": "sniperrifle", - "tick": 54711 - }, - { - "killer": 56, - "assister": null, - "victim": 51, - "weapon": "flaregun", - "tick": 55863 - }, - { - "killer": 44, - "assister": null, - "victim": 42, - "weapon": "machina", - "tick": 56325 - }, - { - "killer": 44, - "assister": null, - "victim": 32, - "weapon": "machina", - "tick": 56675 - }, - { - "killer": 36, - "assister": null, - "victim": 44, - "weapon": "sniperrifle", - "tick": 56805 - }, - { - "killer": 53, - "assister": null, - "victim": 36, - "weapon": "blackbox", - "tick": 57171 - }, - { - "killer": 56, - "assister": null, - "victim": 46, - "weapon": "world", - "tick": 57371 - }, - { - "killer": 56, - "assister": null, - "victim": 47, - "weapon": "degreaser", - "tick": 57595 - }, - { - "killer": 43, - "assister": null, - "victim": 51, - "weapon": "scattergun", - "tick": 57709 - }, - { - "killer": 43, - "assister": 55, - "victim": 53, - "weapon": "scattergun", - "tick": 57913 - }, - { - "killer": 42, - "assister": null, - "victim": 50, - "weapon": "spy_cicle", - "tick": 58611 - }, - { - "killer": 36, - "assister": null, - "victim": 46, - "weapon": "sniperrifle", - "tick": 59336 - }, - { - "killer": 55, - "assister": 43, - "victim": 45, - "weapon": "minigun", - "tick": 59474 - }, - { - "killer": 44, - "assister": null, - "victim": 42, - "weapon": "machina", - "tick": 59485 - }, - { - "killer": 55, - "assister": 39, - "victim": 53, - "weapon": "minigun", - "tick": 59647 - }, - { - "killer": 43, - "assister": 55, - "victim": 47, - "weapon": "scattergun", - "tick": 59904 - }, - { - "killer": 54, - "assister": null, - "victim": 51, - "weapon": "iron_bomber", - "tick": 59982 - }, - { - "killer": 44, - "assister": null, - "victim": 32, - "weapon": "machina", - "tick": 60275 - }, - { - "killer": 52, - "assister": 44, - "victim": 55, - "weapon": "tomislav", - "tick": 60564 - }, - { - "killer": 36, - "assister": null, - "victim": 52, - "weapon": "sniperrifle", - "tick": 60564 - }, - { - "killer": 45, - "assister": 50, - "victim": 56, - "weapon": "tf_projectile_pipe_remote", - "tick": 60744 - }, - { - "killer": 54, - "assister": 56, - "victim": 50, - "weapon": "tf_projectile_pipe_remote", - "tick": 60888 - }, - { - "killer": 54, - "assister": 36, - "victim": 44, - "weapon": "tf_projectile_pipe_remote", - "tick": 60902 - }, - { - "killer": 45, - "assister": 48, - "victim": 54, - "weapon": "tf_projectile_pipe_remote", - "tick": 61046 - }, - { - "killer": 43, - "assister": null, - "victim": 53, - "weapon": "scattergun", - "tick": 61269 - }, - { - "killer": 53, - "assister": null, - "victim": 42, - "weapon": "blackbox", - "tick": 61295 - }, - { - "killer": 43, - "assister": 36, - "victim": 45, - "weapon": "atomizer", - "tick": 61579 - }, - { - "killer": 43, - "assister": 39, - "victim": 47, - "weapon": "scattergun", - "tick": 61763 - }, - { - "killer": 36, - "assister": 43, - "victim": 48, - "weapon": "sniperrifle", - "tick": 61857 - }, - { - "killer": 39, - "assister": null, - "victim": 46, - "weapon": "obj_minisentry", - "tick": 62221 - } - ] -} \ No newline at end of file + "score": { + "red": 3, + "blue": 0 + }, + "chat": [ + { + "time": 926, + "from": "Foz", + "text": "gg" + }, + { + "time": 769, + "from": "\uff2d\uff41\uff53\uff4f\uff4e\u2727", + "text": "gg" + }, + { + "time": 770, + "from": "Kireek", + "text": "gg" + }, + { + "time": 770, + "from": "Sketis", + "text": "wp" + }, + { + "time": 771, + "from": "Vinegar", + "text": "gg" + }, + { + "time": 771, + "from": "Pendulum", + "text": "gg in chat" + }, + { + "time": 772, + "from": "Icewind | demos.tf", + "text": "gg" + }, + { + "time": 773, + "from": "Solar", + "text": "gg" + }, + { + "time": 775, + "from": "magikarp", + "text": "gg" + } + ], + "players": [ + { + "name": "Icewind | demos.tf", + "demo_user_id": 30, + "steam_id": "[U:1:64229260]", + "team": "red", + "class": "medic" + }, + { + "name": "Foz", + "demo_user_id": 32, + "steam_id": "[U:1:115748435]", + "team": "red", + "class": "soldier" + }, + { + "name": "Chicken Meatballs, FOZ", + "demo_user_id": 36, + "steam_id": "[U:1:115754284]", + "team": "red", + "class": "sniper" + }, + { + "name": "Kireek", + "demo_user_id": 39, + "steam_id": "[U:1:92428736]", + "team": "red", + "class": "engineer" + }, + { + "name": "Vinegar", + "demo_user_id": 42, + "steam_id": "[U:1:22958903]", + "team": "red", + "class": "spy" + }, + { + "name": "[GC]Kimo", + "demo_user_id": 43, + "steam_id": "[U:1:32061783]", + "team": "red", + "class": "scout" + }, + { + "name": "magikarp", + "demo_user_id": 44, + "steam_id": "[U:1:67502510]", + "team": "blue", + "class": "sniper" + }, + { + "name": "Solar", + "demo_user_id": 45, + "steam_id": "[U:1:55128465]", + "team": "blue", + "class": "demoman" + }, + { + "name": "ztreak", + "demo_user_id": 46, + "steam_id": "[U:1:301587080]", + "team": "blue", + "class": "scout" + }, + { + "name": "TheMasterOfDisaster", + "demo_user_id": 47, + "steam_id": "[U:1:22162172]", + "team": "blue", + "class": "pyro" + }, + { + "name": "Sage Luke", + "demo_user_id": 48, + "steam_id": "[U:1:13559571]", + "team": "blue", + "class": "medic" + }, + { + "name": "Sketis", + "demo_user_id": 50, + "steam_id": "[U:1:71706948]", + "team": "blue", + "class": "engineer" + }, + { + "name": "Pyla", + "demo_user_id": 51, + "steam_id": "[U:1:157204170]", + "team": "blue", + "class": "spy" + }, + { + "name": "\uff2d\uff41\uff53\uff4f\uff4e\u2727", + "demo_user_id": 52, + "steam_id": "[U:1:30838206]", + "team": "blue", + "class": "heavyweapons" + }, + { + "name": "\uff52\uff41\uff4e\uff45", + "demo_user_id": 53, + "steam_id": "[U:1:174774002]", + "team": "blue", + "class": "soldier" + }, + { + "name": "Old Billy Riley", + "demo_user_id": 54, + "steam_id": "[U:1:92096346]", + "team": "red", + "class": "demoman" + }, + { + "name": "Pendulum", + "demo_user_id": 55, + "steam_id": "[U:1:143626373]", + "team": "red", + "class": "heavyweapons" + }, + { + "name": "Jedi(fla)master", + "demo_user_id": 56, + "steam_id": "[U:1:30220936]", + "team": "red", + "class": "pyro" + } + ], + "kills": [ + { + "killer": 36, + "assister": null, + "victim": 50, + "weapon": "sniperrifle", + "tick": 10651 + }, + { + "killer": 55, + "assister": null, + "victim": 44, + "weapon": "minigun", + "tick": 10687 + }, + { + "killer": 39, + "assister": null, + "victim": 46, + "weapon": "shotgun_primary", + "tick": 10711 + }, + { + "killer": 32, + "assister": null, + "victim": 45, + "weapon": "quake_rl", + "tick": 10814 + }, + { + "killer": 32, + "assister": null, + "victim": 48, + "weapon": "quake_rl", + "tick": 10814 + }, + { + "killer": 55, + "assister": null, + "victim": 53, + "weapon": "minigun", + "tick": 10834 + }, + { + "killer": 45, + "assister": null, + "victim": 42, + "weapon": "tf_projectile_pipe_remote", + "tick": 12037 + }, + { + "killer": 36, + "assister": 43, + "victim": 46, + "weapon": "sniperrifle", + "tick": 12152 + }, + { + "killer": 44, + "assister": null, + "victim": 56, + "weapon": "machina", + "tick": 12428 + }, + { + "killer": 51, + "assister": null, + "victim": 55, + "weapon": "spy_cicle", + "tick": 12450 + }, + { + "killer": 32, + "assister": 56, + "victim": 53, + "weapon": "quake_rl", + "tick": 12524 + }, + { + "killer": 44, + "assister": null, + "victim": 32, + "weapon": "machina", + "tick": 12736 + }, + { + "killer": 47, + "assister": null, + "victim": 42, + "weapon": "degreaser", + "tick": 12898 + }, + { + "killer": 39, + "assister": null, + "victim": 47, + "weapon": "obj_minisentry", + "tick": 13042 + }, + { + "killer": 51, + "assister": 47, + "victim": 39, + "weapon": "spy_cicle", + "tick": 13096 + }, + { + "killer": 44, + "assister": null, + "victim": 30, + "weapon": "machina", + "tick": 13696 + }, + { + "killer": 54, + "assister": 43, + "victim": 52, + "weapon": "tf_projectile_pipe_remote", + "tick": 13800 + }, + { + "killer": 46, + "assister": 48, + "victim": 42, + "weapon": "scattergun", + "tick": 13992 + }, + { + "killer": 45, + "assister": 48, + "victim": 43, + "weapon": "iron_bomber", + "tick": 14272 + }, + { + "killer": 36, + "assister": null, + "victim": 46, + "weapon": "sniperrifle", + "tick": 14529 + }, + { + "killer": 44, + "assister": 48, + "victim": 56, + "weapon": "machina", + "tick": 14830 + }, + { + "killer": 45, + "assister": null, + "victim": 54, + "weapon": "iron_bomber", + "tick": 14918 + }, + { + "killer": 39, + "assister": null, + "victim": 51, + "weapon": "shotgun_primary", + "tick": 15509 + }, + { + "killer": 42, + "assister": 55, + "victim": 44, + "weapon": "revolver", + "tick": 15738 + }, + { + "killer": 42, + "assister": null, + "victim": 47, + "weapon": "revolver", + "tick": 15900 + }, + { + "killer": 43, + "assister": null, + "victim": 45, + "weapon": "world", + "tick": 15991 + }, + { + "killer": 53, + "assister": 48, + "victim": 42, + "weapon": "blackbox", + "tick": 16105 + }, + { + "killer": 50, + "assister": 46, + "victim": 42, + "weapon": "rescue_ranger", + "tick": 16358 + }, + { + "killer": 54, + "assister": 39, + "victim": 46, + "weapon": "tf_projectile_pipe_remote", + "tick": 16935 + }, + { + "killer": 43, + "assister": 55, + "victim": 52, + "weapon": "scattergun", + "tick": 17825 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 18178 + }, + { + "killer": 53, + "assister": 48, + "victim": 42, + "weapon": "blackbox", + "tick": 18791 + }, + { + "killer": 43, + "assister": 42, + "victim": 44, + "weapon": "scattergun", + "tick": 18936 + }, + { + "killer": 39, + "assister": 43, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 19416 + }, + { + "killer": 36, + "assister": 54, + "victim": 52, + "weapon": "sniperrifle", + "tick": 19736 + }, + { + "killer": 43, + "assister": null, + "victim": 50, + "weapon": "scattergun", + "tick": 20060 + }, + { + "killer": 51, + "assister": null, + "victim": 42, + "weapon": "spy_cicle", + "tick": 20224 + }, + { + "killer": 36, + "assister": null, + "victim": 44, + "weapon": "sniperrifle", + "tick": 20521 + }, + { + "killer": 43, + "assister": 39, + "victim": 47, + "weapon": "scattergun", + "tick": 20730 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 20735 + }, + { + "killer": 50, + "assister": null, + "victim": 42, + "weapon": "obj_minisentry", + "tick": 21844 + }, + { + "killer": 32, + "assister": null, + "victim": 51, + "weapon": "quake_rl", + "tick": 21870 + }, + { + "killer": 45, + "assister": 48, + "victim": 56, + "weapon": "iron_bomber", + "tick": 21896 + }, + { + "killer": 47, + "assister": 50, + "victim": 42, + "weapon": "degreaser", + "tick": 22199 + }, + { + "killer": 53, + "assister": 52, + "victim": 43, + "weapon": "blackbox", + "tick": 22275 + }, + { + "killer": 39, + "assister": 55, + "victim": 53, + "weapon": "shotgun_primary", + "tick": 22464 + }, + { + "killer": 36, + "assister": 54, + "victim": 50, + "weapon": "sniperrifle", + "tick": 22520 + }, + { + "killer": 39, + "assister": 32, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 22631 + }, + { + "killer": 42, + "assister": null, + "victim": 44, + "weapon": "world", + "tick": 22661 + }, + { + "killer": 39, + "assister": 55, + "victim": 47, + "weapon": "obj_minisentry", + "tick": 22835 + }, + { + "killer": 50, + "assister": null, + "victim": 42, + "weapon": "obj_minisentry", + "tick": 22855 + }, + { + "killer": 39, + "assister": 54, + "victim": 45, + "weapon": "shotgun_primary", + "tick": 23389 + }, + { + "killer": 44, + "assister": 46, + "victim": 36, + "weapon": "machina", + "tick": 24391 + }, + { + "killer": 53, + "assister": null, + "victim": 32, + "weapon": "blackbox", + "tick": 25148 + }, + { + "killer": 54, + "assister": 30, + "victim": 46, + "weapon": "tf_projectile_pipe_remote", + "tick": 25196 + }, + { + "killer": 54, + "assister": 30, + "victim": 52, + "weapon": "tf_projectile_pipe_remote", + "tick": 25196 + }, + { + "killer": 56, + "assister": 39, + "victim": 51, + "weapon": "degreaser", + "tick": 25264 + }, + { + "killer": 42, + "assister": null, + "victim": 53, + "weapon": "revolver", + "tick": 25358 + }, + { + "killer": 43, + "assister": 39, + "victim": 47, + "weapon": "scattergun", + "tick": 25397 + }, + { + "killer": 55, + "assister": 30, + "victim": 50, + "weapon": "minigun", + "tick": 25529 + }, + { + "killer": 42, + "assister": null, + "victim": 44, + "weapon": "spy_cicle", + "tick": 26007 + }, + { + "killer": 46, + "assister": 48, + "victim": 42, + "weapon": "scattergun", + "tick": 26411 + }, + { + "killer": 51, + "assister": null, + "victim": 55, + "weapon": "spy_cicle", + "tick": 26848 + }, + { + "killer": 42, + "assister": 39, + "victim": 50, + "weapon": "spy_cicle", + "tick": 27080 + }, + { + "killer": 46, + "assister": null, + "victim": 42, + "weapon": "scattergun", + "tick": 27450 + }, + { + "killer": 43, + "assister": 39, + "victim": 53, + "weapon": "scattergun", + "tick": 27955 + }, + { + "killer": 32, + "assister": 39, + "victim": 47, + "weapon": "quake_rl", + "tick": 28013 + }, + { + "killer": 44, + "assister": null, + "victim": 39, + "weapon": "machina", + "tick": 28049 + }, + { + "killer": 50, + "assister": null, + "victim": 42, + "weapon": "shotgun_primary", + "tick": 28311 + }, + { + "killer": 56, + "assister": null, + "victim": 51, + "weapon": "degreaser", + "tick": 28390 + }, + { + "killer": 54, + "assister": 32, + "victim": 46, + "weapon": "tf_projectile_pipe_remote", + "tick": 28889 + }, + { + "killer": 32, + "assister": 54, + "victim": 48, + "weapon": "quake_rl", + "tick": 28896 + }, + { + "killer": 30, + "assister": null, + "victim": 45, + "weapon": "crusaders_crossbow", + "tick": 28970 + }, + { + "killer": 54, + "assister": null, + "victim": 52, + "weapon": "iron_bomber", + "tick": 28980 + }, + { + "killer": 50, + "assister": 52, + "victim": 32, + "weapon": "obj_minisentry", + "tick": 29040 + }, + { + "killer": 44, + "assister": 50, + "victim": 56, + "weapon": "machina", + "tick": 29090 + }, + { + "killer": 43, + "assister": 56, + "victim": 50, + "weapon": "scattergun", + "tick": 29314 + }, + { + "killer": 44, + "assister": null, + "victim": 56, + "weapon": "machina", + "tick": 31127 + }, + { + "killer": 32, + "assister": 43, + "victim": 47, + "weapon": "quake_rl", + "tick": 31559 + }, + { + "killer": 51, + "assister": null, + "victim": 55, + "weapon": "kunai", + "tick": 31673 + }, + { + "killer": 42, + "assister": null, + "victim": 52, + "weapon": "kunai", + "tick": 31675 + }, + { + "killer": 44, + "assister": 52, + "victim": 32, + "weapon": "machina", + "tick": 31717 + }, + { + "killer": 43, + "assister": 32, + "victim": 53, + "weapon": "scattergun", + "tick": 31726 + }, + { + "killer": 53, + "assister": null, + "victim": 43, + "weapon": "blackbox", + "tick": 31730 + }, + { + "killer": 54, + "assister": 39, + "victim": 50, + "weapon": "iron_bomber", + "tick": 31839 + }, + { + "killer": 36, + "assister": null, + "victim": 46, + "weapon": "sniperrifle", + "tick": 32125 + }, + { + "killer": 44, + "assister": 48, + "victim": 39, + "weapon": "machina", + "tick": 32651 + }, + { + "killer": 54, + "assister": null, + "victim": 45, + "weapon": "iron_bomber", + "tick": 32811 + }, + { + "killer": 42, + "assister": null, + "victim": 48, + "weapon": "letranger", + "tick": 33017 + }, + { + "killer": 56, + "assister": 43, + "victim": 51, + "weapon": "flaregun", + "tick": 33061 + }, + { + "killer": 54, + "assister": null, + "victim": 44, + "weapon": "iron_bomber", + "tick": 33203 + }, + { + "killer": 50, + "assister": 47, + "victim": 42, + "weapon": "shotgun_primary", + "tick": 34179 + }, + { + "killer": 36, + "assister": null, + "victim": 44, + "weapon": "sniperrifle", + "tick": 34920 + }, + { + "killer": 32, + "assister": null, + "victim": 51, + "weapon": "quake_rl", + "tick": 35322 + }, + { + "killer": 54, + "assister": 30, + "victim": 46, + "weapon": "iron_bomber", + "tick": 35465 + }, + { + "killer": 32, + "assister": 39, + "victim": 53, + "weapon": "quake_rl", + "tick": 36017 + }, + { + "killer": 39, + "assister": 55, + "victim": 47, + "weapon": "shotgun_primary", + "tick": 36265 + }, + { + "killer": 54, + "assister": 36, + "victim": 52, + "weapon": "tf_projectile_pipe_remote", + "tick": 36441 + }, + { + "killer": 42, + "assister": null, + "victim": 44, + "weapon": "kunai", + "tick": 36717 + }, + { + "killer": 54, + "assister": 55, + "victim": 50, + "weapon": "tf_projectile_pipe_remote", + "tick": 37567 + }, + { + "killer": 51, + "assister": null, + "victim": 32, + "weapon": "kunai", + "tick": 37571 + }, + { + "killer": 51, + "assister": null, + "victim": 30, + "weapon": "kunai", + "tick": 38117 + }, + { + "killer": 44, + "assister": null, + "victim": 42, + "weapon": "machina", + "tick": 38131 + }, + { + "killer": 54, + "assister": 43, + "victim": 51, + "weapon": "tf_projectile_pipe_remote", + "tick": 38255 + }, + { + "killer": 46, + "assister": null, + "victim": 55, + "weapon": "scattergun", + "tick": 38683 + }, + { + "killer": 43, + "assister": 54, + "victim": 52, + "weapon": "scattergun", + "tick": 38703 + }, + { + "killer": 39, + "assister": 55, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 38787 + }, + { + "killer": 44, + "assister": null, + "victim": 54, + "weapon": "machina", + "tick": 38797 + }, + { + "killer": 45, + "assister": 48, + "victim": 43, + "weapon": "tf_projectile_pipe_remote", + "tick": 38809 + }, + { + "killer": 32, + "assister": null, + "victim": 45, + "weapon": "quake_rl", + "tick": 39291 + }, + { + "killer": 56, + "assister": null, + "victim": 44, + "weapon": "flaregun", + "tick": 39351 + }, + { + "killer": 56, + "assister": null, + "victim": 48, + "weapon": "flaregun", + "tick": 39591 + }, + { + "killer": 36, + "assister": 32, + "victim": 47, + "weapon": "sniperrifle", + "tick": 39611 + }, + { + "killer": 56, + "assister": null, + "victim": 51, + "weapon": "degreaser", + "tick": 39747 + }, + { + "killer": 53, + "assister": null, + "victim": 56, + "weapon": "blackbox", + "tick": 39753 + }, + { + "killer": 36, + "assister": null, + "victim": 50, + "weapon": "sniperrifle", + "tick": 39775 + }, + { + "killer": 53, + "assister": null, + "victim": 32, + "weapon": "blackbox", + "tick": 40053 + }, + { + "killer": 39, + "assister": 55, + "victim": 53, + "weapon": "shotgun_primary", + "tick": 40183 + }, + { + "killer": 36, + "assister": 30, + "victim": 44, + "weapon": "sniperrifle", + "tick": 41360 + }, + { + "killer": 42, + "assister": 39, + "victim": 50, + "weapon": "kunai", + "tick": 41393 + }, + { + "killer": 55, + "assister": null, + "victim": 51, + "weapon": "minigun", + "tick": 41761 + }, + { + "killer": 36, + "assister": 54, + "victim": 47, + "weapon": "sniperrifle", + "tick": 42213 + }, + { + "killer": 45, + "assister": 52, + "victim": 42, + "weapon": "tf_projectile_pipe_remote", + "tick": 42481 + }, + { + "killer": 43, + "assister": null, + "victim": 53, + "weapon": "scattergun", + "tick": 42735 + }, + { + "killer": 36, + "assister": null, + "victim": 44, + "weapon": "sniperrifle", + "tick": 42884 + }, + { + "killer": 43, + "assister": null, + "victim": 46, + "weapon": "scattergun", + "tick": 42912 + }, + { + "killer": 43, + "assister": 32, + "victim": 51, + "weapon": "scattergun", + "tick": 43261 + }, + { + "killer": 42, + "assister": null, + "victim": 47, + "weapon": "kunai", + "tick": 44809 + }, + { + "killer": 36, + "assister": 30, + "victim": 52, + "weapon": "sniperrifle", + "tick": 44963 + }, + { + "killer": 54, + "assister": 30, + "victim": 48, + "weapon": "tf_projectile_pipe_remote", + "tick": 45381 + }, + { + "killer": 55, + "assister": 36, + "victim": 50, + "weapon": "minigun", + "tick": 45381 + }, + { + "killer": 51, + "assister": 50, + "victim": 56, + "weapon": "kunai", + "tick": 45551 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 45651 + }, + { + "killer": 45, + "assister": 50, + "victim": 32, + "weapon": "iron_bomber", + "tick": 45665 + }, + { + "killer": 32, + "assister": null, + "victim": 45, + "weapon": "quake_rl", + "tick": 45667 + }, + { + "killer": 39, + "assister": 43, + "victim": 51, + "weapon": "shotgun_primary", + "tick": 45729 + }, + { + "killer": 39, + "assister": 43, + "victim": 53, + "weapon": "obj_minisentry", + "tick": 45865 + }, + { + "killer": 39, + "assister": null, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 46049 + }, + { + "killer": 54, + "assister": 43, + "victim": 45, + "weapon": "tf_projectile_pipe_remote", + "tick": 47557 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 47775 + }, + { + "killer": 48, + "assister": null, + "victim": 32, + "weapon": "crusaders_crossbow", + "tick": 47827 + }, + { + "killer": 54, + "assister": 55, + "victim": 47, + "weapon": "iron_bomber", + "tick": 47953 + }, + { + "killer": 39, + "assister": 56, + "victim": 51, + "weapon": "shotgun_primary", + "tick": 47991 + }, + { + "killer": 52, + "assister": null, + "victim": 54, + "weapon": "tomislav", + "tick": 48053 + }, + { + "killer": 36, + "assister": null, + "victim": 52, + "weapon": "sniperrifle", + "tick": 48437 + }, + { + "killer": 43, + "assister": null, + "victim": 46, + "weapon": "scattergun", + "tick": 48509 + }, + { + "killer": 39, + "assister": 56, + "victim": 50, + "weapon": "obj_minisentry", + "tick": 48527 + }, + { + "killer": 44, + "assister": 48, + "victim": 36, + "weapon": "machina", + "tick": 48607 + }, + { + "killer": 39, + "assister": 43, + "victim": 53, + "weapon": "obj_minisentry", + "tick": 48773 + }, + { + "killer": 48, + "assister": null, + "victim": 43, + "weapon": "crusaders_crossbow", + "tick": 49049 + }, + { + "killer": 44, + "assister": 48, + "victim": 39, + "weapon": "machina", + "tick": 49121 + }, + { + "killer": 42, + "assister": 55, + "victim": 47, + "weapon": "kunai", + "tick": 49923 + }, + { + "killer": 32, + "assister": 55, + "victim": 44, + "weapon": "quake_rl", + "tick": 50659 + }, + { + "killer": 51, + "assister": null, + "victim": 55, + "weapon": "kunai", + "tick": 50825 + }, + { + "killer": 42, + "assister": null, + "victim": 45, + "weapon": "kunai", + "tick": 50845 + }, + { + "killer": 46, + "assister": 48, + "victim": 42, + "weapon": "scattergun", + "tick": 51071 + }, + { + "killer": 36, + "assister": null, + "victim": 52, + "weapon": "sniperrifle", + "tick": 51293 + }, + { + "killer": 56, + "assister": null, + "victim": 51, + "weapon": "degreaser", + "tick": 51801 + }, + { + "killer": 44, + "assister": 50, + "victim": 54, + "weapon": "machina", + "tick": 52481 + }, + { + "killer": 44, + "assister": null, + "victim": 43, + "weapon": "machina", + "tick": 52817 + }, + { + "killer": 36, + "assister": null, + "victim": 46, + "weapon": "sniperrifle", + "tick": 52849 + }, + { + "killer": 55, + "assister": 39, + "victim": 47, + "weapon": "minigun", + "tick": 52921 + }, + { + "killer": 52, + "assister": null, + "victim": 42, + "weapon": "tomislav", + "tick": 53161 + }, + { + "killer": 44, + "assister": null, + "victim": 56, + "weapon": "machina", + "tick": 53266 + }, + { + "killer": 36, + "assister": null, + "victim": 48, + "weapon": "sniperrifle", + "tick": 53406 + }, + { + "killer": 55, + "assister": 30, + "victim": 45, + "weapon": "minigun", + "tick": 53410 + }, + { + "killer": 32, + "assister": null, + "victim": 50, + "weapon": "quake_rl", + "tick": 53593 + }, + { + "killer": 32, + "assister": null, + "victim": 51, + "weapon": "quake_rl", + "tick": 53717 + }, + { + "killer": 42, + "assister": null, + "victim": 44, + "weapon": "ambassador", + "tick": 53846 + }, + { + "killer": 52, + "assister": null, + "victim": 42, + "weapon": "tomislav", + "tick": 54068 + }, + { + "killer": 54, + "assister": 30, + "victim": 53, + "weapon": "iron_bomber", + "tick": 54109 + }, + { + "killer": 47, + "assister": 46, + "victim": 42, + "weapon": "degreaser", + "tick": 54366 + }, + { + "killer": 36, + "assister": null, + "victim": 52, + "weapon": "sniperrifle", + "tick": 54711 + }, + { + "killer": 56, + "assister": null, + "victim": 51, + "weapon": "flaregun", + "tick": 55863 + }, + { + "killer": 44, + "assister": null, + "victim": 42, + "weapon": "machina", + "tick": 56325 + }, + { + "killer": 44, + "assister": null, + "victim": 32, + "weapon": "machina", + "tick": 56675 + }, + { + "killer": 36, + "assister": null, + "victim": 44, + "weapon": "sniperrifle", + "tick": 56805 + }, + { + "killer": 53, + "assister": null, + "victim": 36, + "weapon": "blackbox", + "tick": 57171 + }, + { + "killer": 56, + "assister": null, + "victim": 46, + "weapon": "world", + "tick": 57371 + }, + { + "killer": 56, + "assister": null, + "victim": 47, + "weapon": "degreaser", + "tick": 57595 + }, + { + "killer": 43, + "assister": null, + "victim": 51, + "weapon": "scattergun", + "tick": 57709 + }, + { + "killer": 43, + "assister": 55, + "victim": 53, + "weapon": "scattergun", + "tick": 57913 + }, + { + "killer": 42, + "assister": null, + "victim": 50, + "weapon": "spy_cicle", + "tick": 58611 + }, + { + "killer": 36, + "assister": null, + "victim": 46, + "weapon": "sniperrifle", + "tick": 59336 + }, + { + "killer": 55, + "assister": 43, + "victim": 45, + "weapon": "minigun", + "tick": 59474 + }, + { + "killer": 44, + "assister": null, + "victim": 42, + "weapon": "machina", + "tick": 59485 + }, + { + "killer": 55, + "assister": 39, + "victim": 53, + "weapon": "minigun", + "tick": 59647 + }, + { + "killer": 43, + "assister": 55, + "victim": 47, + "weapon": "scattergun", + "tick": 59904 + }, + { + "killer": 54, + "assister": null, + "victim": 51, + "weapon": "iron_bomber", + "tick": 59982 + }, + { + "killer": 44, + "assister": null, + "victim": 32, + "weapon": "machina", + "tick": 60275 + }, + { + "killer": 52, + "assister": 44, + "victim": 55, + "weapon": "tomislav", + "tick": 60564 + }, + { + "killer": 36, + "assister": null, + "victim": 52, + "weapon": "sniperrifle", + "tick": 60564 + }, + { + "killer": 45, + "assister": 50, + "victim": 56, + "weapon": "tf_projectile_pipe_remote", + "tick": 60744 + }, + { + "killer": 54, + "assister": 56, + "victim": 50, + "weapon": "tf_projectile_pipe_remote", + "tick": 60888 + }, + { + "killer": 54, + "assister": 36, + "victim": 44, + "weapon": "tf_projectile_pipe_remote", + "tick": 60902 + }, + { + "killer": 45, + "assister": 48, + "victim": 54, + "weapon": "tf_projectile_pipe_remote", + "tick": 61046 + }, + { + "killer": 43, + "assister": null, + "victim": 53, + "weapon": "scattergun", + "tick": 61269 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 61295 + }, + { + "killer": 43, + "assister": 36, + "victim": 45, + "weapon": "atomizer", + "tick": 61579 + }, + { + "killer": 43, + "assister": 39, + "victim": 47, + "weapon": "scattergun", + "tick": 61763 + }, + { + "killer": 36, + "assister": 43, + "victim": 48, + "weapon": "sniperrifle", + "tick": 61857 + }, + { + "killer": 39, + "assister": null, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 62221 + } + ] +} diff --git a/test/data/product-raw.json b/test/data/product-raw.json index f0a88d8..5ec1dc0 100644 --- a/test/data/product-raw.json +++ b/test/data/product-raw.json @@ -1 +1,1598 @@ -{"chat":[{"kind":"TF_Chat_All","from":"Foz","text":"gg","tick":61747},{"kind":"TF_Chat_All","from":"Mason✧","text":"gg","tick":61871},{"kind":"TF_Chat_All","from":"Kireek","text":"gg","tick":61959},{"kind":"TF_Chat_All","from":"Sketis","text":"wp","tick":61963},{"kind":"TF_Chat_All","from":"Vinegar","text":"gg","tick":61999},{"kind":"TF_Chat_All","from":"Pendulum","text":"gg in chat","tick":62043},{"kind":"TF_Chat_All","from":"Icewind | demos.tf","text":"gg","tick":62075},{"kind":"TF_Chat_All","from":"Solar","text":"gg","tick":62167},{"kind":"TF_Chat_All","from":"magikarp","text":"gg","tick":62281}],"users":{"18":{"classes":{},"name":"UGC Highlander Match TV","steamId":"BOT","userId":18},"30":{"classes":{"5":6},"name":"Icewind | demos.tf","steamId":"[U:1:64229260]","userId":30,"team":"red"},"32":{"classes":{"3":12},"name":"Foz","steamId":"[U:1:115748435]","userId":32,"team":"red"},"36":{"classes":{"2":7},"name":"Chicken Meatballs, FOZ","steamId":"[U:1:115754284]","userId":36,"team":"red"},"39":{"classes":{"9":8},"name":"Kireek","steamId":"[U:1:92428736]","userId":39,"team":"red"},"42":{"classes":{"8":15},"name":"Vinegar","steamId":"[U:1:22958903]","userId":42,"team":"red"},"43":{"classes":{"1":10},"name":"[GC]Kimo","steamId":"[U:1:32061783]","userId":43,"team":"red"},"44":{"classes":{"2":19},"name":"magikarp","steamId":"[U:1:67502510]","userId":44,"team":"blue"},"45":{"classes":{"4":12},"name":"Solar","steamId":"[U:1:55128465]","userId":45,"team":"blue"},"46":{"classes":{"1":18},"name":"ztreak","steamId":"[U:1:301587080]","userId":46,"team":"blue"},"47":{"classes":{"7":21},"name":"TheMasterOfDisaster","steamId":"[U:1:22162172]","userId":47,"team":"blue"},"48":{"classes":{"5":7},"name":"Sage Luke","steamId":"[U:1:13559571]","userId":48,"team":"blue"},"50":{"classes":{"9":18},"name":"Sketis","steamId":"[U:1:71706948]","userId":50,"team":"blue"},"51":{"classes":{"8":20},"name":"Pyla","steamId":"[U:1:157204170]","userId":51,"team":"blue"},"52":{"classes":{"6":16},"name":"Mason✧","steamId":"[U:1:30838206]","userId":52,"team":"blue"},"53":{"classes":{"3":16},"name":"rane","steamId":"[U:1:174774002]","userId":53,"team":"blue"},"54":{"classes":{"4":8},"name":"Old Billy Riley","steamId":"[U:1:92096346]","userId":54,"team":"red"},"55":{"classes":{"6":10},"name":"Pendulum","steamId":"[U:1:143626373]","userId":55,"team":"red"},"56":{"classes":{"7":10},"name":"Jedi(fla)master","steamId":"[U:1:30220936]","userId":56,"team":"red"}},"deaths":[{"killer":36,"assister":null,"victim":50,"weapon":"sniperrifle","tick":10651},{"killer":55,"assister":null,"victim":44,"weapon":"minigun","tick":10687},{"killer":39,"assister":null,"victim":46,"weapon":"shotgun_primary","tick":10711},{"killer":32,"assister":null,"victim":45,"weapon":"quake_rl","tick":10814},{"killer":32,"assister":null,"victim":48,"weapon":"quake_rl","tick":10814},{"killer":55,"assister":null,"victim":53,"weapon":"minigun","tick":10834},{"killer":45,"assister":null,"victim":42,"weapon":"tf_projectile_pipe_remote","tick":12037},{"killer":36,"assister":43,"victim":46,"weapon":"sniperrifle","tick":12152},{"killer":44,"assister":null,"victim":56,"weapon":"machina","tick":12428},{"killer":51,"assister":null,"victim":55,"weapon":"spy_cicle","tick":12450},{"killer":32,"assister":56,"victim":53,"weapon":"quake_rl","tick":12524},{"killer":44,"assister":null,"victim":32,"weapon":"machina","tick":12736},{"killer":47,"assister":null,"victim":42,"weapon":"degreaser","tick":12898},{"killer":39,"assister":null,"victim":47,"weapon":"obj_minisentry","tick":13042},{"killer":51,"assister":47,"victim":39,"weapon":"spy_cicle","tick":13096},{"killer":44,"assister":null,"victim":30,"weapon":"machina","tick":13696},{"killer":54,"assister":43,"victim":52,"weapon":"tf_projectile_pipe_remote","tick":13800},{"killer":46,"assister":48,"victim":42,"weapon":"scattergun","tick":13992},{"killer":45,"assister":48,"victim":43,"weapon":"iron_bomber","tick":14272},{"killer":36,"assister":null,"victim":46,"weapon":"sniperrifle","tick":14529},{"killer":44,"assister":48,"victim":56,"weapon":"machina","tick":14830},{"killer":45,"assister":null,"victim":54,"weapon":"iron_bomber","tick":14918},{"killer":39,"assister":null,"victim":51,"weapon":"shotgun_primary","tick":15509},{"killer":42,"assister":55,"victim":44,"weapon":"revolver","tick":15738},{"killer":42,"assister":null,"victim":47,"weapon":"revolver","tick":15900},{"killer":43,"assister":null,"victim":45,"weapon":"world","tick":15991},{"killer":53,"assister":48,"victim":42,"weapon":"blackbox","tick":16105},{"killer":50,"assister":46,"victim":42,"weapon":"rescue_ranger","tick":16358},{"killer":54,"assister":39,"victim":46,"weapon":"tf_projectile_pipe_remote","tick":16935},{"killer":43,"assister":55,"victim":52,"weapon":"scattergun","tick":17825},{"killer":53,"assister":null,"victim":42,"weapon":"blackbox","tick":18178},{"killer":53,"assister":48,"victim":42,"weapon":"blackbox","tick":18791},{"killer":43,"assister":42,"victim":44,"weapon":"scattergun","tick":18936},{"killer":39,"assister":43,"victim":46,"weapon":"obj_minisentry","tick":19416},{"killer":36,"assister":54,"victim":52,"weapon":"sniperrifle","tick":19736},{"killer":43,"assister":null,"victim":50,"weapon":"scattergun","tick":20060},{"killer":51,"assister":null,"victim":42,"weapon":"spy_cicle","tick":20224},{"killer":36,"assister":null,"victim":44,"weapon":"sniperrifle","tick":20521},{"killer":43,"assister":39,"victim":47,"weapon":"scattergun","tick":20730},{"killer":53,"assister":null,"victim":42,"weapon":"blackbox","tick":20735},{"killer":50,"assister":null,"victim":42,"weapon":"obj_minisentry","tick":21844},{"killer":32,"assister":null,"victim":51,"weapon":"quake_rl","tick":21870},{"killer":45,"assister":48,"victim":56,"weapon":"iron_bomber","tick":21896},{"killer":47,"assister":50,"victim":42,"weapon":"degreaser","tick":22199},{"killer":53,"assister":52,"victim":43,"weapon":"blackbox","tick":22275},{"killer":39,"assister":55,"victim":53,"weapon":"shotgun_primary","tick":22464},{"killer":36,"assister":54,"victim":50,"weapon":"sniperrifle","tick":22520},{"killer":39,"assister":32,"victim":46,"weapon":"obj_minisentry","tick":22631},{"killer":42,"assister":null,"victim":44,"weapon":"world","tick":22661},{"killer":39,"assister":55,"victim":47,"weapon":"obj_minisentry","tick":22835},{"killer":50,"assister":null,"victim":42,"weapon":"obj_minisentry","tick":22855},{"killer":39,"assister":54,"victim":45,"weapon":"shotgun_primary","tick":23389},{"killer":44,"assister":46,"victim":36,"weapon":"machina","tick":24391},{"killer":53,"assister":null,"victim":32,"weapon":"blackbox","tick":25148},{"killer":54,"assister":30,"victim":46,"weapon":"tf_projectile_pipe_remote","tick":25196},{"killer":54,"assister":30,"victim":52,"weapon":"tf_projectile_pipe_remote","tick":25196},{"killer":56,"assister":39,"victim":51,"weapon":"degreaser","tick":25264},{"killer":42,"assister":null,"victim":53,"weapon":"revolver","tick":25358},{"killer":43,"assister":39,"victim":47,"weapon":"scattergun","tick":25397},{"killer":55,"assister":30,"victim":50,"weapon":"minigun","tick":25529},{"killer":42,"assister":null,"victim":44,"weapon":"spy_cicle","tick":26007},{"killer":46,"assister":48,"victim":42,"weapon":"scattergun","tick":26411},{"killer":51,"assister":null,"victim":55,"weapon":"spy_cicle","tick":26848},{"killer":42,"assister":39,"victim":50,"weapon":"spy_cicle","tick":27080},{"killer":46,"assister":null,"victim":42,"weapon":"scattergun","tick":27450},{"killer":43,"assister":39,"victim":53,"weapon":"scattergun","tick":27955},{"killer":32,"assister":39,"victim":47,"weapon":"quake_rl","tick":28013},{"killer":44,"assister":null,"victim":39,"weapon":"machina","tick":28049},{"killer":50,"assister":null,"victim":42,"weapon":"shotgun_primary","tick":28311},{"killer":56,"assister":null,"victim":51,"weapon":"degreaser","tick":28390},{"killer":54,"assister":32,"victim":46,"weapon":"tf_projectile_pipe_remote","tick":28889},{"killer":32,"assister":54,"victim":48,"weapon":"quake_rl","tick":28896},{"killer":30,"assister":null,"victim":45,"weapon":"crusaders_crossbow","tick":28970},{"killer":54,"assister":null,"victim":52,"weapon":"iron_bomber","tick":28980},{"killer":50,"assister":52,"victim":32,"weapon":"obj_minisentry","tick":29040},{"killer":44,"assister":50,"victim":56,"weapon":"machina","tick":29090},{"killer":43,"assister":56,"victim":50,"weapon":"scattergun","tick":29314},{"killer":44,"assister":null,"victim":56,"weapon":"machina","tick":31127},{"killer":32,"assister":43,"victim":47,"weapon":"quake_rl","tick":31559},{"killer":51,"assister":null,"victim":55,"weapon":"kunai","tick":31673},{"killer":42,"assister":null,"victim":52,"weapon":"kunai","tick":31675},{"killer":44,"assister":52,"victim":32,"weapon":"machina","tick":31717},{"killer":43,"assister":32,"victim":53,"weapon":"scattergun","tick":31726},{"killer":53,"assister":null,"victim":43,"weapon":"blackbox","tick":31730},{"killer":54,"assister":39,"victim":50,"weapon":"iron_bomber","tick":31839},{"killer":36,"assister":null,"victim":46,"weapon":"sniperrifle","tick":32125},{"killer":44,"assister":48,"victim":39,"weapon":"machina","tick":32651},{"killer":54,"assister":null,"victim":45,"weapon":"iron_bomber","tick":32811},{"killer":42,"assister":null,"victim":48,"weapon":"letranger","tick":33017},{"killer":56,"assister":43,"victim":51,"weapon":"flaregun","tick":33061},{"killer":54,"assister":null,"victim":44,"weapon":"iron_bomber","tick":33203},{"killer":50,"assister":47,"victim":42,"weapon":"shotgun_primary","tick":34179},{"killer":36,"assister":null,"victim":44,"weapon":"sniperrifle","tick":34920},{"killer":32,"assister":null,"victim":51,"weapon":"quake_rl","tick":35322},{"killer":54,"assister":30,"victim":46,"weapon":"iron_bomber","tick":35465},{"killer":32,"assister":39,"victim":53,"weapon":"quake_rl","tick":36017},{"killer":39,"assister":55,"victim":47,"weapon":"shotgun_primary","tick":36265},{"killer":54,"assister":36,"victim":52,"weapon":"tf_projectile_pipe_remote","tick":36441},{"killer":42,"assister":null,"victim":44,"weapon":"kunai","tick":36717},{"killer":54,"assister":55,"victim":50,"weapon":"tf_projectile_pipe_remote","tick":37567},{"killer":51,"assister":null,"victim":32,"weapon":"kunai","tick":37571},{"killer":51,"assister":null,"victim":30,"weapon":"kunai","tick":38117},{"killer":44,"assister":null,"victim":42,"weapon":"machina","tick":38131},{"killer":54,"assister":43,"victim":51,"weapon":"tf_projectile_pipe_remote","tick":38255},{"killer":46,"assister":null,"victim":55,"weapon":"scattergun","tick":38683},{"killer":43,"assister":54,"victim":52,"weapon":"scattergun","tick":38703},{"killer":39,"assister":55,"victim":46,"weapon":"obj_minisentry","tick":38787},{"killer":44,"assister":null,"victim":54,"weapon":"machina","tick":38797},{"killer":45,"assister":48,"victim":43,"weapon":"tf_projectile_pipe_remote","tick":38809},{"killer":32,"assister":null,"victim":45,"weapon":"quake_rl","tick":39291},{"killer":56,"assister":null,"victim":44,"weapon":"flaregun","tick":39351},{"killer":56,"assister":null,"victim":48,"weapon":"flaregun","tick":39591},{"killer":36,"assister":32,"victim":47,"weapon":"sniperrifle","tick":39611},{"killer":56,"assister":null,"victim":51,"weapon":"degreaser","tick":39747},{"killer":53,"assister":null,"victim":56,"weapon":"blackbox","tick":39753},{"killer":36,"assister":null,"victim":50,"weapon":"sniperrifle","tick":39775},{"killer":53,"assister":null,"victim":32,"weapon":"blackbox","tick":40053},{"killer":39,"assister":55,"victim":53,"weapon":"shotgun_primary","tick":40183},{"killer":36,"assister":30,"victim":44,"weapon":"sniperrifle","tick":41360},{"killer":42,"assister":39,"victim":50,"weapon":"kunai","tick":41393},{"killer":55,"assister":null,"victim":51,"weapon":"minigun","tick":41761},{"killer":36,"assister":54,"victim":47,"weapon":"sniperrifle","tick":42213},{"killer":45,"assister":52,"victim":42,"weapon":"tf_projectile_pipe_remote","tick":42481},{"killer":43,"assister":null,"victim":53,"weapon":"scattergun","tick":42735},{"killer":36,"assister":null,"victim":44,"weapon":"sniperrifle","tick":42884},{"killer":43,"assister":null,"victim":46,"weapon":"scattergun","tick":42912},{"killer":43,"assister":32,"victim":51,"weapon":"scattergun","tick":43261},{"killer":42,"assister":null,"victim":47,"weapon":"kunai","tick":44809},{"killer":36,"assister":30,"victim":52,"weapon":"sniperrifle","tick":44963},{"killer":54,"assister":30,"victim":48,"weapon":"tf_projectile_pipe_remote","tick":45381},{"killer":55,"assister":36,"victim":50,"weapon":"minigun","tick":45381},{"killer":51,"assister":50,"victim":56,"weapon":"kunai","tick":45551},{"killer":53,"assister":null,"victim":42,"weapon":"blackbox","tick":45651},{"killer":45,"assister":50,"victim":32,"weapon":"iron_bomber","tick":45665},{"killer":32,"assister":null,"victim":45,"weapon":"quake_rl","tick":45667},{"killer":39,"assister":43,"victim":51,"weapon":"shotgun_primary","tick":45729},{"killer":39,"assister":43,"victim":53,"weapon":"obj_minisentry","tick":45865},{"killer":39,"assister":null,"victim":46,"weapon":"obj_minisentry","tick":46049},{"killer":54,"assister":43,"victim":45,"weapon":"tf_projectile_pipe_remote","tick":47557},{"killer":53,"assister":null,"victim":42,"weapon":"blackbox","tick":47775},{"killer":48,"assister":null,"victim":32,"weapon":"crusaders_crossbow","tick":47827},{"killer":54,"assister":55,"victim":47,"weapon":"iron_bomber","tick":47953},{"killer":39,"assister":56,"victim":51,"weapon":"shotgun_primary","tick":47991},{"killer":52,"assister":null,"victim":54,"weapon":"tomislav","tick":48053},{"killer":36,"assister":null,"victim":52,"weapon":"sniperrifle","tick":48437},{"killer":43,"assister":null,"victim":46,"weapon":"scattergun","tick":48509},{"killer":39,"assister":56,"victim":50,"weapon":"obj_minisentry","tick":48527},{"killer":44,"assister":48,"victim":36,"weapon":"machina","tick":48607},{"killer":39,"assister":43,"victim":53,"weapon":"obj_minisentry","tick":48773},{"killer":48,"assister":null,"victim":43,"weapon":"crusaders_crossbow","tick":49049},{"killer":44,"assister":48,"victim":39,"weapon":"machina","tick":49121},{"killer":42,"assister":55,"victim":47,"weapon":"kunai","tick":49923},{"killer":32,"assister":55,"victim":44,"weapon":"quake_rl","tick":50659},{"killer":51,"assister":null,"victim":55,"weapon":"kunai","tick":50825},{"killer":42,"assister":null,"victim":45,"weapon":"kunai","tick":50845},{"killer":46,"assister":48,"victim":42,"weapon":"scattergun","tick":51071},{"killer":36,"assister":null,"victim":52,"weapon":"sniperrifle","tick":51293},{"killer":56,"assister":null,"victim":51,"weapon":"degreaser","tick":51801},{"killer":44,"assister":50,"victim":54,"weapon":"machina","tick":52481},{"killer":44,"assister":null,"victim":43,"weapon":"machina","tick":52817},{"killer":36,"assister":null,"victim":46,"weapon":"sniperrifle","tick":52849},{"killer":55,"assister":39,"victim":47,"weapon":"minigun","tick":52921},{"killer":52,"assister":null,"victim":42,"weapon":"tomislav","tick":53161},{"killer":44,"assister":null,"victim":56,"weapon":"machina","tick":53266},{"killer":36,"assister":null,"victim":48,"weapon":"sniperrifle","tick":53406},{"killer":55,"assister":30,"victim":45,"weapon":"minigun","tick":53410},{"killer":32,"assister":null,"victim":50,"weapon":"quake_rl","tick":53593},{"killer":32,"assister":null,"victim":51,"weapon":"quake_rl","tick":53717},{"killer":42,"assister":null,"victim":44,"weapon":"ambassador","tick":53846},{"killer":52,"assister":null,"victim":42,"weapon":"tomislav","tick":54068},{"killer":54,"assister":30,"victim":53,"weapon":"iron_bomber","tick":54109},{"killer":47,"assister":46,"victim":42,"weapon":"degreaser","tick":54366},{"killer":36,"assister":null,"victim":52,"weapon":"sniperrifle","tick":54711},{"killer":56,"assister":null,"victim":51,"weapon":"flaregun","tick":55863},{"killer":44,"assister":null,"victim":42,"weapon":"machina","tick":56325},{"killer":44,"assister":null,"victim":32,"weapon":"machina","tick":56675},{"killer":36,"assister":null,"victim":44,"weapon":"sniperrifle","tick":56805},{"killer":53,"assister":null,"victim":36,"weapon":"blackbox","tick":57171},{"killer":56,"assister":null,"victim":46,"weapon":"world","tick":57371},{"killer":56,"assister":null,"victim":47,"weapon":"degreaser","tick":57595},{"killer":43,"assister":null,"victim":51,"weapon":"scattergun","tick":57709},{"killer":43,"assister":55,"victim":53,"weapon":"scattergun","tick":57913},{"killer":42,"assister":null,"victim":50,"weapon":"spy_cicle","tick":58611},{"killer":36,"assister":null,"victim":46,"weapon":"sniperrifle","tick":59336},{"killer":55,"assister":43,"victim":45,"weapon":"minigun","tick":59474},{"killer":44,"assister":null,"victim":42,"weapon":"machina","tick":59485},{"killer":55,"assister":39,"victim":53,"weapon":"minigun","tick":59647},{"killer":43,"assister":55,"victim":47,"weapon":"scattergun","tick":59904},{"killer":54,"assister":null,"victim":51,"weapon":"iron_bomber","tick":59982},{"killer":44,"assister":null,"victim":32,"weapon":"machina","tick":60275},{"killer":52,"assister":44,"victim":55,"weapon":"tomislav","tick":60564},{"killer":36,"assister":null,"victim":52,"weapon":"sniperrifle","tick":60564},{"killer":45,"assister":50,"victim":56,"weapon":"tf_projectile_pipe_remote","tick":60744},{"killer":54,"assister":56,"victim":50,"weapon":"tf_projectile_pipe_remote","tick":60888},{"killer":54,"assister":36,"victim":44,"weapon":"tf_projectile_pipe_remote","tick":60902},{"killer":45,"assister":48,"victim":54,"weapon":"tf_projectile_pipe_remote","tick":61046},{"killer":43,"assister":null,"victim":53,"weapon":"scattergun","tick":61269},{"killer":53,"assister":null,"victim":42,"weapon":"blackbox","tick":61295},{"killer":43,"assister":36,"victim":45,"weapon":"atomizer","tick":61579},{"killer":43,"assister":39,"victim":47,"weapon":"scattergun","tick":61763},{"killer":36,"assister":43,"victim":48,"weapon":"sniperrifle","tick":61857},{"killer":39,"assister":null,"victim":46,"weapon":"obj_minisentry","tick":62221}],"rounds":[{"winner":"red","length":276.0299987792969,"end_tick":29322},{"winner":"red","length":238.97998046875,"end_tick":45921},{"winner":"red","length":228.45001220703125,"end_tick":61817}],"startTick":10587,"intervalPerTick":0.014999999664723873,"header":{"type":"HL2DEMO","version":3,"protocol":24,"server":"UGC Highlander Match","nick":"SourceTV Demo","map":"koth_product_rc8","game":"tf","duration":778.4849853515625,"ticks":51899,"frames":25703,"sigon":818263}} \ No newline at end of file +{ + "chat": [ + { "kind": "TF_Chat_All", "from": "Foz", "text": "gg", "tick": 61747 }, + { + "kind": "TF_Chat_All", + "from": "Mason✧", + "text": "gg", + "tick": 61871 + }, + { "kind": "TF_Chat_All", "from": "Kireek", "text": "gg", "tick": 61959 }, + { "kind": "TF_Chat_All", "from": "Sketis", "text": "wp", "tick": 61963 }, + { "kind": "TF_Chat_All", "from": "Vinegar", "text": "gg", "tick": 61999 }, + { + "kind": "TF_Chat_All", + "from": "Pendulum", + "text": "gg in chat", + "tick": 62043 + }, + { + "kind": "TF_Chat_All", + "from": "Icewind | demos.tf", + "text": "gg", + "tick": 62075 + }, + { "kind": "TF_Chat_All", "from": "Solar", "text": "gg", "tick": 62167 }, + { "kind": "TF_Chat_All", "from": "magikarp", "text": "gg", "tick": 62281 } + ], + "users": { + "18": { + "classes": {}, + "name": "UGC Highlander Match TV", + "steamId": "BOT", + "userId": 18 + }, + "30": { + "classes": { "5": 6 }, + "name": "Icewind | demos.tf", + "steamId": "[U:1:64229260]", + "userId": 30, + "team": "red" + }, + "32": { + "classes": { "3": 12 }, + "name": "Foz", + "steamId": "[U:1:115748435]", + "userId": 32, + "team": "red" + }, + "36": { + "classes": { "2": 7 }, + "name": "Chicken Meatballs, FOZ", + "steamId": "[U:1:115754284]", + "userId": 36, + "team": "red" + }, + "39": { + "classes": { "9": 8 }, + "name": "Kireek", + "steamId": "[U:1:92428736]", + "userId": 39, + "team": "red" + }, + "42": { + "classes": { "8": 15 }, + "name": "Vinegar", + "steamId": "[U:1:22958903]", + "userId": 42, + "team": "red" + }, + "43": { + "classes": { "1": 10 }, + "name": "[GC]Kimo", + "steamId": "[U:1:32061783]", + "userId": 43, + "team": "red" + }, + "44": { + "classes": { "2": 19 }, + "name": "magikarp", + "steamId": "[U:1:67502510]", + "userId": 44, + "team": "blue" + }, + "45": { + "classes": { "4": 12 }, + "name": "Solar", + "steamId": "[U:1:55128465]", + "userId": 45, + "team": "blue" + }, + "46": { + "classes": { "1": 18 }, + "name": "ztreak", + "steamId": "[U:1:301587080]", + "userId": 46, + "team": "blue" + }, + "47": { + "classes": { "7": 21 }, + "name": "TheMasterOfDisaster", + "steamId": "[U:1:22162172]", + "userId": 47, + "team": "blue" + }, + "48": { + "classes": { "5": 7 }, + "name": "Sage Luke", + "steamId": "[U:1:13559571]", + "userId": 48, + "team": "blue" + }, + "50": { + "classes": { "9": 18 }, + "name": "Sketis", + "steamId": "[U:1:71706948]", + "userId": 50, + "team": "blue" + }, + "51": { + "classes": { "8": 20 }, + "name": "Pyla", + "steamId": "[U:1:157204170]", + "userId": 51, + "team": "blue" + }, + "52": { + "classes": { "6": 16 }, + "name": "Mason✧", + "steamId": "[U:1:30838206]", + "userId": 52, + "team": "blue" + }, + "53": { + "classes": { "3": 16 }, + "name": "rane", + "steamId": "[U:1:174774002]", + "userId": 53, + "team": "blue" + }, + "54": { + "classes": { "4": 8 }, + "name": "Old Billy Riley", + "steamId": "[U:1:92096346]", + "userId": 54, + "team": "red" + }, + "55": { + "classes": { "6": 10 }, + "name": "Pendulum", + "steamId": "[U:1:143626373]", + "userId": 55, + "team": "red" + }, + "56": { + "classes": { "7": 10 }, + "name": "Jedi(fla)master", + "steamId": "[U:1:30220936]", + "userId": 56, + "team": "red" + } + }, + "deaths": [ + { + "killer": 36, + "assister": null, + "victim": 50, + "weapon": "sniperrifle", + "tick": 10651 + }, + { + "killer": 55, + "assister": null, + "victim": 44, + "weapon": "minigun", + "tick": 10687 + }, + { + "killer": 39, + "assister": null, + "victim": 46, + "weapon": "shotgun_primary", + "tick": 10711 + }, + { + "killer": 32, + "assister": null, + "victim": 45, + "weapon": "quake_rl", + "tick": 10814 + }, + { + "killer": 32, + "assister": null, + "victim": 48, + "weapon": "quake_rl", + "tick": 10814 + }, + { + "killer": 55, + "assister": null, + "victim": 53, + "weapon": "minigun", + "tick": 10834 + }, + { + "killer": 45, + "assister": null, + "victim": 42, + "weapon": "tf_projectile_pipe_remote", + "tick": 12037 + }, + { + "killer": 36, + "assister": 43, + "victim": 46, + "weapon": "sniperrifle", + "tick": 12152 + }, + { + "killer": 44, + "assister": null, + "victim": 56, + "weapon": "machina", + "tick": 12428 + }, + { + "killer": 51, + "assister": null, + "victim": 55, + "weapon": "spy_cicle", + "tick": 12450 + }, + { + "killer": 32, + "assister": 56, + "victim": 53, + "weapon": "quake_rl", + "tick": 12524 + }, + { + "killer": 44, + "assister": null, + "victim": 32, + "weapon": "machina", + "tick": 12736 + }, + { + "killer": 47, + "assister": null, + "victim": 42, + "weapon": "degreaser", + "tick": 12898 + }, + { + "killer": 39, + "assister": null, + "victim": 47, + "weapon": "obj_minisentry", + "tick": 13042 + }, + { + "killer": 51, + "assister": 47, + "victim": 39, + "weapon": "spy_cicle", + "tick": 13096 + }, + { + "killer": 44, + "assister": null, + "victim": 30, + "weapon": "machina", + "tick": 13696 + }, + { + "killer": 54, + "assister": 43, + "victim": 52, + "weapon": "tf_projectile_pipe_remote", + "tick": 13800 + }, + { + "killer": 46, + "assister": 48, + "victim": 42, + "weapon": "scattergun", + "tick": 13992 + }, + { + "killer": 45, + "assister": 48, + "victim": 43, + "weapon": "iron_bomber", + "tick": 14272 + }, + { + "killer": 36, + "assister": null, + "victim": 46, + "weapon": "sniperrifle", + "tick": 14529 + }, + { + "killer": 44, + "assister": 48, + "victim": 56, + "weapon": "machina", + "tick": 14830 + }, + { + "killer": 45, + "assister": null, + "victim": 54, + "weapon": "iron_bomber", + "tick": 14918 + }, + { + "killer": 39, + "assister": null, + "victim": 51, + "weapon": "shotgun_primary", + "tick": 15509 + }, + { + "killer": 42, + "assister": 55, + "victim": 44, + "weapon": "revolver", + "tick": 15738 + }, + { + "killer": 42, + "assister": null, + "victim": 47, + "weapon": "revolver", + "tick": 15900 + }, + { + "killer": 43, + "assister": null, + "victim": 45, + "weapon": "world", + "tick": 15991 + }, + { + "killer": 53, + "assister": 48, + "victim": 42, + "weapon": "blackbox", + "tick": 16105 + }, + { + "killer": 50, + "assister": 46, + "victim": 42, + "weapon": "rescue_ranger", + "tick": 16358 + }, + { + "killer": 54, + "assister": 39, + "victim": 46, + "weapon": "tf_projectile_pipe_remote", + "tick": 16935 + }, + { + "killer": 43, + "assister": 55, + "victim": 52, + "weapon": "scattergun", + "tick": 17825 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 18178 + }, + { + "killer": 53, + "assister": 48, + "victim": 42, + "weapon": "blackbox", + "tick": 18791 + }, + { + "killer": 43, + "assister": 42, + "victim": 44, + "weapon": "scattergun", + "tick": 18936 + }, + { + "killer": 39, + "assister": 43, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 19416 + }, + { + "killer": 36, + "assister": 54, + "victim": 52, + "weapon": "sniperrifle", + "tick": 19736 + }, + { + "killer": 43, + "assister": null, + "victim": 50, + "weapon": "scattergun", + "tick": 20060 + }, + { + "killer": 51, + "assister": null, + "victim": 42, + "weapon": "spy_cicle", + "tick": 20224 + }, + { + "killer": 36, + "assister": null, + "victim": 44, + "weapon": "sniperrifle", + "tick": 20521 + }, + { + "killer": 43, + "assister": 39, + "victim": 47, + "weapon": "scattergun", + "tick": 20730 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 20735 + }, + { + "killer": 50, + "assister": null, + "victim": 42, + "weapon": "obj_minisentry", + "tick": 21844 + }, + { + "killer": 32, + "assister": null, + "victim": 51, + "weapon": "quake_rl", + "tick": 21870 + }, + { + "killer": 45, + "assister": 48, + "victim": 56, + "weapon": "iron_bomber", + "tick": 21896 + }, + { + "killer": 47, + "assister": 50, + "victim": 42, + "weapon": "degreaser", + "tick": 22199 + }, + { + "killer": 53, + "assister": 52, + "victim": 43, + "weapon": "blackbox", + "tick": 22275 + }, + { + "killer": 39, + "assister": 55, + "victim": 53, + "weapon": "shotgun_primary", + "tick": 22464 + }, + { + "killer": 36, + "assister": 54, + "victim": 50, + "weapon": "sniperrifle", + "tick": 22520 + }, + { + "killer": 39, + "assister": 32, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 22631 + }, + { + "killer": 42, + "assister": null, + "victim": 44, + "weapon": "world", + "tick": 22661 + }, + { + "killer": 39, + "assister": 55, + "victim": 47, + "weapon": "obj_minisentry", + "tick": 22835 + }, + { + "killer": 50, + "assister": null, + "victim": 42, + "weapon": "obj_minisentry", + "tick": 22855 + }, + { + "killer": 39, + "assister": 54, + "victim": 45, + "weapon": "shotgun_primary", + "tick": 23389 + }, + { + "killer": 44, + "assister": 46, + "victim": 36, + "weapon": "machina", + "tick": 24391 + }, + { + "killer": 53, + "assister": null, + "victim": 32, + "weapon": "blackbox", + "tick": 25148 + }, + { + "killer": 54, + "assister": 30, + "victim": 46, + "weapon": "tf_projectile_pipe_remote", + "tick": 25196 + }, + { + "killer": 54, + "assister": 30, + "victim": 52, + "weapon": "tf_projectile_pipe_remote", + "tick": 25196 + }, + { + "killer": 56, + "assister": 39, + "victim": 51, + "weapon": "degreaser", + "tick": 25264 + }, + { + "killer": 42, + "assister": null, + "victim": 53, + "weapon": "revolver", + "tick": 25358 + }, + { + "killer": 43, + "assister": 39, + "victim": 47, + "weapon": "scattergun", + "tick": 25397 + }, + { + "killer": 55, + "assister": 30, + "victim": 50, + "weapon": "minigun", + "tick": 25529 + }, + { + "killer": 42, + "assister": null, + "victim": 44, + "weapon": "spy_cicle", + "tick": 26007 + }, + { + "killer": 46, + "assister": 48, + "victim": 42, + "weapon": "scattergun", + "tick": 26411 + }, + { + "killer": 51, + "assister": null, + "victim": 55, + "weapon": "spy_cicle", + "tick": 26848 + }, + { + "killer": 42, + "assister": 39, + "victim": 50, + "weapon": "spy_cicle", + "tick": 27080 + }, + { + "killer": 46, + "assister": null, + "victim": 42, + "weapon": "scattergun", + "tick": 27450 + }, + { + "killer": 43, + "assister": 39, + "victim": 53, + "weapon": "scattergun", + "tick": 27955 + }, + { + "killer": 32, + "assister": 39, + "victim": 47, + "weapon": "quake_rl", + "tick": 28013 + }, + { + "killer": 44, + "assister": null, + "victim": 39, + "weapon": "machina", + "tick": 28049 + }, + { + "killer": 50, + "assister": null, + "victim": 42, + "weapon": "shotgun_primary", + "tick": 28311 + }, + { + "killer": 56, + "assister": null, + "victim": 51, + "weapon": "degreaser", + "tick": 28390 + }, + { + "killer": 54, + "assister": 32, + "victim": 46, + "weapon": "tf_projectile_pipe_remote", + "tick": 28889 + }, + { + "killer": 32, + "assister": 54, + "victim": 48, + "weapon": "quake_rl", + "tick": 28896 + }, + { + "killer": 30, + "assister": null, + "victim": 45, + "weapon": "crusaders_crossbow", + "tick": 28970 + }, + { + "killer": 54, + "assister": null, + "victim": 52, + "weapon": "iron_bomber", + "tick": 28980 + }, + { + "killer": 50, + "assister": 52, + "victim": 32, + "weapon": "obj_minisentry", + "tick": 29040 + }, + { + "killer": 44, + "assister": 50, + "victim": 56, + "weapon": "machina", + "tick": 29090 + }, + { + "killer": 43, + "assister": 56, + "victim": 50, + "weapon": "scattergun", + "tick": 29314 + }, + { + "killer": 44, + "assister": null, + "victim": 56, + "weapon": "machina", + "tick": 31127 + }, + { + "killer": 32, + "assister": 43, + "victim": 47, + "weapon": "quake_rl", + "tick": 31559 + }, + { + "killer": 51, + "assister": null, + "victim": 55, + "weapon": "kunai", + "tick": 31673 + }, + { + "killer": 42, + "assister": null, + "victim": 52, + "weapon": "kunai", + "tick": 31675 + }, + { + "killer": 44, + "assister": 52, + "victim": 32, + "weapon": "machina", + "tick": 31717 + }, + { + "killer": 43, + "assister": 32, + "victim": 53, + "weapon": "scattergun", + "tick": 31726 + }, + { + "killer": 53, + "assister": null, + "victim": 43, + "weapon": "blackbox", + "tick": 31730 + }, + { + "killer": 54, + "assister": 39, + "victim": 50, + "weapon": "iron_bomber", + "tick": 31839 + }, + { + "killer": 36, + "assister": null, + "victim": 46, + "weapon": "sniperrifle", + "tick": 32125 + }, + { + "killer": 44, + "assister": 48, + "victim": 39, + "weapon": "machina", + "tick": 32651 + }, + { + "killer": 54, + "assister": null, + "victim": 45, + "weapon": "iron_bomber", + "tick": 32811 + }, + { + "killer": 42, + "assister": null, + "victim": 48, + "weapon": "letranger", + "tick": 33017 + }, + { + "killer": 56, + "assister": 43, + "victim": 51, + "weapon": "flaregun", + "tick": 33061 + }, + { + "killer": 54, + "assister": null, + "victim": 44, + "weapon": "iron_bomber", + "tick": 33203 + }, + { + "killer": 50, + "assister": 47, + "victim": 42, + "weapon": "shotgun_primary", + "tick": 34179 + }, + { + "killer": 36, + "assister": null, + "victim": 44, + "weapon": "sniperrifle", + "tick": 34920 + }, + { + "killer": 32, + "assister": null, + "victim": 51, + "weapon": "quake_rl", + "tick": 35322 + }, + { + "killer": 54, + "assister": 30, + "victim": 46, + "weapon": "iron_bomber", + "tick": 35465 + }, + { + "killer": 32, + "assister": 39, + "victim": 53, + "weapon": "quake_rl", + "tick": 36017 + }, + { + "killer": 39, + "assister": 55, + "victim": 47, + "weapon": "shotgun_primary", + "tick": 36265 + }, + { + "killer": 54, + "assister": 36, + "victim": 52, + "weapon": "tf_projectile_pipe_remote", + "tick": 36441 + }, + { + "killer": 42, + "assister": null, + "victim": 44, + "weapon": "kunai", + "tick": 36717 + }, + { + "killer": 54, + "assister": 55, + "victim": 50, + "weapon": "tf_projectile_pipe_remote", + "tick": 37567 + }, + { + "killer": 51, + "assister": null, + "victim": 32, + "weapon": "kunai", + "tick": 37571 + }, + { + "killer": 51, + "assister": null, + "victim": 30, + "weapon": "kunai", + "tick": 38117 + }, + { + "killer": 44, + "assister": null, + "victim": 42, + "weapon": "machina", + "tick": 38131 + }, + { + "killer": 54, + "assister": 43, + "victim": 51, + "weapon": "tf_projectile_pipe_remote", + "tick": 38255 + }, + { + "killer": 46, + "assister": null, + "victim": 55, + "weapon": "scattergun", + "tick": 38683 + }, + { + "killer": 43, + "assister": 54, + "victim": 52, + "weapon": "scattergun", + "tick": 38703 + }, + { + "killer": 39, + "assister": 55, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 38787 + }, + { + "killer": 44, + "assister": null, + "victim": 54, + "weapon": "machina", + "tick": 38797 + }, + { + "killer": 45, + "assister": 48, + "victim": 43, + "weapon": "tf_projectile_pipe_remote", + "tick": 38809 + }, + { + "killer": 32, + "assister": null, + "victim": 45, + "weapon": "quake_rl", + "tick": 39291 + }, + { + "killer": 56, + "assister": null, + "victim": 44, + "weapon": "flaregun", + "tick": 39351 + }, + { + "killer": 56, + "assister": null, + "victim": 48, + "weapon": "flaregun", + "tick": 39591 + }, + { + "killer": 36, + "assister": 32, + "victim": 47, + "weapon": "sniperrifle", + "tick": 39611 + }, + { + "killer": 56, + "assister": null, + "victim": 51, + "weapon": "degreaser", + "tick": 39747 + }, + { + "killer": 53, + "assister": null, + "victim": 56, + "weapon": "blackbox", + "tick": 39753 + }, + { + "killer": 36, + "assister": null, + "victim": 50, + "weapon": "sniperrifle", + "tick": 39775 + }, + { + "killer": 53, + "assister": null, + "victim": 32, + "weapon": "blackbox", + "tick": 40053 + }, + { + "killer": 39, + "assister": 55, + "victim": 53, + "weapon": "shotgun_primary", + "tick": 40183 + }, + { + "killer": 36, + "assister": 30, + "victim": 44, + "weapon": "sniperrifle", + "tick": 41360 + }, + { + "killer": 42, + "assister": 39, + "victim": 50, + "weapon": "kunai", + "tick": 41393 + }, + { + "killer": 55, + "assister": null, + "victim": 51, + "weapon": "minigun", + "tick": 41761 + }, + { + "killer": 36, + "assister": 54, + "victim": 47, + "weapon": "sniperrifle", + "tick": 42213 + }, + { + "killer": 45, + "assister": 52, + "victim": 42, + "weapon": "tf_projectile_pipe_remote", + "tick": 42481 + }, + { + "killer": 43, + "assister": null, + "victim": 53, + "weapon": "scattergun", + "tick": 42735 + }, + { + "killer": 36, + "assister": null, + "victim": 44, + "weapon": "sniperrifle", + "tick": 42884 + }, + { + "killer": 43, + "assister": null, + "victim": 46, + "weapon": "scattergun", + "tick": 42912 + }, + { + "killer": 43, + "assister": 32, + "victim": 51, + "weapon": "scattergun", + "tick": 43261 + }, + { + "killer": 42, + "assister": null, + "victim": 47, + "weapon": "kunai", + "tick": 44809 + }, + { + "killer": 36, + "assister": 30, + "victim": 52, + "weapon": "sniperrifle", + "tick": 44963 + }, + { + "killer": 54, + "assister": 30, + "victim": 48, + "weapon": "tf_projectile_pipe_remote", + "tick": 45381 + }, + { + "killer": 55, + "assister": 36, + "victim": 50, + "weapon": "minigun", + "tick": 45381 + }, + { + "killer": 51, + "assister": 50, + "victim": 56, + "weapon": "kunai", + "tick": 45551 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 45651 + }, + { + "killer": 45, + "assister": 50, + "victim": 32, + "weapon": "iron_bomber", + "tick": 45665 + }, + { + "killer": 32, + "assister": null, + "victim": 45, + "weapon": "quake_rl", + "tick": 45667 + }, + { + "killer": 39, + "assister": 43, + "victim": 51, + "weapon": "shotgun_primary", + "tick": 45729 + }, + { + "killer": 39, + "assister": 43, + "victim": 53, + "weapon": "obj_minisentry", + "tick": 45865 + }, + { + "killer": 39, + "assister": null, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 46049 + }, + { + "killer": 54, + "assister": 43, + "victim": 45, + "weapon": "tf_projectile_pipe_remote", + "tick": 47557 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 47775 + }, + { + "killer": 48, + "assister": null, + "victim": 32, + "weapon": "crusaders_crossbow", + "tick": 47827 + }, + { + "killer": 54, + "assister": 55, + "victim": 47, + "weapon": "iron_bomber", + "tick": 47953 + }, + { + "killer": 39, + "assister": 56, + "victim": 51, + "weapon": "shotgun_primary", + "tick": 47991 + }, + { + "killer": 52, + "assister": null, + "victim": 54, + "weapon": "tomislav", + "tick": 48053 + }, + { + "killer": 36, + "assister": null, + "victim": 52, + "weapon": "sniperrifle", + "tick": 48437 + }, + { + "killer": 43, + "assister": null, + "victim": 46, + "weapon": "scattergun", + "tick": 48509 + }, + { + "killer": 39, + "assister": 56, + "victim": 50, + "weapon": "obj_minisentry", + "tick": 48527 + }, + { + "killer": 44, + "assister": 48, + "victim": 36, + "weapon": "machina", + "tick": 48607 + }, + { + "killer": 39, + "assister": 43, + "victim": 53, + "weapon": "obj_minisentry", + "tick": 48773 + }, + { + "killer": 48, + "assister": null, + "victim": 43, + "weapon": "crusaders_crossbow", + "tick": 49049 + }, + { + "killer": 44, + "assister": 48, + "victim": 39, + "weapon": "machina", + "tick": 49121 + }, + { + "killer": 42, + "assister": 55, + "victim": 47, + "weapon": "kunai", + "tick": 49923 + }, + { + "killer": 32, + "assister": 55, + "victim": 44, + "weapon": "quake_rl", + "tick": 50659 + }, + { + "killer": 51, + "assister": null, + "victim": 55, + "weapon": "kunai", + "tick": 50825 + }, + { + "killer": 42, + "assister": null, + "victim": 45, + "weapon": "kunai", + "tick": 50845 + }, + { + "killer": 46, + "assister": 48, + "victim": 42, + "weapon": "scattergun", + "tick": 51071 + }, + { + "killer": 36, + "assister": null, + "victim": 52, + "weapon": "sniperrifle", + "tick": 51293 + }, + { + "killer": 56, + "assister": null, + "victim": 51, + "weapon": "degreaser", + "tick": 51801 + }, + { + "killer": 44, + "assister": 50, + "victim": 54, + "weapon": "machina", + "tick": 52481 + }, + { + "killer": 44, + "assister": null, + "victim": 43, + "weapon": "machina", + "tick": 52817 + }, + { + "killer": 36, + "assister": null, + "victim": 46, + "weapon": "sniperrifle", + "tick": 52849 + }, + { + "killer": 55, + "assister": 39, + "victim": 47, + "weapon": "minigun", + "tick": 52921 + }, + { + "killer": 52, + "assister": null, + "victim": 42, + "weapon": "tomislav", + "tick": 53161 + }, + { + "killer": 44, + "assister": null, + "victim": 56, + "weapon": "machina", + "tick": 53266 + }, + { + "killer": 36, + "assister": null, + "victim": 48, + "weapon": "sniperrifle", + "tick": 53406 + }, + { + "killer": 55, + "assister": 30, + "victim": 45, + "weapon": "minigun", + "tick": 53410 + }, + { + "killer": 32, + "assister": null, + "victim": 50, + "weapon": "quake_rl", + "tick": 53593 + }, + { + "killer": 32, + "assister": null, + "victim": 51, + "weapon": "quake_rl", + "tick": 53717 + }, + { + "killer": 42, + "assister": null, + "victim": 44, + "weapon": "ambassador", + "tick": 53846 + }, + { + "killer": 52, + "assister": null, + "victim": 42, + "weapon": "tomislav", + "tick": 54068 + }, + { + "killer": 54, + "assister": 30, + "victim": 53, + "weapon": "iron_bomber", + "tick": 54109 + }, + { + "killer": 47, + "assister": 46, + "victim": 42, + "weapon": "degreaser", + "tick": 54366 + }, + { + "killer": 36, + "assister": null, + "victim": 52, + "weapon": "sniperrifle", + "tick": 54711 + }, + { + "killer": 56, + "assister": null, + "victim": 51, + "weapon": "flaregun", + "tick": 55863 + }, + { + "killer": 44, + "assister": null, + "victim": 42, + "weapon": "machina", + "tick": 56325 + }, + { + "killer": 44, + "assister": null, + "victim": 32, + "weapon": "machina", + "tick": 56675 + }, + { + "killer": 36, + "assister": null, + "victim": 44, + "weapon": "sniperrifle", + "tick": 56805 + }, + { + "killer": 53, + "assister": null, + "victim": 36, + "weapon": "blackbox", + "tick": 57171 + }, + { + "killer": 56, + "assister": null, + "victim": 46, + "weapon": "world", + "tick": 57371 + }, + { + "killer": 56, + "assister": null, + "victim": 47, + "weapon": "degreaser", + "tick": 57595 + }, + { + "killer": 43, + "assister": null, + "victim": 51, + "weapon": "scattergun", + "tick": 57709 + }, + { + "killer": 43, + "assister": 55, + "victim": 53, + "weapon": "scattergun", + "tick": 57913 + }, + { + "killer": 42, + "assister": null, + "victim": 50, + "weapon": "spy_cicle", + "tick": 58611 + }, + { + "killer": 36, + "assister": null, + "victim": 46, + "weapon": "sniperrifle", + "tick": 59336 + }, + { + "killer": 55, + "assister": 43, + "victim": 45, + "weapon": "minigun", + "tick": 59474 + }, + { + "killer": 44, + "assister": null, + "victim": 42, + "weapon": "machina", + "tick": 59485 + }, + { + "killer": 55, + "assister": 39, + "victim": 53, + "weapon": "minigun", + "tick": 59647 + }, + { + "killer": 43, + "assister": 55, + "victim": 47, + "weapon": "scattergun", + "tick": 59904 + }, + { + "killer": 54, + "assister": null, + "victim": 51, + "weapon": "iron_bomber", + "tick": 59982 + }, + { + "killer": 44, + "assister": null, + "victim": 32, + "weapon": "machina", + "tick": 60275 + }, + { + "killer": 52, + "assister": 44, + "victim": 55, + "weapon": "tomislav", + "tick": 60564 + }, + { + "killer": 36, + "assister": null, + "victim": 52, + "weapon": "sniperrifle", + "tick": 60564 + }, + { + "killer": 45, + "assister": 50, + "victim": 56, + "weapon": "tf_projectile_pipe_remote", + "tick": 60744 + }, + { + "killer": 54, + "assister": 56, + "victim": 50, + "weapon": "tf_projectile_pipe_remote", + "tick": 60888 + }, + { + "killer": 54, + "assister": 36, + "victim": 44, + "weapon": "tf_projectile_pipe_remote", + "tick": 60902 + }, + { + "killer": 45, + "assister": 48, + "victim": 54, + "weapon": "tf_projectile_pipe_remote", + "tick": 61046 + }, + { + "killer": 43, + "assister": null, + "victim": 53, + "weapon": "scattergun", + "tick": 61269 + }, + { + "killer": 53, + "assister": null, + "victim": 42, + "weapon": "blackbox", + "tick": 61295 + }, + { + "killer": 43, + "assister": 36, + "victim": 45, + "weapon": "atomizer", + "tick": 61579 + }, + { + "killer": 43, + "assister": 39, + "victim": 47, + "weapon": "scattergun", + "tick": 61763 + }, + { + "killer": 36, + "assister": 43, + "victim": 48, + "weapon": "sniperrifle", + "tick": 61857 + }, + { + "killer": 39, + "assister": null, + "victim": 46, + "weapon": "obj_minisentry", + "tick": 62221 + } + ], + "rounds": [ + { "winner": "red", "length": 276.0299987792969, "end_tick": 29322 }, + { "winner": "red", "length": 238.97998046875, "end_tick": 45921 }, + { "winner": "red", "length": 228.45001220703125, "end_tick": 61817 } + ], + "startTick": 10587, + "intervalPerTick": 0.014999999664723873, + "header": { + "type": "HL2DEMO", + "version": 3, + "protocol": 24, + "server": "UGC Highlander Match", + "nick": "SourceTV Demo", + "map": "koth_product_rc8", + "game": "tf", + "duration": 778.4849853515625, + "ticks": 51899, + "frames": 25703, + "sigon": 818263 + } +}