diff --git a/.git-crypt/.gitattributes b/.git-crypt/.gitattributes
new file mode 100644
index 0000000..665b10e
--- /dev/null
+++ b/.git-crypt/.gitattributes
@@ -0,0 +1,4 @@
+# Do not edit this file. To specify the files to encrypt, create your own
+# .gitattributes file in the directory where your files are.
+* !filter !diff
+*.gpg binary
diff --git a/.git-crypt/keys/default/0/059F098EBF0E9A13E10A46BF6500251E087653C9.gpg b/.git-crypt/keys/default/0/059F098EBF0E9A13E10A46BF6500251E087653C9.gpg
new file mode 100644
index 0000000..8164576
Binary files /dev/null and b/.git-crypt/keys/default/0/059F098EBF0E9A13E10A46BF6500251E087653C9.gpg differ
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..7e0e7cf
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+secrets.gcrypt/** filter=git-crypt diff=git-crypt
diff --git a/.github/screenshots/desktop.png b/.github/screenshots/desktop.png
new file mode 100644
index 0000000..a37242f
Binary files /dev/null and b/.github/screenshots/desktop.png differ
diff --git a/.github/screenshots/neovim.png b/.github/screenshots/neovim.png
new file mode 100644
index 0000000..030fff1
Binary files /dev/null and b/.github/screenshots/neovim.png differ
diff --git a/.github/workflows/autoupdate.yml b/.github/workflows/autoupdate.yml
new file mode 100644
index 0000000..6ab9707
--- /dev/null
+++ b/.github/workflows/autoupdate.yml
@@ -0,0 +1,50 @@
+name: Auto update
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: "0 0 * * *"
+
+jobs:
+ update:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.PAT_TOKEN }}
+
+ - name: Check for updates
+ id: check
+ run: |
+ local=$(cat flake.lock | jq ".nodes.nixpkgs.locked.rev")
+ remote=$(curl "https://api.github.com/repos/NixOS/nixpkgs/branches/nixos-unstable/commits?per_page=1" | jq ".commit.sha")
+ if [[ $local == $remote ]]; then
+ echo "skip=1" >> "$GITHUB_OUTPUT"
+ else
+ echo "skip=0" >> "$GITHUB_OUTPUT"
+ branch=$(TZ='Australia/Melbourne' date '+staging_auto/%Y%m%d')
+ echo "branch_name=${branch}" >> "$GITHUB_OUTPUT"
+ fi
+
+ - name: Install nix
+ if: steps.check.outputs.skip == 0
+ uses: cachix/install-nix-action@v31
+
+ - name: Configure git
+ if: steps.check.outputs.skip == 0
+ run: |
+ git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git config --local user.name "github-actions[bot]"
+
+ - name: Update
+ if: steps.check.outputs.skip == 0
+ run: ./update.sh
+
+ - name: Push
+ if: steps.check.outputs.skip == 0
+ uses: ad-m/github-push-action@master
+ with:
+ github_token: ${{ secrets.PAT_TOKEN }}
+ branch: ${{ steps.check.outputs.branch_name }}
diff --git a/.github/workflows/cachix.yml b/.github/workflows/cachix.yml
index 602af55..06bed3e 100644
--- a/.github/workflows/cachix.yml
+++ b/.github/workflows/cachix.yml
@@ -1,35 +1,28 @@
-name: Cachix build
+name: CI
on:
push:
workflow_dispatch:
jobs:
- linux:
- name: Build Linux
+ build:
+ name: Build linux-lava for x86_64-linux
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2.3.4
- - uses: cachix/install-nix-action@v13
+ # credits to https://github.com/easimon/maximize-build-space/issues/45
+ - name: Remove unneeded packages to maximise build space
+ shell: bash
+ run: |
+ df -h
+ sudo rm -rf /usr/share/dotnet
+ sudo rm -rf /usr/local/lib/android
+ df -h
+ - uses: actions/checkout@v4
with:
- install_url: https://github.com/numtide/nix-flakes-installer/releases/download/nix-3.0pre20201007_5257a25/install
- extra_nix_config: experimental-features = nix-command flakes
- - uses: cachix/cachix-action@v10
+ fetch-depth: 0
+ - uses: cachix/install-nix-action@v31
+ - uses: cachix/cachix-action@v16
with:
name: lava
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- run: nix build -L .#linux-lava
- wine:
- name: Build Wine
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2.3.4
- - uses: cachix/install-nix-action@v13
- with:
- install_url: https://github.com/numtide/nix-flakes-installer/releases/download/nix-3.0pre20201007_5257a25/install
- extra_nix_config: experimental-features = nix-command flakes
- - uses: cachix/cachix-action@v10
- with:
- name: lava
- authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- - run: nix build -L .#wine-osu
diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml
new file mode 100644
index 0000000..4990cc7
--- /dev/null
+++ b/.github/workflows/image.yml
@@ -0,0 +1,31 @@
+name: Build images
+
+on:
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ name: Build caramel-img
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - uses: dbhi/qus/action@main
+ with:
+ targets: arm aarch64
+ - uses: cachix/install-nix-action@v17
+ with:
+ install_url: https://github.com/numtide/nix-unstable-installer/releases/download/nix-2.12.0pre20220930_89ca75c/install
+ extra_nix_config: |
+ extra-platforms = aarch64-linux arm-linux
+ experimental-features = nix-command flakes
+ - uses: cachix/cachix-action@v10
+ with:
+ name: lava
+ authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
+ - run: nix build -L .#packages.aarch64-linux.caramel-img
+ - uses: actions/upload-artifact@v3
+ with:
+ name: caramel-sd-image
+ path: result/sd-image/*
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b2be92b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+result
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..daec2a6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,31 @@
+# flakes
+My NixOS config!
+
+
+
+
+## Usage
+I recommend more that you only simply look at the modules as inspiration for your own config. Some of them
+may or may not work on your machine if copied directly (but theoretically they should).
+
+But if you insist, just copy-paste one of the hosts in `hosts/`, one of the users in `users/`, and modify them
+to your liking. Open up `flake.nix`, add your new host config at the bottom, and then build it!
+
+## Hosts
+| Name | Description |
+| ------- | ----------- |
+| hyacinth | Main Desktop PC |
+| anemone | Main Laptop |
+| caramel | Raspberry Pi 400, stateless |
+| dandelion | ARM OCI VPS, stateless |
+
+## Users
+| Name | Description |
+| ---- | ----------- |
+| rin | Main user for general usage |
+| hana | Lightweight user intended for inspecting stateless hosts |
+
+## License
+Licensed under CC0
+
+Credit is appreciated but not necessary
diff --git a/containers/amethyst/configuration.nix b/containers/amethyst/configuration.nix
new file mode 100644
index 0000000..b9d496d
--- /dev/null
+++ b/containers/amethyst/configuration.nix
@@ -0,0 +1,47 @@
+{ lib, pkgs, ... }: {
+ system.stateVersion = "23.11";
+ systemd.tmpfiles.rules = [
+ "d /persist/transmission 755 transmission transmission"
+ "d /persist/transmission/.config/transmission-daemon 750 transmission transmission"
+ "d /persist/transmission/.incomplete 750 transmission transmission"
+ "d /persist/transmission/Downloads 755 transmission transmission"
+ "d /persist/transmission/watchdir 755 transmission transmission"
+ ];
+ networking.wg-quick.interfaces.wg0 = {
+ configFile = "/persist/vpn.conf";
+ preUp = ''
+ # Try to access the DNS for up to 300s
+ for i in {1..60}; do
+ ${pkgs.iputils}/bin/ping -c1 'google.com' && break
+ echo "Attempt $i: DNS still not available"
+ sleep 5s
+ done
+ '';
+ };
+
+ # https://github.com/NixOS/nixpkgs/issues/258793
+ systemd.services.transmission.serviceConfig = {
+ BindReadOnlyPaths = lib.mkForce [ builtins.storeDir "/etc" ];
+ RootDirectoryStartOnly = lib.mkForce false;
+ RootDirectory = lib.mkForce "";
+ PrivateMounts = lib.mkForce false;
+ PrivateUsers = lib.mkForce false;
+ };
+
+ networking.firewall.allowedTCPPorts = [ 9091 ];
+ services.transmission = {
+ enable = true;
+ package = pkgs.transmission_4;
+ downloadDirPermissions = "775";
+ openFirewall = true;
+ home = "/persist/transmission";
+ settings = {
+ ratio-limit-enabled = true;
+ rpc-bind-address = "0.0.0.0";
+ rpc-enabled = true;
+ rpc-port = 9091;
+ rpc-host-whitelist-enabled = false;
+ rpc-whitelist-enabled = false;
+ };
+ };
+}
diff --git a/containers/amethyst/flake.lock b/containers/amethyst/flake.lock
new file mode 100644
index 0000000..88ab73f
--- /dev/null
+++ b/containers/amethyst/flake.lock
@@ -0,0 +1,27 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/containers/amethyst/flake.nix b/containers/amethyst/flake.nix
new file mode 100644
index 0000000..739c3e5
--- /dev/null
+++ b/containers/amethyst/flake.nix
@@ -0,0 +1,51 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ };
+ outputs = { nixpkgs, ... }: {
+ nixosConfigurations.container = nixpkgs.lib.nixosSystem {
+ modules = [ ./configuration.nix ];
+ };
+ nixosModule = { ... }:
+ let
+ name = "amethyst";
+ fqdn = "amethyst.lava.moe";
+ subnet = "1";
+ in {
+ networking.nat = {
+ enable = true;
+ enableIPv6 = true;
+ internalInterfaces = [ "ve-${name}" ];
+ };
+
+ services.nginx.virtualHosts."${fqdn}" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ #locations."/".proxyPass = "http://[fd0d:1::${subnet}:2]:9091";
+ locations."/".proxyPass = "http://10.30.${subnet}.2:9091";
+ listenAddresses = [ "10.0.0.1" "[fd0d::1]" ];
+ };
+
+ systemd.tmpfiles.rules = [ "d /persist/containers/${name} 755 root users" ];
+ containers.${name} = {
+ autoStart = true;
+ privateNetwork = true;
+ hostAddress = "10.30.${subnet}.1";
+ localAddress = "10.30.${subnet}.2";
+ hostAddress6 = "fd0d:1::${subnet}:1";
+ localAddress6 = "fd0d:1::${subnet}:2";
+ # privateUsers = "pick";
+ nixpkgs = nixpkgs;
+ ephemeral = true;
+ config = { imports = [ ./configuration.nix ]; };
+
+ bindMounts."persist" = {
+ hostPath = "/persist/containers/${name}";
+ mountPoint = "/persist";
+ isReadOnly = false;
+ };
+ # flake = "path:" + ./.;
+ };
+ };
+ };
+}
diff --git a/containers/beryllium/configuration.nix b/containers/beryllium/configuration.nix
new file mode 100644
index 0000000..6629a31
--- /dev/null
+++ b/containers/beryllium/configuration.nix
@@ -0,0 +1,23 @@
+{ ... }: {
+ system.stateVersion = "25.11";
+ fileSystems."/var/lib/private" = {
+ device = "/persist";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ networking.firewall.allowedTCPPorts = [ 6167 ];
+ networking.firewall.allowedUDPPorts = [ 6167 ];
+ # TODO: this should be generically set
+ networking.useHostResolvConf = false;
+ networking.nameservers = [ "8.8.8.8" ];
+
+ services.matrix-continuwuity = {
+ enable = true;
+ settings.global = {
+ # TODO: link this with outer container's address
+ address = [ "10.30.2.2" ];
+ server_name = "lava.moe";
+ rocksdb_recovery_mode = 2;
+ };
+ };
+}
diff --git a/containers/beryllium/flake.lock b/containers/beryllium/flake.lock
new file mode 100644
index 0000000..88ab73f
--- /dev/null
+++ b/containers/beryllium/flake.lock
@@ -0,0 +1,27 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/containers/beryllium/flake.nix b/containers/beryllium/flake.nix
new file mode 100644
index 0000000..5805401
--- /dev/null
+++ b/containers/beryllium/flake.nix
@@ -0,0 +1,69 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ };
+ outputs = { nixpkgs, ... }: {
+ nixosConfigurations.container = nixpkgs.lib.nixosSystem {
+ modules = [ ./configuration.nix ];
+ };
+ nixosModule = { ... }:
+ let
+ name = "beryllium";
+ fqdn = "beryllium.lava.moe";
+ subnet = "2";
+ in {
+ networking.nat = {
+ enable = true;
+ enableIPv6 = true;
+ internalInterfaces = [ "ve-${name}" ];
+ };
+
+ services.nginx.virtualHosts."${fqdn}" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ locations."/".extraConfig = "return 302 'https://lava.moe';";
+ locations."/_matrix".proxyPass = "http://10.30.${subnet}.2:6167";
+ locations."/_conduwuit".proxyPass = "http://10.30.${subnet}.2:6167";
+ locations."/_continuwuity".proxyPass = "http://10.30.${subnet}.2:6167";
+ };
+
+ services.nginx.virtualHosts."lava.moe" = {
+ locations."= /.well-known/matrix/server".extraConfig =
+ let
+ server = { "m.server" = "${fqdn}:443"; };
+ in ''
+ add_header Content-Type application/json;
+ return 200 '${builtins.toJSON server}';
+ '';
+ locations."= /.well-known/matrix/client".extraConfig =
+ let
+ client = {
+ "m.homeserver" = { "base_url" = "https://${fqdn}"; };
+ # "m.identity_server" = { "base_url" = "https://vector.im"; };
+ };
+ in ''
+ add_header Content-Type application/json;
+ add_header Access-Control-Allow-Origin *;
+ return 200 '${builtins.toJSON client}';
+ '';
+ };
+
+ systemd.tmpfiles.rules = [ "d /persist/containers/${name} 755 root users" ];
+ containers.${name} = {
+ autoStart = true;
+ privateNetwork = true;
+ hostAddress = "10.30.${subnet}.1";
+ localAddress = "10.30.${subnet}.2";
+ nixpkgs = nixpkgs;
+ ephemeral = true;
+ config = { imports = [ ./configuration.nix ]; };
+
+ bindMounts."persist" = {
+ hostPath = "/persist/containers/${name}";
+ mountPoint = "/persist";
+ isReadOnly = false;
+ };
+ };
+ };
+ };
+}
diff --git a/containers/citrine/configuration.nix b/containers/citrine/configuration.nix
new file mode 100644
index 0000000..0f4242a
--- /dev/null
+++ b/containers/citrine/configuration.nix
@@ -0,0 +1,53 @@
+{ config, fqdn, lib, ... }: {
+ system.stateVersion = "25.11";
+ networking.firewall.allowedTCPPorts = [ 22 3000 ];
+ networking.firewall.allowedUDPPorts = [ 22 3000 ];
+
+ systemd.tmpfiles.rules = [
+ "L+ /persist/forgejo/custom/templates - - - - ${./templates}"
+ ];
+
+ services.forgejo = {
+ enable = true;
+ lfs.enable = true;
+ settings = {
+ DEFAULT.APP_NAME = "cilly's botanical laboratory";
+ server = {
+ DOMAIN = fqdn;
+ ROOT_URL = "https://${fqdn}/";
+ HTTP_PORT = 3000;
+ START_SSH_SERVER = true;
+ BUILTIN_SSH_SERVER_USER = "git";
+ SSH_DOMAIN = "git.lava.moe";
+ SSH_SERVER_KEY_EXCHANGES = "mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256";
+ };
+ ui = lib.mkForce {
+ DEFAULT_THEME = "catppuccin-maroon-auto";
+ THEMES = lib.strings.concatMapStringsSep "," (x: "${x}-auto") [
+ "catppuccin-pink"
+ "catppuccin-maroon"
+ "catppuccin-flamingo"
+ "catppuccin-rosewater"
+ "forgejo"
+ "gitea"
+ ];
+ };
+ api.ENABLE_SWAGGER = false;
+ other.SHOW_FOOTER_TEMPLATE_LOAD_TIME = false;
+ repository.ENABLE_PUSH_CREATE_USER = true;
+ repository.ENABLE_PUSH_CREATE_ORG = true;
+ service.DISABLE_REGISTRATION = true;
+ };
+ stateDir = "/persist/forgejo";
+ };
+
+ systemd.services.forgejo.serviceConfig = {
+ AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
+ CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
+ PrivateUsers = lib.mkForce false;
+ };
+
+ catppuccin.forgejo.enable = true;
+
+ environment.systemPackages = [ config.services.forgejo.package ];
+}
diff --git a/containers/citrine/flake.lock b/containers/citrine/flake.lock
new file mode 100644
index 0000000..d627614
--- /dev/null
+++ b/containers/citrine/flake.lock
@@ -0,0 +1,62 @@
+{
+ "nodes": {
+ "catppuccin": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ },
+ "locked": {
+ "lastModified": 1773403535,
+ "narHash": "sha256-47MZaFrHxNO8tVUAmtVnerXUw2WWVluBOiU9MulN/yM=",
+ "owner": "catppuccin",
+ "repo": "nix",
+ "rev": "d45b5665cc638bad1b794350de02f4dd41b0bb47",
+ "type": "github"
+ },
+ "original": {
+ "owner": "catppuccin",
+ "repo": "nix",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1773122722,
+ "narHash": "sha256-FIqHByVqxCprNjor1NqF80F2QQoiiyqanNNefdlvOg4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "62dc67aa6a52b4364dd75994ec00b51fbf474e50",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "catppuccin": "catppuccin",
+ "nixpkgs": "nixpkgs_2"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/containers/citrine/flake.nix b/containers/citrine/flake.nix
new file mode 100644
index 0000000..c2a81b7
--- /dev/null
+++ b/containers/citrine/flake.nix
@@ -0,0 +1,68 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ catppuccin.url = "github:catppuccin/nix";
+ };
+ outputs = { nixpkgs, catppuccin, ... }:
+ let
+ name = "citrine";
+ fqdn = "lab.lava.moe";
+ subnetId = "3";
+
+ subnet = x: "fd0d:1::${subnetId}:${toString x}";
+ host = subnet 1;
+ client = subnet 2;
+
+ subnet4 = x: "10.30.${subnetId}.${toString x}";
+ host4 = subnet4 1;
+ client4 = subnet4 2;
+
+ modules = [
+ ./configuration.nix
+ catppuccin.nixosModules.catppuccin
+ {
+ networking.useHostResolvConf = false;
+ networking.nameservers = [ host ];
+ }
+ ];
+ in {
+ nixosConfigurations.container = nixpkgs.lib.nixosSystem {
+ inherit modules;
+ };
+ nixosModule = { ... }: {
+ networking.nat = {
+ enable = true;
+ enableIPv6 = true;
+ internalInterfaces = [ "ve-${name}" ];
+ };
+
+ services.nginx.virtualHosts."${fqdn}" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ locations."/".proxyPass = "http://[${client}]:3000";
+ };
+
+ systemd.tmpfiles.rules = [ "d /persist/containers/${name} 755 root users" ];
+ containers.${name} = {
+ autoStart = true;
+ privateNetwork = true;
+ hostAddress = host4;
+ localAddress = client4;
+ hostAddress6 = host;
+ localAddress6 = client;
+ # privateUsers = "pick";
+ nixpkgs = nixpkgs;
+ ephemeral = true;
+ config = { imports = modules; };
+ specialArgs = { inherit fqdn; };
+
+ bindMounts."persist" = {
+ hostPath = "/persist/containers/${name}";
+ mountPoint = "/persist";
+ isReadOnly = false;
+ };
+ # flake = "path:" + ./.;
+ };
+ };
+ };
+}
diff --git a/containers/citrine/templates/base/footer_content.tmpl b/containers/citrine/templates/base/footer_content.tmpl
new file mode 100644
index 0000000..a9238c3
--- /dev/null
+++ b/containers/citrine/templates/base/footer_content.tmpl
@@ -0,0 +1,31 @@
+
diff --git a/containers/citrine/templates/home.tmpl b/containers/citrine/templates/home.tmpl
new file mode 100644
index 0000000..d460caf
--- /dev/null
+++ b/containers/citrine/templates/home.tmpl
@@ -0,0 +1,19 @@
+{{template "base/head" .}}
+{{if not .IsSigned}}
+
+{{end}}
+
+
+
+

+
+
+
{{ctx.Locale.Tr "startpage.app_desc"}}
+
+
+
+ {{template "home_forgejo" .}}
+
+{{template "base/footer" .}}
diff --git a/containers/diamond/configuration.nix b/containers/diamond/configuration.nix
new file mode 100644
index 0000000..01b4311
--- /dev/null
+++ b/containers/diamond/configuration.nix
@@ -0,0 +1,22 @@
+{ fqdn, ... }: {
+ system.stateVersion = "25.11";
+ systemd.tmpfiles.rules = [
+ "d /persist/vaultwarden 755 vaultwarden vaultwarden"
+ ];
+ fileSystems."/var/lib/vaultwarden" = {
+ device = "/persist/vaultwarden";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ networking.firewall.allowedTCPPorts = [ 8000 ];
+ networking.firewall.allowedUDPPorts = [ 8000 ];
+
+ services.vaultwarden = {
+ enable = true;
+ domain = fqdn;
+ config = {
+ DOMAIN = "https://${fqdn}";
+ ROCKET_ADDRESS = "::";
+ };
+ };
+}
diff --git a/containers/diamond/flake.lock b/containers/diamond/flake.lock
new file mode 100644
index 0000000..88ab73f
--- /dev/null
+++ b/containers/diamond/flake.lock
@@ -0,0 +1,27 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/containers/diamond/flake.nix b/containers/diamond/flake.nix
new file mode 100644
index 0000000..71ab4fd
--- /dev/null
+++ b/containers/diamond/flake.nix
@@ -0,0 +1,51 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ };
+ outputs = { nixpkgs, ... }:
+ let
+ name = "diamond";
+ fqdn = "astransia.lava.moe";
+ subnetId = "4";
+
+ subnet = x: "fd0d:1::${subnetId}:${toString x}";
+ host = subnet 1;
+ client = subnet 2;
+
+ modules = [
+ ./configuration.nix
+ ];
+ in {
+ nixosConfigurations.container = nixpkgs.lib.nixosSystem {
+ inherit modules;
+ };
+ nixosModule = { ... }: {
+ services.nginx.virtualHosts."${fqdn}" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ locations."/".proxyPass = "http://[${client}]:8000";
+ listenAddresses = [ "10.0.0.1" "[fd0d::1]" "100.67.1.1" ];
+ };
+
+ systemd.tmpfiles.rules = [ "d /persist/containers/${name} 755 root users" ];
+ containers.${name} = {
+ autoStart = true;
+ privateNetwork = true;
+ hostAddress6 = host;
+ localAddress6 = client;
+ # privateUsers = "pick";
+ nixpkgs = nixpkgs;
+ ephemeral = true;
+ config = { imports = modules; };
+ specialArgs = { inherit fqdn; };
+
+ bindMounts."persist" = {
+ hostPath = "/persist/containers/${name}";
+ mountPoint = "/persist";
+ isReadOnly = false;
+ };
+ # flake = "path:" + ./.;
+ };
+ };
+ };
+}
diff --git a/containers/emerald/configuration.nix b/containers/emerald/configuration.nix
new file mode 100644
index 0000000..421ddb0
--- /dev/null
+++ b/containers/emerald/configuration.nix
@@ -0,0 +1,23 @@
+{ fqdn, shareFqdn, ... }: {
+ system.stateVersion = "25.11";
+ systemd.tmpfiles.rules = [
+ "d /persist/navidrome 755 navidrome navidrome"
+ ];
+ networking.firewall.allowedTCPPorts = [ 4533 ];
+ networking.firewall.allowedUDPPorts = [ 4533 ];
+
+ services.navidrome = {
+ enable = true;
+ environmentFile = "/binds/navidrome_env";
+ settings = {
+ Port = 4533;
+ Address = "[::]";
+ BaseUrl = "https://${fqdn}/";
+ ShareURL = "https://${shareFqdn}";
+ EnableSharing = true;
+ DataFolder = "/persist/navidrome";
+ MusicFolder = "/binds/music/main";
+ };
+ };
+ systemd.services.navidrome.serviceConfig.BindReadOnlyPaths = ["/binds/music"];
+}
diff --git a/containers/emerald/flake.lock b/containers/emerald/flake.lock
new file mode 100644
index 0000000..88ab73f
--- /dev/null
+++ b/containers/emerald/flake.lock
@@ -0,0 +1,27 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/containers/emerald/flake.nix b/containers/emerald/flake.nix
new file mode 100644
index 0000000..5ee69e4
--- /dev/null
+++ b/containers/emerald/flake.nix
@@ -0,0 +1,78 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ };
+ outputs = { nixpkgs, ... }:
+ let
+ name = "emerald";
+ fqdn = "navia.lava.moe";
+ shareFqdn = "muse.lava.moe";
+ subnetId = "5";
+
+ subnet = x: "fd0d:2::${subnetId}:${toString x}";
+ host = subnet 1;
+ client = subnet 2;
+
+ subnet4 = x: "10.32.${subnetId}.${toString x}";
+ host4 = subnet4 1;
+ client4 = subnet4 2;
+
+ modules = [
+ ./configuration.nix
+ {
+ networking.useHostResolvConf = false;
+ networking.nameservers = [ host ];
+ }
+ ];
+ in {
+ nixosConfigurations.container = nixpkgs.lib.nixosSystem {
+ inherit modules;
+ };
+ nixosModule = { config, ... }: {
+ networking.nat = {
+ enable = true;
+ enableIPv6 = true;
+ internalInterfaces = [ "ve-${name}" ];
+ };
+
+ services.nginx.virtualHosts."${fqdn}" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ locations."/".proxyPass = "http://[${client}]:4533";
+ listenAddresses = [ "100.67.2.1" ];
+ };
+
+ systemd.tmpfiles.rules = [ "d /persist/containers/${name} 755 root users" ];
+ containers.${name} = {
+ autoStart = true;
+ privateNetwork = true;
+ hostAddress = host4;
+ localAddress = client4;
+ hostAddress6 = host;
+ localAddress6 = client;
+ # privateUsers = "pick";
+ nixpkgs = nixpkgs;
+ ephemeral = true;
+ config = { imports = modules; };
+ specialArgs = { inherit fqdn shareFqdn; };
+
+ bindMounts."persist" = {
+ hostPath = "/persist/containers/${name}";
+ mountPoint = "/persist";
+ isReadOnly = false;
+ };
+ bindMounts."music" = {
+ hostPath = "/flower/media/music";
+ mountPoint = "/binds/music";
+ isReadOnly = true;
+ };
+ bindMounts."navidrome_env" = {
+ hostPath = config.age.secrets.navidrome_env.path;
+ mountPoint = "/binds/navidrome_env";
+ isReadOnly = true;
+ };
+ # flake = "path:" + ./.;
+ };
+ };
+ };
+}
diff --git a/containers/fluorite/configuration.nix b/containers/fluorite/configuration.nix
new file mode 100644
index 0000000..9fcb5f5
--- /dev/null
+++ b/containers/fluorite/configuration.nix
@@ -0,0 +1,22 @@
+{ ... }: {
+ system.stateVersion = "25.11";
+ systemd.tmpfiles.rules = [
+ "d /persist/slskd/Downloads 755 slskd slskd"
+ ];
+ fileSystems."/var/lib/slskd" = {
+ device = "/persist/slskd";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ networking.firewall.allowedTCPPorts = [ 5030 50300 ];
+ networking.firewall.allowedUDPPorts = [ 5030 50300 ];
+
+ services.slskd = {
+ enable = true;
+ domain = null;
+ environmentFile = "/binds/slskd_env";
+ settings = {
+ shares.directories = [ "/binds/music/" ];
+ };
+ };
+}
diff --git a/containers/fluorite/flake.lock b/containers/fluorite/flake.lock
new file mode 100644
index 0000000..88ab73f
--- /dev/null
+++ b/containers/fluorite/flake.lock
@@ -0,0 +1,27 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/containers/fluorite/flake.nix b/containers/fluorite/flake.nix
new file mode 100644
index 0000000..33fcdb1
--- /dev/null
+++ b/containers/fluorite/flake.nix
@@ -0,0 +1,89 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ };
+ outputs = { nixpkgs, ... }:
+ let
+ name = "fluorite";
+ fqdn = "fluorite.lava.moe";
+ subnetId = "6";
+
+ subnet = x: "fd0d:1::${subnetId}:${toString x}";
+ host = subnet 1;
+ client = subnet 2;
+
+ subnet4 = x: "10.30.${subnetId}.${toString x}";
+ host4 = subnet4 1;
+ client4 = subnet4 2;
+
+ modules = [
+ ./configuration.nix
+ {
+ networking.useHostResolvConf = false;
+ networking.nameservers = [ host ];
+ }
+ ];
+ in {
+ nixosConfigurations.container = nixpkgs.lib.nixosSystem {
+ inherit modules;
+ };
+ nixosModule = { config, ... }: {
+ networking.nat = {
+ enable = true;
+ enableIPv6 = true;
+ internalInterfaces = [ "ve-${name}" ];
+ };
+ networking.firewall.allowedTCPPorts = [ 50300 ];
+
+ services.nginx.virtualHosts."${fqdn}" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ locations."/".proxyPass = "http://[${client}]:5030";
+ listenAddresses = [ "10.0.0.1" "[fd0d::1]" "100.67.1.1" ];
+ };
+
+ systemd.tmpfiles.rules = [
+ "d /persist/containers/${name} 755 root users"
+ "d /persist/media/music 075 nobody users"
+ ];
+ containers.${name} = {
+ autoStart = true;
+ privateNetwork = true;
+ hostAddress = host4;
+ localAddress = client4;
+ hostAddress6 = host;
+ localAddress6 = client;
+ # privateUsers = "pick";
+ nixpkgs = nixpkgs;
+ ephemeral = true;
+ config = { imports = modules; };
+ specialArgs = { inherit fqdn; };
+
+ forwardPorts = [
+ {
+ containerPort = 50300;
+ hostPort = 50300;
+ protocol = "tcp";
+ }
+ ];
+
+ bindMounts."persist" = {
+ hostPath = "/persist/containers/${name}";
+ mountPoint = "/persist";
+ isReadOnly = false;
+ };
+ bindMounts."music" = {
+ hostPath = "/persist/media/music";
+ mountPoint = "/binds/music";
+ isReadOnly = true;
+ };
+ bindMounts."slskd_env" = {
+ hostPath = config.age.secrets.slskd_env.path;
+ mountPoint = "/binds/slskd_env";
+ isReadOnly = true;
+ };
+ # flake = "path:" + ./.;
+ };
+ };
+ };
+}
diff --git a/containers/garnet/configuration.nix b/containers/garnet/configuration.nix
new file mode 100644
index 0000000..21400c5
--- /dev/null
+++ b/containers/garnet/configuration.nix
@@ -0,0 +1,36 @@
+{ ... }: {
+ system.stateVersion = "25.11";
+ fileSystems."/var/lib/opencloud" = {
+ device = "/flower/data";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ fileSystems."/etc/opencloud" = {
+ device = "/persist/cfg";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ # TODO: hardcoded address
+ networking.extraHosts = ''
+ 100.67.2.1 cloud.lava.moe
+ '';
+
+ networking.firewall.allowedTCPPorts = [ 9200 ];
+ networking.firewall.allowedUDPPorts = [ 9200 ];
+
+ environment.etc."opencloud-admin-pass".text = ''
+ IDM_ADMIN_PASSWORD=supersillysecure
+ '';
+ services.opencloud = {
+ enable = true;
+ url = "https://cloud.lava.moe";
+ address = "10.30.7.2";
+ port = 9200;
+ environment = {
+ PROXY_TLS = "false";
+ IDP_ACCESS_TOKEN_EXPIRATION = "2592000";
+ IDP_ID_TOKEN_EXPIRATION = "2592000";
+ };
+ environmentFile = "/etc/opencloud-admin-pass";
+ };
+}
diff --git a/containers/garnet/flake.lock b/containers/garnet/flake.lock
new file mode 100644
index 0000000..4070242
--- /dev/null
+++ b/containers/garnet/flake.lock
@@ -0,0 +1,27 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1779560665,
+ "narHash": "sha256-tpyBcxPpcQb8ukyNF7DoCwfSY3VPsxHoYwj00Cayv5o=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "64c08a7ca051951c8eae34e3e3cb1e202fe36786",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/containers/garnet/flake.nix b/containers/garnet/flake.nix
new file mode 100644
index 0000000..df835a4
--- /dev/null
+++ b/containers/garnet/flake.nix
@@ -0,0 +1,84 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ };
+ outputs = { nixpkgs, ... }:
+ let
+ name = "garnet";
+ fqdn = "cloud.lava.moe";
+ subnetId = "7";
+
+ subnet = x: "fd0d:1::${subnetId}:${toString x}";
+ host = subnet 1;
+ client = subnet 2;
+
+ subnet4 = x: "10.30.${subnetId}.${toString x}";
+ host4 = subnet4 1;
+ client4 = subnet4 2;
+
+ modules = [
+ ./configuration.nix
+ {
+ networking.useHostResolvConf = false;
+ networking.nameservers = [ host ];
+ }
+ ];
+ in {
+ nixosConfigurations.container = nixpkgs.lib.nixosSystem {
+ inherit modules;
+ };
+ nixosModule = { config, ... }: {
+ networking.nat = {
+ enable = true;
+ enableIPv6 = true;
+ internalInterfaces = [ "ve-${name}" ];
+ };
+
+ services.nginx.virtualHosts."${fqdn}" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://${client4}:9200";
+ proxyWebsockets = true;
+ };
+ extraConfig = ''
+ proxy_read_timeout 3600s;
+ proxy_send_timeout 3600s;
+ keepalive_requests 100000;
+ keepalive_timeout 5m;
+ http2_max_concurrent_streams 512;
+ '';
+ # TODO: hardcoded address
+ listenAddresses = [ "100.67.2.1" ];
+ };
+
+ systemd.tmpfiles.rules = [
+ "d /persist/containers/${name} 755 root users"
+ ];
+ containers.${name} = {
+ autoStart = true;
+ privateNetwork = true;
+ hostAddress = host4;
+ localAddress = client4;
+ hostAddress6 = host;
+ localAddress6 = client;
+ # privateUsers = "pick";
+ nixpkgs = nixpkgs;
+ ephemeral = true;
+ config = { imports = modules; };
+ specialArgs = { inherit fqdn; };
+
+ bindMounts."persist" = {
+ hostPath = "/persist/containers/${name}";
+ mountPoint = "/persist";
+ isReadOnly = false;
+ };
+ bindMounts."content" = {
+ hostPath = "/flower/opencloud";
+ mountPoint = "/flower";
+ isReadOnly = false;
+ };
+ };
+ };
+ };
+}
diff --git a/flake.lock b/flake.lock
index d59f3ff..2578a7e 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,33 +1,720 @@
{
"nodes": {
+ "aagl": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "nixpkgs": "nixpkgs",
+ "rust-overlay": "rust-overlay"
+ },
+ "locked": {
+ "lastModified": 1779903856,
+ "narHash": "sha256-uRShMtD6xW3ZKZbCQ6sDzKWEnbBXUg3IGfOARYogKhg=",
+ "owner": "ezKEa",
+ "repo": "aagl-gtk-on-nix",
+ "rev": "50671fc7f29d686f63ef34b603320d44ad7f2d29",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ezKEa",
+ "repo": "aagl-gtk-on-nix",
+ "type": "github"
+ }
+ },
+ "agenix": {
+ "inputs": {
+ "darwin": "darwin",
+ "home-manager": "home-manager",
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1770165109,
+ "narHash": "sha256-9VnK6Oqai65puVJ4WYtCTvlJeXxMzAp/69HhQuTdl/I=",
+ "owner": "ryantm",
+ "repo": "agenix",
+ "rev": "b027ee29d959fda4b60b57566d64c98a202e0feb",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ryantm",
+ "repo": "agenix",
+ "type": "github"
+ }
+ },
+ "c-amethyst": {
+ "inputs": {
+ "nixpkgs": "nixpkgs_2"
+ },
+ "locked": {
+ "path": "./containers/amethyst",
+ "type": "path"
+ },
+ "original": {
+ "path": "./containers/amethyst",
+ "type": "path"
+ },
+ "parent": []
+ },
+ "c-beryllium": {
+ "inputs": {
+ "nixpkgs": "nixpkgs_3"
+ },
+ "locked": {
+ "path": "./containers/beryllium",
+ "type": "path"
+ },
+ "original": {
+ "path": "./containers/beryllium",
+ "type": "path"
+ },
+ "parent": []
+ },
+ "c-citrine": {
+ "inputs": {
+ "catppuccin": "catppuccin",
+ "nixpkgs": "nixpkgs_5"
+ },
+ "locked": {
+ "path": "./containers/citrine",
+ "type": "path"
+ },
+ "original": {
+ "path": "./containers/citrine",
+ "type": "path"
+ },
+ "parent": []
+ },
+ "c-diamond": {
+ "inputs": {
+ "nixpkgs": "nixpkgs_6"
+ },
+ "locked": {
+ "path": "./containers/diamond",
+ "type": "path"
+ },
+ "original": {
+ "path": "./containers/diamond",
+ "type": "path"
+ },
+ "parent": []
+ },
+ "c-emerald": {
+ "inputs": {
+ "nixpkgs": "nixpkgs_7"
+ },
+ "locked": {
+ "path": "./containers/emerald",
+ "type": "path"
+ },
+ "original": {
+ "path": "./containers/emerald",
+ "type": "path"
+ },
+ "parent": []
+ },
+ "c-fluorite": {
+ "inputs": {
+ "nixpkgs": "nixpkgs_8"
+ },
+ "locked": {
+ "path": "./containers/fluorite",
+ "type": "path"
+ },
+ "original": {
+ "path": "./containers/fluorite",
+ "type": "path"
+ },
+ "parent": []
+ },
+ "c-garnet": {
+ "inputs": {
+ "nixpkgs": "nixpkgs_9"
+ },
+ "locked": {
+ "path": "./containers/garnet",
+ "type": "path"
+ },
+ "original": {
+ "path": "./containers/garnet",
+ "type": "path"
+ },
+ "parent": []
+ },
+ "catppuccin": {
+ "inputs": {
+ "nixpkgs": "nixpkgs_4"
+ },
+ "locked": {
+ "lastModified": 1773403535,
+ "narHash": "sha256-47MZaFrHxNO8tVUAmtVnerXUw2WWVluBOiU9MulN/yM=",
+ "owner": "catppuccin",
+ "repo": "nix",
+ "rev": "d45b5665cc638bad1b794350de02f4dd41b0bb47",
+ "type": "github"
+ },
+ "original": {
+ "owner": "catppuccin",
+ "repo": "nix",
+ "type": "github"
+ }
+ },
+ "catppuccin-palette": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1774131488,
+ "narHash": "sha256-hsy+GhuM4MSjnwGq1YJSLBFIbVm67SSdPRgObP00mxw=",
+ "owner": "catppuccin",
+ "repo": "palette",
+ "rev": "07d02aa110ef9eb7e7427afca5c73ba9cf7f8ebd",
+ "type": "github"
+ },
+ "original": {
+ "owner": "catppuccin",
+ "repo": "palette",
+ "type": "github"
+ }
+ },
+ "catppuccin-v1_1": {
+ "locked": {
+ "lastModified": 1734055249,
+ "narHash": "sha256-pCWJgwo77KD7EJpwynwKrWPZ//dwypHq2TfdzZWqK68=",
+ "rev": "7221d6ca17ac36ed20588e1c3a80177ac5843fa7",
+ "revCount": 326,
+ "type": "tarball",
+ "url": "https://api.flakehub.com/f/pinned/catppuccin/nix/1.1.1/0193bdc0-b045-7eed-bbec-95611a8ecdf5/source.tar.gz"
+ },
+ "original": {
+ "type": "tarball",
+ "url": "https://flakehub.com/f/catppuccin/nix/1.1.%2A.tar.gz"
+ }
+ },
+ "catppuccin-v1_2": {
+ "locked": {
+ "lastModified": 1734728407,
+ "narHash": "sha256-Let3uJo4YDyfqbqaw66dpZxhJB2TrDyZWSFd5rpPLJA=",
+ "rev": "23ee86dbf4ed347878115a78971d43025362fab1",
+ "revCount": 341,
+ "type": "tarball",
+ "url": "https://api.flakehub.com/f/pinned/catppuccin/nix/1.2.0/0193e5e0-33b7-7149-a362-bfe56b20f64e/source.tar.gz"
+ },
+ "original": {
+ "type": "tarball",
+ "url": "https://flakehub.com/f/catppuccin/nix/1.2.%2A.tar.gz"
+ }
+ },
+ "catppuccin_2": {
+ "inputs": {
+ "catppuccin-v1_1": "catppuccin-v1_1",
+ "catppuccin-v1_2": "catppuccin-v1_2",
+ "home-manager": "home-manager_2",
+ "home-manager-stable": "home-manager-stable",
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "nixpkgs-stable": "nixpkgs-stable",
+ "nuscht-search": "nuscht-search"
+ },
+ "locked": {
+ "lastModified": 1736069220,
+ "narHash": "sha256-76MaB3COao55nlhWmSmq9PKgu2iGIs54C1cAE0E5J6Y=",
+ "owner": "catppuccin",
+ "repo": "nix",
+ "rev": "8eada392fd6571a747e1c5fc358dd61c14c8704e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "catppuccin",
+ "repo": "nix",
+ "rev": "8eada392fd6571a747e1c5fc358dd61c14c8704e",
+ "type": "github"
+ }
+ },
+ "darwin": {
+ "inputs": {
+ "nixpkgs": [
+ "agenix",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1744478979,
+ "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=",
+ "owner": "lnl7",
+ "repo": "nix-darwin",
+ "rev": "43975d782b418ebf4969e9ccba82466728c2851b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "lnl7",
+ "ref": "master",
+ "repo": "nix-darwin",
+ "type": "github"
+ }
+ },
+ "fast-syntax-highlighting": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1752660993,
+ "narHash": "sha256-ZihUL4JAVk9V+IELSakytlb24BvEEJ161CQEHZYYoSA=",
+ "owner": "zdharma-continuum",
+ "repo": "fast-syntax-highlighting",
+ "rev": "3d574ccf48804b10dca52625df13da5edae7f553",
+ "type": "github"
+ },
+ "original": {
+ "owner": "zdharma-continuum",
+ "repo": "fast-syntax-highlighting",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1767039857,
+ "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-compat_2": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1767039857,
+ "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
+ "owner": "NixOS",
+ "repo": "flake-compat",
+ "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": [
+ "neovim-nightly",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1778716662,
+ "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-parts_2": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1778716662,
+ "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems_2"
+ },
+ "locked": {
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_2": {
+ "inputs": {
+ "systems": "systems_3"
+ },
+ "locked": {
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_3": {
+ "inputs": {
+ "systems": "systems_4"
+ },
+ "locked": {
+ "lastModified": 1701680307,
+ "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "git-hooks": {
+ "inputs": {
+ "flake-compat": "flake-compat_2",
+ "gitignore": "gitignore",
+ "nixpkgs": [
+ "nix-gaming",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1778507602,
+ "narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
+ "owner": "cachix",
+ "repo": "git-hooks.nix",
+ "rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "git-hooks.nix",
+ "type": "github"
+ }
+ },
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "nix-gaming",
+ "git-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1709087332,
+ "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
"home-manager": {
+ "inputs": {
+ "nixpkgs": [
+ "agenix",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1745494811,
+ "narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=",
+ "owner": "nix-community",
+ "repo": "home-manager",
+ "rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "home-manager",
+ "type": "github"
+ }
+ },
+ "home-manager-stable": {
+ "inputs": {
+ "nixpkgs": [
+ "catppuccin",
+ "nixpkgs-stable"
+ ]
+ },
+ "locked": {
+ "lastModified": 1734366194,
+ "narHash": "sha256-vykpJ1xsdkv0j8WOVXrRFHUAdp9NXHpxdnn1F4pYgSw=",
+ "owner": "nix-community",
+ "repo": "home-manager",
+ "rev": "80b0fdf483c5d1cb75aaad909bd390d48673857f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "ref": "release-24.11",
+ "repo": "home-manager",
+ "type": "github"
+ }
+ },
+ "home-manager_2": {
+ "inputs": {
+ "nixpkgs": [
+ "catppuccin",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1734622215,
+ "narHash": "sha256-OOfI0XhSJGHblfdNDhfnn8QnZxng63rWk9eeJ2tCbiI=",
+ "owner": "nix-community",
+ "repo": "home-manager",
+ "rev": "1395379a7a36e40f2a76e7b9936cc52950baa1be",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "home-manager",
+ "type": "github"
+ }
+ },
+ "home-manager_3": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
- "lastModified": 1624718580,
- "narHash": "sha256-hzt3zC4lm7XvvEISpaJirotBOo7XYdeI3cVslT/BvMw=",
- "owner": "LavaDesu",
+ "lastModified": 1779969295,
+ "narHash": "sha256-HwIJ3tOcwSMiV75L7KqJXciXR9UfT+d7rwOZMX7cTnA=",
+ "owner": "nix-community",
"repo": "home-manager",
- "rev": "c52a96d07de8930de256ffeffd82314757f7a5da",
+ "rev": "61e2c9659324181e0f0ed911958c536333b1d4f6",
"type": "github"
},
"original": {
- "owner": "LavaDesu",
- "ref": "aa",
+ "owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
+ "ixx": {
+ "inputs": {
+ "flake-utils": [
+ "catppuccin",
+ "nuscht-search",
+ "flake-utils"
+ ],
+ "nixpkgs": [
+ "catppuccin",
+ "nuscht-search",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1729958008,
+ "narHash": "sha256-EiOq8jF4Z/zQe0QYVc3+qSKxRK//CFHMB84aYrYGwEs=",
+ "owner": "NuschtOS",
+ "repo": "ixx",
+ "rev": "9fd01aad037f345350eab2cd45e1946cc66da4eb",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NuschtOS",
+ "ref": "v0.0.6",
+ "repo": "ixx",
+ "type": "github"
+ }
+ },
+ "linux-tkg": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1779857514,
+ "narHash": "sha256-dCrVB3cFvv1d/9wuEejYN131b1phyf6SDy1bcEvtWGo=",
+ "owner": "Frogging-Family",
+ "repo": "linux-tkg",
+ "rev": "c9196dea7ee464f7792f94cd39c32431ad9e25ab",
+ "type": "github"
+ },
+ "original": {
+ "owner": "Frogging-Family",
+ "repo": "linux-tkg",
+ "type": "github"
+ }
+ },
+ "neovim-nightly": {
+ "inputs": {
+ "flake-parts": "flake-parts",
+ "neovim-src": "neovim-src",
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1780013080,
+ "narHash": "sha256-m984DKbcIeNNuLYFjN3780rPEd55Xe9/cB4BNKkIDvg=",
+ "owner": "nix-community",
+ "repo": "neovim-nightly-overlay",
+ "rev": "c6cc238427db8f61b786a66d7e02cf7724b30226",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "neovim-nightly-overlay",
+ "type": "github"
+ }
+ },
+ "neovim-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1779979065,
+ "narHash": "sha256-3uF/oP2D4Jka3DU2G8qqml75UOzPRrK+FIp+jghOq0s=",
+ "owner": "neovim",
+ "repo": "neovim",
+ "rev": "5d85669a33e10f1f156b086562458cbbc8054438",
+ "type": "github"
+ },
+ "original": {
+ "owner": "neovim",
+ "repo": "neovim",
+ "type": "github"
+ }
+ },
+ "nix-gaming": {
+ "inputs": {
+ "flake-parts": "flake-parts_2",
+ "git-hooks": "git-hooks",
+ "nixpkgs": "nixpkgs_10"
+ },
+ "locked": {
+ "lastModified": 1779768228,
+ "narHash": "sha256-/dRavNAx/Mp67xcQQ3JBIMyf0cLoXqKedafB1+wksAE=",
+ "owner": "fufexan",
+ "repo": "nix-gaming",
+ "rev": "6e7a8414c0f547a86646eb0b56ebf89e7cc217a2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "fufexan",
+ "repo": "nix-gaming",
+ "type": "github"
+ }
+ },
+ "nix-index-database": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1779604987,
+ "narHash": "sha256-ZQ5z+fVhxYKtIFwtqGp5O0PD84BM1riASvqDaN5Xs+s=",
+ "owner": "nix-community",
+ "repo": "nix-index-database",
+ "rev": "8fba98c80b48fa013820e0163c5096922fea4ddd",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "nix-index-database",
+ "type": "github"
+ }
+ },
"nixpkgs": {
"locked": {
- "lastModified": 1624271441,
- "narHash": "sha256-26QNDCdRE5mPOWYJrPGpVzgrJ3ZxqvWOONfeMsjryz4=",
+ "lastModified": 1777268161,
+ "narHash": "sha256-bxrdOn8SCOv8tN4JbTF/TXq7kjo9ag4M+C8yzzIRYbE=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "1c3fe55ad329cbcb28471bb30f05c9827f724c76",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "lastModified": 1777168982,
+ "narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=",
+ "owner": "nix-community",
+ "repo": "nixpkgs.lib",
+ "rev": "f5901329dade4a6ea039af1433fb087bd9c1fe14",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "nixpkgs.lib",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable": {
+ "locked": {
+ "lastModified": 1734600368,
+ "narHash": "sha256-nbG9TijTMcfr+au7ZVbKpAhMJzzE2nQBYmRvSdXUD8g=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "7e567a3d092b7de69cdf5deaeb8d9526de230916",
+ "rev": "b47fd6fa00c6afca88b8ee46cfdb00e104f50bca",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-24.11",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_10": {
+ "locked": {
+ "lastModified": 1779536132,
+ "narHash": "sha256-q+fF42iv/geEbHfgSzy3tS0FF/EyD6XTZ98E6yxiBO8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "3d8f0f3f72a6cd4d93d0ad13203f2ea1cb7e1456",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_11": {
+ "locked": {
+ "lastModified": 1779560665,
+ "narHash": "sha256-tpyBcxPpcQb8ukyNF7DoCwfSY3VPsxHoYwj00Cayv5o=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "64c08a7ca051951c8eae34e3e3cb1e202fe36786",
"type": "github"
},
"original": {
@@ -37,25 +724,510 @@
"type": "github"
}
},
- "root": {
- "inputs": {
- "home-manager": "home-manager",
- "nixpkgs": "nixpkgs",
- "secrets": "secrets"
- }
- },
- "secrets": {
+ "nixpkgs_12": {
"locked": {
- "lastModified": 1621557628,
- "narHash": "sha256-exoyO1kp/2Pheentn1MPHU9gbx/wtbkPay3aoC0ooOM=",
- "owner": "LavaDesu",
- "repo": "flakes-secrets",
- "rev": "365392dd012cb896fcbbedbd8b05ad91fcf0b56a",
+ "lastModified": 1770019141,
+ "narHash": "sha256-VKS4ZLNx4PNrABoB0L8KUpc1fE7CLpQXQs985tGfaCU=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "cb369ef2efd432b3cdf8622b0ffc0a97a02f3137",
"type": "github"
},
"original": {
- "owner": "LavaDesu",
- "repo": "flakes-secrets",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_3": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_4": {
+ "locked": {
+ "lastModified": 1773122722,
+ "narHash": "sha256-FIqHByVqxCprNjor1NqF80F2QQoiiyqanNNefdlvOg4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "62dc67aa6a52b4364dd75994ec00b51fbf474e50",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_5": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_6": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_7": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_8": {
+ "locked": {
+ "lastModified": 1773282481,
+ "narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_9": {
+ "locked": {
+ "lastModified": 1779560665,
+ "narHash": "sha256-tpyBcxPpcQb8ukyNF7DoCwfSY3VPsxHoYwj00Cayv5o=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "64c08a7ca051951c8eae34e3e3cb1e202fe36786",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nuscht-search": {
+ "inputs": {
+ "flake-utils": "flake-utils",
+ "ixx": "ixx",
+ "nixpkgs": [
+ "catppuccin",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1733773348,
+ "narHash": "sha256-Y47y+LesOCkJaLvj+dI/Oa6FAKj/T9sKVKDXLNsViPw=",
+ "owner": "NuschtOS",
+ "repo": "search",
+ "rev": "3051be7f403bff1d1d380e4612f0c70675b44fc9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NuschtOS",
+ "repo": "search",
+ "type": "github"
+ }
+ },
+ "nvim-treesitter": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1775221900,
+ "narHash": "sha256-PQR6tFt4lCrAZNQG7BLMD1IiCKja9wDS1S4laGJf/HE=",
+ "owner": "nvim-treesitter",
+ "repo": "nvim-treesitter",
+ "rev": "4916d6592ede8c07973490d9322f187e07dfefac",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nvim-treesitter",
+ "repo": "nvim-treesitter",
+ "type": "github"
+ }
+ },
+ "pastel": {
+ "inputs": {
+ "flake-utils": "flake-utils_2",
+ "nixpkgs": "nixpkgs_12",
+ "pnpm2nix": "pnpm2nix"
+ },
+ "locked": {
+ "lastModified": 1775622883,
+ "narHash": "sha256-2+7uCRXn+tn4LVaO7hLKPaezdKPW6HGvTr00aO4Tcxs=",
+ "owner": "cillynder",
+ "repo": "pastel",
+ "rev": "46f6569d5ad41ec1256dbf999d21701f73d6077b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cillynder",
+ "repo": "pastel",
+ "type": "github"
+ }
+ },
+ "pnpm2nix": {
+ "inputs": {
+ "flake-utils": "flake-utils_3",
+ "nixpkgs": [
+ "pastel",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1717937937,
+ "narHash": "sha256-bKoHjG5P15vCVpDndIXFfoJC65XhrBPQ9GWcXtXNuDA=",
+ "owner": "wrvsrx",
+ "repo": "pnpm2nix-nzbr",
+ "rev": "a2d285ad5718cb202f45e98a4f839a5b2608c4b1",
+ "type": "github"
+ },
+ "original": {
+ "owner": "wrvsrx",
+ "ref": "adapt-to-v9",
+ "repo": "pnpm2nix-nzbr",
+ "type": "github"
+ }
+ },
+ "pure": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1779255807,
+ "narHash": "sha256-UQ0hP3qJd4Qxiw1LXPdb9d0Dc4OSD3HJpgYzaCfujno=",
+ "owner": "sindresorhus",
+ "repo": "pure",
+ "rev": "cc0759a0de620f191510e2e2f9748194a605b54d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "sindresorhus",
+ "repo": "pure",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "aagl": "aagl",
+ "agenix": "agenix",
+ "c-amethyst": "c-amethyst",
+ "c-beryllium": "c-beryllium",
+ "c-citrine": "c-citrine",
+ "c-diamond": "c-diamond",
+ "c-emerald": "c-emerald",
+ "c-fluorite": "c-fluorite",
+ "c-garnet": "c-garnet",
+ "catppuccin": "catppuccin_2",
+ "catppuccin-palette": "catppuccin-palette",
+ "fast-syntax-highlighting": "fast-syntax-highlighting",
+ "home-manager": "home-manager_3",
+ "linux-tkg": "linux-tkg",
+ "neovim-nightly": "neovim-nightly",
+ "nix-gaming": "nix-gaming",
+ "nix-index-database": "nix-index-database",
+ "nixpkgs": "nixpkgs_11",
+ "nvim-treesitter": "nvim-treesitter",
+ "pastel": "pastel",
+ "pure": "pure",
+ "spicetify-nix": "spicetify-nix",
+ "spotify-adblock": "spotify-adblock",
+ "stevenblack-hosts": "stevenblack-hosts",
+ "tree-sitter-jsonc": "tree-sitter-jsonc",
+ "website": "website",
+ "wine-discord-ipc-bridge": "wine-discord-ipc-bridge",
+ "zsh-abbr": "zsh-abbr",
+ "zsh-history-substring-search": "zsh-history-substring-search"
+ }
+ },
+ "rust-overlay": {
+ "inputs": {
+ "nixpkgs": [
+ "aagl",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1777605393,
+ "narHash": "sha256-Hjp0VOOHgHcTrX23iVvnfAudPcuCmfkfpQNFwv2v/ks=",
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "rev": "ff88db34cfa486fc4964a6991cab1678d82eee8c",
+ "type": "github"
+ },
+ "original": {
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "type": "github"
+ }
+ },
+ "spicetify-nix": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "systems": "systems_5"
+ },
+ "locked": {
+ "lastModified": 1779824049,
+ "narHash": "sha256-dWHVUjP03KSVG1PaLKA6j9EdxWSxSQvipMUIcSyuA/U=",
+ "owner": "Gerg-L",
+ "repo": "spicetify-nix",
+ "rev": "1362178e5f5f7a848c49fe9dee004ef8824f100a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "Gerg-L",
+ "repo": "spicetify-nix",
+ "type": "github"
+ }
+ },
+ "spotify-adblock": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1773417310,
+ "narHash": "sha256-nwiX2wCZBKRTNPhmrurWQWISQdxgomdNwcIKG2kSQsE=",
+ "owner": "abba23",
+ "repo": "spotify-adblock",
+ "rev": "813d3451c53126bf1941baaf8dd37f1152c3f412",
+ "type": "github"
+ },
+ "original": {
+ "owner": "abba23",
+ "repo": "spotify-adblock",
+ "type": "github"
+ }
+ },
+ "stevenblack-hosts": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1779976382,
+ "narHash": "sha256-wt5NGa4K8/vda669UYUmTUt+BR9X5fPnuTZFfQdpLYo=",
+ "owner": "StevenBlack",
+ "repo": "hosts",
+ "rev": "d3e838712512490260f051150e3573eeebecfadb",
+ "type": "github"
+ },
+ "original": {
+ "owner": "StevenBlack",
+ "repo": "hosts",
+ "type": "github"
+ }
+ },
+ "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"
+ }
+ },
+ "systems_3": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ },
+ "systems_4": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ },
+ "systems_5": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ },
+ "tree-sitter-jsonc": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1769637052,
+ "narHash": "sha256-V38tvBHJsSHJbj8QrMbt5hz2q8WLf4jtKsTiAo98/Vo=",
+ "owner": "WhyNotHugo",
+ "repo": "tree-sitter-jsonc",
+ "rev": "f7890ba894d885d1b2b721cfae759b07d53c8886",
+ "type": "gitlab"
+ },
+ "original": {
+ "owner": "WhyNotHugo",
+ "repo": "tree-sitter-jsonc",
+ "type": "gitlab"
+ }
+ },
+ "website": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1668017714,
+ "narHash": "sha256-ywy/7xeT6FHkF7lcs+stW1WPV+piE8ztSwcQ161iico=",
+ "owner": "cillynder",
+ "repo": "lavadesu.github.io",
+ "rev": "4e30c50be520a0a1bbecf408f056e6aaf135df67",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cillynder",
+ "ref": "master",
+ "repo": "lavadesu.github.io",
+ "type": "github"
+ }
+ },
+ "wine-discord-ipc-bridge": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1730092778,
+ "narHash": "sha256-jzsbOKMakNQ6RNMlioX088fGzFBDxOP45Atlsfm2RKg=",
+ "owner": "0e4ef622",
+ "repo": "wine-discord-ipc-bridge",
+ "rev": "86fcbddaf654aec40c6fe6a8293f627340331b0c",
+ "type": "github"
+ },
+ "original": {
+ "owner": "0e4ef622",
+ "repo": "wine-discord-ipc-bridge",
+ "type": "github"
+ }
+ },
+ "zsh-abbr": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1773890443,
+ "narHash": "sha256-SVuwDeHIBg8yArKGzDEfsG3fz0UwABQoJkyKTQAPUiw=",
+ "ref": "refs/heads/main",
+ "rev": "889f4772c12b9dbe4965bbd56f2572af0a28fa3b",
+ "revCount": 1139,
+ "submodules": true,
+ "type": "git",
+ "url": "https://github.com/olets/zsh-abbr"
+ },
+ "original": {
+ "submodules": true,
+ "type": "git",
+ "url": "https://github.com/olets/zsh-abbr"
+ }
+ },
+ "zsh-history-substring-search": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1768499095,
+ "narHash": "sha256-KHujL1/TM5R3m4uQh2nGVC98D6MOyCgQpyFf+8gjKR0=",
+ "owner": "zsh-users",
+ "repo": "zsh-history-substring-search",
+ "rev": "14c8d2e0ffaee98f2df9850b19944f32546fdea5",
+ "type": "github"
+ },
+ "original": {
+ "owner": "zsh-users",
+ "repo": "zsh-history-substring-search",
"type": "github"
}
}
diff --git a/flake.nix b/flake.nix
index f1585df..5cf3457 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,65 +1,101 @@
{
inputs = {
- nixpkgs = { url = "github:NixOS/nixpkgs/nixos-unstable"; };
- home-manager = { url = "github:LavaDesu/home-manager/aa"; };
- secrets = { url = "github:LavaDesu/flakes-secrets"; };
-
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
+
+ agenix.url = "github:ryantm/agenix";
+ agenix.inputs.nixpkgs.follows = "nixpkgs";
+ aagl.url = "github:ezKEa/aagl-gtk-on-nix";
+ catppuccin.url = "github:catppuccin/nix/8eada392fd6571a747e1c5fc358dd61c14c8704e";
+ catppuccin.inputs.nixpkgs.follows = "nixpkgs";
+ catppuccin-palette = { url = "github:catppuccin/palette"; flake = false; };
+ neovim-nightly.url = "github:nix-community/neovim-nightly-overlay";
+ neovim-nightly.inputs.nixpkgs.follows = "nixpkgs";
+
+ nix-gaming.url = "github:fufexan/nix-gaming";
+ nix-index-database.url = "github:nix-community/nix-index-database";
+ nix-index-database.inputs.nixpkgs.follows = "nixpkgs";
+ spicetify-nix.url = "github:Gerg-L/spicetify-nix";
+ spicetify-nix.inputs.nixpkgs.follows = "nixpkgs";
+
+ # services
+ pastel.url = "github:cillynder/pastel";
+ stevenblack-hosts = { url = "github:StevenBlack/hosts"; flake = false; };
+ website = { url = "github:cillynder/lavadesu.github.io/master"; flake = false; };
+
+ # zsh plugins
+ zsh-abbr = { url = "git+https://github.com/olets/zsh-abbr?submodules=1"; flake = false; };
+ zsh-history-substring-search = { url = "github:zsh-users/zsh-history-substring-search"; flake = false; };
+ fast-syntax-highlighting = { url = "github:zdharma-continuum/fast-syntax-highlighting"; flake = false; };
+ pure = { url = "github:sindresorhus/pure"; flake = false; };
+
+ # overlays
+ linux-tkg = { url = "github:Frogging-Family/linux-tkg"; flake = false; };
+ nvim-treesitter = { url = "github:nvim-treesitter/nvim-treesitter"; flake = false; };
+ spotify-adblock = { url = "github:abba23/spotify-adblock"; flake = false; };
+ tree-sitter-jsonc = { url = "gitlab:WhyNotHugo/tree-sitter-jsonc"; flake = false; };
+ wine-discord-ipc-bridge = { url = "github:0e4ef622/wine-discord-ipc-bridge"; flake = false; };
+
+ # containers
+ c-amethyst.url = "path:./containers/amethyst";
+ c-beryllium.url = "path:./containers/beryllium";
+ c-citrine.url = "path:./containers/citrine";
+ c-diamond.url = "path:./containers/diamond";
+ c-emerald.url = "path:./containers/emerald";
+ c-fluorite.url = "path:./containers/fluorite";
+ c-garnet.url = "path:./containers/garnet";
};
- outputs = inputs: with inputs;
+ outputs = { self, agenix, catppuccin, nixpkgs, ... } @ inputs:
let
- getPaths = root: builtins.map
- (path: root + ("/" + path)) # Prepends root path
- (builtins.attrNames (builtins.readDir root)); # Reads root path
+ overlays = (import ./overlays)
+ ++ [(final: prev: {
+ me = prev.callPackage ./packages { inherit inputs; } // { inherit inputs; };
+ })];
- customPackages = pkgs:
- let
- callPackage = pkgs.callPackage;
- in {
- linux-lava = callPackage ./packages/linux-lava {};
- wine-osu = callPackage ./packages/wine-osu { inherit getPaths; };
- };
+ patchOverlaysWithLinuxLava = nixpkgs: arch: ([(self: super: {
+ linuxLavaNixpkgs = import nixpkgs {
+ overlays = [ (import ./overlays/linux-lava.nix) ] ++ overlays;
+ system = arch;
+ };
+ })] ++ overlays);
- overlays = (builtins.map
- (path: import path) # Imports path
- (builtins.filter
- (path: nixpkgs.lib.hasSuffix ".nix" path) # Checks file extension
- (getPaths ./overlays)
- )
- ) ++ [(self: super: customPackages super)];
-
- revCount = "297098";
- base = { config, ... }: {
- system = {
- configurationRevision = nixpkgs.lib.mkIf (self ? rev) self.rev;
- nixos = rec {
- version = config.system.nixos.release + versionSuffix;
- versionSuffix = ".${nixpkgs.lib.substring 0 8 (nixpkgs.lastModifiedDate or nixpkgs.lastModified or "19700101")}.r${revCount}-${nixpkgs.lib.substring 0 11 (nixpkgs.rev or "dirty")}";
+ mkSystem =
+ if !(self ? rev) then throw "Dirty git tree detected." else
+ nixpkgs: name: arch: extraModules: nixpkgs.lib.nixosSystem {
+ system = arch;
+ modules = [
+ ({
+ nixpkgs.overlays = patchOverlaysWithLinuxLava nixpkgs arch;
+ })
+ agenix.nixosModules.age
+ catppuccin.nixosModules.catppuccin
+ (./hosts + "/${name}")
+ ] ++ extraModules;
+ specialArgs = {
+ inherit inputs;
+ modules = import ./modules { lib = nixpkgs.lib; };
+ gcSecrets = builtins.fromJSON (builtins.readFile "${self}/secrets.gcrypt/shared.json");
};
};
- nix.registry.nixpkgs.flake = nixpkgs;
- nixpkgs.overlays = overlays;
- };
-
- hm-base = {
- home-manager = {
- useGlobalPkgs = true;
- useUserPackages = true;
- };
- };
in
{
- nixosConfigurations."winter" = nixpkgs.lib.nixosSystem {
- system = "x86_64-linux";
- modules = [
- base
- home-manager.nixosModules.home-manager
- hm-base
- ./hosts/winter
- secrets.nixosModules.winter
- ];
- };
- packages.x86_64-linux = customPackages nixpkgs.legacyPackages.x86_64-linux;
+ nixosConfigurations."alyssum" = mkSystem nixpkgs "alyssum" "x86_64-linux" [];
+ nixosConfigurations."anemone" = mkSystem nixpkgs "anemone" "x86_64-linux" [];
+ nixosConfigurations."dandelion" = mkSystem nixpkgs "dandelion" "aarch64-linux" [];
+ nixosConfigurations."hyacinth" = mkSystem nixpkgs "hyacinth" "x86_64-linux" [];
+
+ packages."x86_64-linux" =
+ let
+ pkgs = import nixpkgs rec {
+ overlays = patchOverlaysWithLinuxLava nixpkgs system;
+ system = "x86_64-linux";
+ };
+ in
+ {
+ inherit (pkgs.me) linux-lava spotify-adblock;
+ linux-lava-ccache = pkgs.me.linux-lava.override { useCcache = true; };
+ };
};
}
diff --git a/hosts/alyssum/default.nix b/hosts/alyssum/default.nix
new file mode 100644
index 0000000..06c415f
--- /dev/null
+++ b/hosts/alyssum/default.nix
@@ -0,0 +1,45 @@
+{ inputs, lib, modules, modulesPath, ... }: {
+ networking.hostName = "alyssum";
+ system.stateVersion = "25.11";
+ time.timeZone = "Australia/Melbourne";
+
+ age.secrets = {
+ acme_dns.file = ../../secrets/acme_dns.age;
+ passwd.file = ../../secrets/passwd.age;
+ navidrome_env.file = ../../secrets/navidrome_env.age;
+ wpa_conf = {
+ file = ../../secrets/wpa_conf.age;
+ path = "/etc/wpa_supplicant/imperative.conf";
+ symlink = false;
+ };
+ };
+
+ imports = with modules.system; [
+ (modulesPath + "/profiles/qemu-guest.nix")
+ home-manager
+
+ base
+ kernel
+ nix-stable
+ packages
+ security
+ tailscale
+
+ modules.services.nginx
+ modules.services.syncthing
+
+ inputs.c-emerald.nixosModule
+ inputs.c-garnet.nixosModule
+
+ ./filesystem.nix
+ ./kernel.nix
+ ./networking.nix
+ ./home.syncthing.nix
+ ./samba.nix
+
+ ../../users/hana
+ ];
+
+ me.environment = "headless";
+ services.syncthing.user = lib.mkForce "hana";
+}
diff --git a/hosts/alyssum/filesystem.nix b/hosts/alyssum/filesystem.nix
new file mode 100644
index 0000000..bdea423
--- /dev/null
+++ b/hosts/alyssum/filesystem.nix
@@ -0,0 +1,35 @@
+{ ... }:
+let
+ bind = src: {
+ depends = [ "/nix" ];
+ device = src;
+ fsType = "none";
+ neededForBoot = true;
+ options = [ "bind" ];
+ };
+
+ mkLabelMount = label: type: {
+ device = "/dev/disk/by-label/${label}";
+ fsType = type;
+ options = [ "defaults" "relatime" ];
+ };
+ mkBtrfsMount = name: subvol: atime: mkLabelMount name "btrfs" // {
+ options = [ "autodefrag" "compress=zstd:3" "defaults" "discard=async" "space_cache=v2" "ssd" "subvol=${subvol}" (if atime then "relatime" else "noatime") ];
+ };
+ submount = mkBtrfsMount "alyssum";
+in {
+ fileSystems = {
+ "/" = {
+ device = "rootfs";
+ fsType = "tmpfs";
+ options = [ "defaults" "size=8G" "mode=755" ];
+ };
+ "/boot" = mkLabelMount "stem" "vfat";
+
+ "/flower" = mkBtrfsMount "myosotis" "/@" true;
+ "/nix" = submount "/@/nix" false;
+ "/persist" = (submount "/@/persist" true) // { neededForBoot = true; };
+ "/persist/.snapshots" = submount "/snap/persist" false;
+ "/var/log/journal" = bind "/persist/journal";
+ };
+}
diff --git a/hosts/alyssum/home.syncthing.nix b/hosts/alyssum/home.syncthing.nix
new file mode 100644
index 0000000..8d5a1cc
--- /dev/null
+++ b/hosts/alyssum/home.syncthing.nix
@@ -0,0 +1,39 @@
+{ config, lib, ... }:
+let
+ configOn = user: port: {
+ me.binds."/home/${user}/.config/syncthing" = "${user}/syncthing/config";
+ me.binds."/home/${user}/.local/state/syncthing" = "${user}/syncthing/state";
+
+ systemd.tmpfiles.rules = [ "d /flower/syncthing/${user} 700 ${user} users" ];
+
+ users.users.${user} = {
+ hashedPasswordFile = config.age.secrets.passwd.path;
+ isNormalUser = true;
+ linger = true;
+ };
+ home-manager.users.${user} = { ... }: {
+ home = {
+ username = "${user}";
+ homeDirectory = "/home/${user}";
+ stateVersion = "26.05";
+ };
+ services.syncthing = {
+ enable = true;
+ guiAddress = "[::]:${toString port}";
+ overrideDevices = false;
+ overrideFolders = false;
+ settings = {
+ options.listenAddresses = [
+ "tcp://0.0.0.0:2${toString port}"
+ "quic://0.0.0.0:2${toString port}"
+ "dynamic+https://relays.syncthing.net/endpoint"
+ ];
+ defaults.folder.path = "/flower/syncthing/${user}";
+ };
+ };
+ };
+ };
+in lib.mkMerge [
+ (configOn "kujira" 8385)
+ (configOn "cilly" 8386)
+]
diff --git a/hosts/alyssum/kernel.nix b/hosts/alyssum/kernel.nix
new file mode 100644
index 0000000..5e9b300
--- /dev/null
+++ b/hosts/alyssum/kernel.nix
@@ -0,0 +1,12 @@
+{ config, lib, ... }: {
+ boot = {
+ loader = {
+ efi.canTouchEfiVariables = true;
+ systemd-boot.enable = true;
+ };
+ initrd.availableKernelModules = [ "nvme" "xhci_pci" "usb_storage" "sd_mod" "rtsx_usb_sdmmc" ];
+ initrd.kernelModules = [ ];
+ kernelModules = [ "kvm-amd" ];
+ };
+ hardware.cpu.amd.updateMicrocode = true;
+}
diff --git a/hosts/alyssum/networking.nix b/hosts/alyssum/networking.nix
new file mode 100644
index 0000000..281cbb6
--- /dev/null
+++ b/hosts/alyssum/networking.nix
@@ -0,0 +1,15 @@
+{ config, ... }: {
+ networking = {
+ useDHCP = true;
+ wireless.enable = true;
+
+ interfaces.wlp1s0.useDHCP = false;
+ interfaces.wlp1s0.ipv4.addresses = [{
+ address = "192.168.1.167";
+ prefixLength = 24;
+ }];
+
+ defaultGateway = "192.168.1.1";
+ nameservers = [ "8.8.8.8" "8.8.4.4" ];
+ };
+}
diff --git a/hosts/alyssum/packages.nix b/hosts/alyssum/packages.nix
new file mode 100644
index 0000000..2d4bd30
--- /dev/null
+++ b/hosts/alyssum/packages.nix
@@ -0,0 +1,14 @@
+{ pkgs, ... }: {
+ environment.systemPackages = with pkgs; [
+ git
+ htop
+ jq
+ neovim
+ rsync
+ sshfs
+ wget
+
+ kitty.terminfo
+ ];
+ environment.variables.EDITOR = "nvim";
+}
diff --git a/hosts/alyssum/samba.nix b/hosts/alyssum/samba.nix
new file mode 100644
index 0000000..d876981
--- /dev/null
+++ b/hosts/alyssum/samba.nix
@@ -0,0 +1,84 @@
+{ config, lib, pkgs, ... }:
+let
+ configOn = user: let
+ passwd_fname = "passwd_smb${user}";
+ in {
+ age.secrets.${passwd_fname}.file = ../../secrets/${passwd_fname}.age;
+ me.binds."/flower/smb/${user}/music" = "/flower/media/music/${user}";
+ me.binds."/flower/smb/${user}/syncthing" = "/flower/syncthing/${user}";
+
+ users.users.${user} = {
+ hashedPasswordFile = config.age.secrets.passwd.path;
+ isNormalUser = true;
+ };
+
+ system.activationScripts = {
+ init_smbpasswd.text = let
+ smbpasswd = "${config.services.samba.package}/bin/smbpasswd";
+ in ''
+ printf "$(cat ${config.age.secrets.${passwd_fname}.path})\n$(cat ${config.age.secrets.${passwd_fname}.path})\n" | ${smbpasswd} -sa ${user}
+ '';
+ };
+ services.samba.settings."${user}" = {
+ "path" = "/flower/smb/${user}";
+ "browseable" = "yes";
+ "read only" = "no";
+ "guest ok" = "no";
+ "create mask" = "0644";
+ "directory mask" = "0755";
+ "force user" = user;
+ "force group" = "users";
+ "valid users" = user;
+ };
+ };
+in lib.mkMerge [
+ (configOn "cilly")
+ (configOn "kujira")
+ {
+ me.binds."/flower/smb/kujira/opencloud" = "/flower/opencloud/data/storage/users/users/a8e29fc0-673c-4c67-be00-2442904acb43";
+
+ networking.firewall.allowPing = true;
+
+ services.samba = {
+ enable = true;
+ package = pkgs.samba4Full;
+ openFirewall = true;
+ settings = {
+ global = {
+ "server smb encrypt" = "required";
+ "workgroup" = "WORKGROUP";
+ "server string" = "smbnix";
+ "netbios name" = "smbnix";
+ "security" = "user";
+ "hosts allow" = "100.64.0.0/10 127.0.0.1 alyssum localhost";
+ "hosts deny" = "0.0.0.0/0";
+ "guest account" = "nobody";
+ "map to guest" = "bad user";
+ };
+ "public" = {
+ "path" = "/flower/smb/public";
+ "browseable" = "yes";
+ "read only" = "no";
+ "guest ok" = "yes";
+ "create mask" = "0644";
+ "directory mask" = "0755";
+ "force user" = "hana";
+ "force group" = "users";
+ };
+ };
+ };
+
+ services.samba-wsdd = {
+ enable = true;
+ openFirewall = true;
+ };
+
+ services.avahi = {
+ enable = true;
+ openFirewall = true;
+ nssmdns4 = true;
+ publish.enable = true;
+ publish.userServices = true;
+ };
+ }
+]
diff --git a/hosts/anemone/default.nix b/hosts/anemone/default.nix
new file mode 100644
index 0000000..841e909
--- /dev/null
+++ b/hosts/anemone/default.nix
@@ -0,0 +1,60 @@
+{ config, inputs, modules, overlays, pkgs, ... }: {
+ networking.hostName = "anemone";
+ system.stateVersion = "23.11";
+ time.timeZone = "Australia/Melbourne";
+
+ nixpkgs.overlays = [ inputs.neovim-nightly.overlays.default ];
+ age.secrets = {
+ wg_anemone.file = ../../secrets/wg_anemone.age;
+ passwd.file = ../../secrets/passwd.age;
+ };
+
+ imports = with modules.system; [
+ home-manager
+
+ audio
+ base
+ bluetooth
+ ccache
+ corectrl
+ docker
+ flatpak
+ greetd
+ gui
+ input
+ kernel
+ nix
+ packages
+ printing
+ security
+ snapper
+ tailscale
+ wireguard
+
+ ./filesystem.nix
+ ./kernel.nix
+ ./networking.nix
+
+ ../../users/rin
+
+ modules.services.syncthing
+ ];
+
+ me = {
+ environment = "laptop";
+ batteryDevice = "BATT";
+ kbBacklightDevice = "asus::kbd_backlight";
+ hasFingerprint = true;
+ hidpi = true;
+ };
+
+ programs.wireshark = {
+ enable = true;
+ package = pkgs.wireshark;
+ };
+
+ services.fprintd.enable = true;
+ services.tlp.enable = true;
+
+ programs.kdeconnect.enable = true;
+}
diff --git a/hosts/anemone/filesystem.nix b/hosts/anemone/filesystem.nix
new file mode 100644
index 0000000..1c984e8
--- /dev/null
+++ b/hosts/anemone/filesystem.nix
@@ -0,0 +1,36 @@
+{ config, lib, ... }:
+let
+ mkLabelMount = label: type: lazy: {
+ device = "/dev/disk/by-label/${label}";
+ fsType = type;
+ options = [ "defaults" "relatime" ] ++ lib.optionals lazy [ "nofail" ];
+ };
+ mkBtrfsMount = name: subvol: atime: mkLabelMount name "btrfs" false // {
+ options = [ "autodefrag" "compress=zstd:3" "defaults" "discard=async" "space_cache=v2" "ssd" "subvol=${subvol}" (if atime then "relatime" else "noatime") ];
+ };
+ submount = mkBtrfsMount "Anemone";
+in
+{
+ fileSystems = {
+ "/" = {
+ device = "rootfs";
+ fsType = "tmpfs";
+ options = [ "defaults" "size=8G" "mode=755" ];
+ };
+ "/boot" = mkLabelMount "SYSTEM" "vfat" true;
+
+ "/mnt/butter" = submount "/" true;
+ "/nix" = submount "/current/snow" false;
+ "/home" = submount "/current/home" true;
+ "/home/.snapshots" = submount "/snapshot/home" false;
+ "/root" = submount "/current/root" false;
+ "/var" = submount "/current/var" false;
+ "/persist" = {
+ depends = [ "/var" ];
+ device = "/var/persist";
+ fsType = "none";
+ options = [ "bind" ];
+ neededForBoot = true;
+ };
+ };
+}
diff --git a/hosts/anemone/kernel.nix b/hosts/anemone/kernel.nix
new file mode 100644
index 0000000..d959b37
--- /dev/null
+++ b/hosts/anemone/kernel.nix
@@ -0,0 +1,62 @@
+{ config, lib, pkgs, ... }: {
+ boot = {
+ consoleLogLevel = 0;
+ loader = {
+ efi.canTouchEfiVariables = true;
+ systemd-boot.enable = true;
+ };
+ initrd = {
+ availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
+ systemd.enable = true;
+ verbose = false;
+ };
+ kernelModules = [ "kvm-amd" ];
+ kernelPackages = lib.mkForce (pkgs.linuxPackagesFor pkgs.me.linux-lava);
+ kernelParams = [
+ "quiet"
+ "console=tty2"
+ "systemd.show_status=0"
+ "rd.systemd.show_status=0"
+ "rd.udev.log_level=3"
+ "udev.log_level=3"
+ "udev.log_priority=3"
+ ];
+ };
+
+ # swapDevices = [{
+ # device = "/persist/swapfile";
+ # size = 16 * 1024;
+ # }];
+ #
+ # systemd.sleep.extraConfig = ''
+ # HibernateMode=shutdown
+ # '';
+ /*
+ services.logind.lidSwitch = "suspend-then-hibernate";
+ systemd.sleep.extraConfig = ''
+ HibernateDelaySec=14400
+ SuspendEstimationSec=3600
+ HibernateOnACPower=true
+ '';
+ */
+
+ powerManagement.cpufreq.min = 400000;
+
+ hardware.cpu.amd.updateMicrocode = true;
+
+ hardware.firmware = let
+ fw = "${pkgs.linux-firmware}/lib/firmware/cirrus/";
+ in [(
+ pkgs.runCommandNoCC "cs35l41-10431683" { } ''
+ mkdir -p $out/lib/firmware/cirrus
+ cd $out/lib/firmware/cirrus
+
+ cp ${fw}/cs35l41-dsp1-spk-prot-10431e12-spkid0-l0.bin cs35l41-dsp1-spk-prot-10431683-spkid0-l0.bin
+ cp ${fw}/cs35l41-dsp1-spk-prot-10431e12-spkid0-l0.bin cs35l41-dsp1-spk-prot-10431683-spkid0-r0.bin
+ cp ${fw}/cs35l41-dsp1-spk-prot-10431e12-spkid0-l0.bin cs35l41-dsp1-spk-prot-10431683-spkid1-l0.bin
+ cp ${fw}/cs35l41-dsp1-spk-prot-10431e12-spkid0-l0.bin cs35l41-dsp1-spk-prot-10431683-spkid1-r0.bin
+
+ cp ${fw}/cs35l41-dsp1-spk-prot-10431e12.wmfw cs35l41-dsp1-spk-prot-10431683.wmfw
+ ''
+ )];
+}
diff --git a/hosts/anemone/networking.nix b/hosts/anemone/networking.nix
new file mode 100644
index 0000000..f5a4dc5
--- /dev/null
+++ b/hosts/anemone/networking.nix
@@ -0,0 +1,4 @@
+{ config, ... }: {
+ networking.wireless.iwd.enable = true;
+ environment.etc."NetworkManager/system-connections".source = "/persist/nm_system-connections";
+}
diff --git a/hosts/dandelion/default.nix b/hosts/dandelion/default.nix
new file mode 100644
index 0000000..f65dfd1
--- /dev/null
+++ b/hosts/dandelion/default.nix
@@ -0,0 +1,44 @@
+{ inputs, modules, modulesPath, ... }: {
+ networking.hostName = "dandelion";
+ system.stateVersion = "23.11";
+ time.timeZone = "Australia/Melbourne";
+
+ age.secrets = {
+ acme_dns.file = ../../secrets/acme_dns.age;
+ slskd_env.file = ../../secrets/slskd_env.age;
+ wg_dandelion.file = ../../secrets/wg_dandelion.age;
+ };
+
+ imports = with modules.system; [
+ (modulesPath + "/profiles/qemu-guest.nix")
+ home-manager
+
+ base
+ kernel
+ nix-stable
+ packages
+ security
+ tailscale
+ wireguard
+
+ modules.services.banksia
+ modules.services.nginx
+ modules.services.unbound
+ modules.services.website
+
+ inputs.c-amethyst.nixosModule
+ inputs.c-beryllium.nixosModule
+ inputs.c-citrine.nixosModule
+ inputs.c-diamond.nixosModule
+ inputs.c-fluorite.nixosModule
+
+ ./filesystem.nix
+ ./kernel.nix
+ ./networking.nix
+ ./nginx.nix
+
+ ../../users/hana
+ ];
+
+ me.environment = "headless";
+}
diff --git a/hosts/dandelion/filesystem.nix b/hosts/dandelion/filesystem.nix
new file mode 100644
index 0000000..861bc15
--- /dev/null
+++ b/hosts/dandelion/filesystem.nix
@@ -0,0 +1,34 @@
+{ ... }:
+let
+ bind = src: {
+ depends = [ "/nix" ];
+ device = src;
+ fsType = "none";
+ neededForBoot = true;
+ options = [ "bind" ];
+ };
+
+ mkLabelMount = label: type: {
+ device = "/dev/disk/by-label/${label}";
+ fsType = type;
+ options = [ "defaults" "relatime" ];
+ };
+ mkBtrfsMount = name: subvol: atime: mkLabelMount name "btrfs" // {
+ options = [ "autodefrag" "compress=zstd:3" "defaults" "discard=async" "space_cache=v2" "ssd" "subvol=${subvol}" (if atime then "relatime" else "noatime") ];
+ };
+ submount = mkBtrfsMount "DANDELION";
+in {
+ fileSystems = {
+ "/" = {
+ device = "rootfs";
+ fsType = "tmpfs";
+ options = [ "defaults" "size=6G" "mode=755" ];
+ };
+ "/boot" = mkLabelMount "UEFI" "vfat";
+
+ "/nix" = submount "/@/nix" false;
+ "/persist" = (submount "/@/persist" true) // { neededForBoot = true; };
+ "/persist/.snapshots" = submount "/snap/persist" false;
+ "/var/log/journal" = bind "/persist/journal";
+ };
+}
diff --git a/hosts/dandelion/kernel.nix b/hosts/dandelion/kernel.nix
new file mode 100644
index 0000000..7ea7d43
--- /dev/null
+++ b/hosts/dandelion/kernel.nix
@@ -0,0 +1,10 @@
+{ ... }: {
+ boot = {
+ loader = {
+ efi.canTouchEfiVariables = true;
+ systemd-boot.enable = true;
+ };
+ initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" ];
+ initrd.kernelModules = [ "nvme" ];
+ };
+}
diff --git a/hosts/dandelion/networking.nix b/hosts/dandelion/networking.nix
new file mode 100644
index 0000000..322719e
--- /dev/null
+++ b/hosts/dandelion/networking.nix
@@ -0,0 +1,4 @@
+{ ... }: {
+ networking.useDHCP = true;
+ networking.interfaces.enp2s0.useDHCP = false;
+}
diff --git a/hosts/dandelion/nginx.nix b/hosts/dandelion/nginx.nix
new file mode 100644
index 0000000..c29de38
--- /dev/null
+++ b/hosts/dandelion/nginx.nix
@@ -0,0 +1,8 @@
+{ ... }: {
+ services.nginx.virtualHosts."muse.lava.moe" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ locations."/".return = "404";
+ locations."/share/".proxyPass = "http://[fd0d:2::5:2]:4533";
+ };
+}
diff --git a/hosts/dandelion/packages.nix b/hosts/dandelion/packages.nix
new file mode 100644
index 0000000..2d4bd30
--- /dev/null
+++ b/hosts/dandelion/packages.nix
@@ -0,0 +1,14 @@
+{ pkgs, ... }: {
+ environment.systemPackages = with pkgs; [
+ git
+ htop
+ jq
+ neovim
+ rsync
+ sshfs
+ wget
+
+ kitty.terminfo
+ ];
+ environment.variables.EDITOR = "nvim";
+}
diff --git a/hosts/hyacinth/default.nix b/hosts/hyacinth/default.nix
new file mode 100644
index 0000000..a32d4bd
--- /dev/null
+++ b/hosts/hyacinth/default.nix
@@ -0,0 +1,47 @@
+{ config, inputs, modules, overlays, pkgs, ... }: {
+ networking.hostName = "hyacinth";
+ system.stateVersion = "21.11";
+ time.timeZone = "Australia/Melbourne";
+
+ nixpkgs.overlays = [ inputs.neovim-nightly.overlays.default ];
+ age.secrets = {
+ passwd.file = ../../secrets/passwd.age;
+ wg_hyacinth.file = ../../secrets/wg_hyacinth.age;
+ wpa_conf.file = ../../secrets/wpa_conf.age;
+ };
+ imports = with modules.system; [
+ home-manager
+
+ aagl
+ audio
+ base
+ bluetooth
+ ccache
+ corectrl
+ docker
+ flatpak
+ greetd
+ gui
+ input
+ kernel
+ nix
+ packages
+ printing
+ security
+ snapper
+ tailscale
+ wireguard
+
+ modules.services.syncthing
+
+ ./filesystem.nix
+ ./kernel.nix
+ ./networking.nix
+ ./packages.nix
+
+ ../../users/rin
+ ];
+ systemd.services.nix-daemon.environment.TMPDIR = "/nix/tmp";
+
+ me.hasBluetooth = true;
+}
diff --git a/hosts/hyacinth/filesystem.nix b/hosts/hyacinth/filesystem.nix
new file mode 100644
index 0000000..2757182
--- /dev/null
+++ b/hosts/hyacinth/filesystem.nix
@@ -0,0 +1,50 @@
+{ config, lib, ... }:
+let
+ mkLabelMount = label: type: {
+ device = "/dev/disk/by-label/${label}";
+ fsType = type;
+ options = [ "defaults" "relatime" ];
+ };
+ mkBtrfsMount = name: subvol: atime: mkLabelMount name "btrfs" // {
+ options = [ "autodefrag" "compress=zstd:3" "defaults" "discard=async" "space_cache=v2" "ssd" "subvol=${subvol}" (if atime then "relatime" else "noatime") ];
+ };
+ mkCakeMount = mkBtrfsMount "CAKE";
+in
+{
+ fileSystems = {
+ "/" = {
+ device = "rootfs";
+ fsType = "tmpfs";
+ options = [ "defaults" "size=24G" "mode=755" ];
+ };
+ "/boot" = mkLabelMount "CUP" "vfat";
+
+ "/mnt/butter" = mkCakeMount "/" true;
+ "/mnt/cream" = mkBtrfsMount "CREAM" "/" true;
+ "/mnt/cream/permanence/.snapshots" = mkBtrfsMount "CREAM" "/snapshot/permanence" false;
+ "/nix" = mkCakeMount "/current/snow" false;
+ "/home" = mkCakeMount "/current/home" true;
+ "/home/.snapshots" = mkCakeMount "/snapshot/home" false;
+ "/root" = mkCakeMount "/current/root" false;
+ "/var" = mkCakeMount "/current/var" false;
+ "/persist" = {
+ depends = [ "/var" ];
+ device = "/var/persist";
+ fsType = "none";
+ options = [ "bind" ];
+ neededForBoot = true;
+ };
+ };
+ services.snapper.configs.cream = {
+ FSTYPE = "btrfs";
+ SUBVOLUME = "/mnt/cream/permanence";
+ TIMELINE_CLEANUP = true;
+ TIMELINE_CREATE = true;
+ TIMELINE_MIN_AGE = "1800";
+ TIMELINE_LIMIT_HOURLY = "5";
+ TIMELINE_LIMIT_DAILY = "7";
+ TIMELINE_LIMIT_WEEKLY = "0";
+ TIMELINE_LIMIT_MONTHLY = "0";
+ TIMELINE_LIMIT_YEARLY = "0";
+ };
+}
diff --git a/hosts/hyacinth/kernel.nix b/hosts/hyacinth/kernel.nix
new file mode 100644
index 0000000..f410014
--- /dev/null
+++ b/hosts/hyacinth/kernel.nix
@@ -0,0 +1,20 @@
+{ config, lib, pkgs, ... }: {
+ boot = {
+ loader = {
+ efi.canTouchEfiVariables = true;
+ systemd-boot.enable = true;
+ };
+ initrd.availableKernelModules = [ "xhci_pci" "nvme" ];
+ initrd.kernelModules = [ "amdgpu" ];
+ kernelParams = [
+ "amdgpu.gpu_recovery=1"
+ "intel_pstate=passive"
+ "split_lock_detect=off"
+ ];
+ kernelPackages = lib.mkForce (pkgs.linuxPackagesFor pkgs.me.linux-lava);
+ };
+ hardware.amdgpu.overdrive = {
+ enable = true;
+ ppfeaturemask = "0xffffffff";
+ };
+}
diff --git a/hosts/hyacinth/networking.nix b/hosts/hyacinth/networking.nix
new file mode 100644
index 0000000..0b2eb03
--- /dev/null
+++ b/hosts/hyacinth/networking.nix
@@ -0,0 +1,19 @@
+{ config, ... }: {
+ environment.etc."wpa_supplicant.conf".source = config.age.secrets.wpa_conf.path;
+ networking = {
+ useDHCP = true;
+ interfaces.enp5s0.useDHCP = false;
+ interfaces.enp5s0.wakeOnLan.enable = true;
+
+ interfaces.enp5s0.ipv4.addresses = [{
+ address = "192.168.1.201";
+ prefixLength = 24;
+ }];
+ defaultGateway = "192.168.1.1";
+ nameservers = [ "8.8.8.8" "8.8.4.4" ];
+
+ extraHosts = ''
+ 10.100.0.1 sugarcane
+ '';
+ };
+}
diff --git a/hosts/hyacinth/packages.nix b/hosts/hyacinth/packages.nix
new file mode 100644
index 0000000..69f9ba1
--- /dev/null
+++ b/hosts/hyacinth/packages.nix
@@ -0,0 +1,7 @@
+{ pkgs, ... }: {
+ environment.systemPackages = with pkgs; [
+ discord
+ jetbrains.idea
+ texliveFull
+ ];
+}
diff --git a/hosts/winter/audio.nix b/hosts/winter/audio.nix
deleted file mode 100644
index 1f34689..0000000
--- a/hosts/winter/audio.nix
+++ /dev/null
@@ -1,107 +0,0 @@
-{ config, ... }:
-let
- int = {
- quantum = {
- min = 512;
- def = 1024;
- max = 2048;
- };
- rate = 48000;
- };
- str = {
- quantum = {
- min = toString int.quantum.min;
- def = toString int.quantum.def;
- max = toString int.quantum.max;
- };
- rate = toString int.rate;
- };
-in {
- sound.enable = false;
- security.rtkit.enable = true;
- services.pipewire = {
- enable = true;
- alsa.enable = true;
- alsa.support32Bit = true;
- pulse.enable = true;
- jack.enable = true;
-
- config.pipewire = {
- "context.properties" = {
- "link.max-buffers" = 16;
- "default.clock.rate" = int.rate;
- "default.clock.quantum" = int.quantum.def;
- "default.clock.min-quantum" = int.quantum.min;
- "default.clock.max-quantum" = int.quantum.max;
- "core.daemon" = true;
- "core.name" = "pipewire-0";
- };
-
- "context.modules" = [
- {
- name = "libpipewire-module-rtkit";
- args = {
- "nice.level" = -15;
- "rt.prio" = 88;
- "rt.time.soft" = 200000;
- "rt.time.hard" = 200000;
- };
- flags = [ "ifexists" "nofail" ];
- }
- { name = "libpipewire-module-protocol-native"; }
- { name = "libpipewire-module-profiler"; }
- { name = "libpipewire-module-metadata"; }
- { name = "libpipewire-module-spa-device-factory"; }
- { name = "libpipewire-module-spa-node-factory"; }
- { name = "libpipewire-module-client-node"; }
- { name = "libpipewire-module-client-device"; }
- {
- name = "libpipewire-module-portal";
- flags = [ "ifexists" "nofail" ];
- }
- { name = "libpipewire-module-access"; args = {}; }
- { name = "libpipewire-module-adapter"; }
- { name = "libpipewire-module-link-factory"; }
- { name = "libpipewire-module-session-manager"; }
- ];
- "stream.properties" = {
- "node.latency" = "${str.quantum.min}/${str.rate}";
- "resample.quality" = 1;
- };
- };
- config.pipewire-pulse = {
- "context.modules" = [
- {
- name = "libpipewire-module-rtkit";
- args = {
- "nice.level" = -15;
- "rt.prio" = 88;
- "rt.time.soft" = 200000;
- "rt.time.hard" = 200000;
- };
- flags = [ "ifexists" "nofail" ];
- }
- { name = "libpipewire-module-protocol-native"; }
- { name = "libpipewire-module-client-node"; }
- { name = "libpipewire-module-adapter"; }
- { name = "libpipewire-module-metadata"; }
- {
- name = "libpipewire-module-protocol-pulse";
- args = {
- "pulse.min.req" = "${str.quantum.min}/${str.rate}";
- "pulse.default.req" = "${str.quantum.def}/${str.rate}";
- "pulse.max.req" = "${str.quantum.max}/${str.rate}";
- "pulse.min.quantum" = "${str.quantum.min}/${str.rate}";
- "pulse.max.quantum" = "${str.quantum.max}/${str.rate}";
- "server.address" = [ "unix:native" ];
- };
- }
- ];
- "stream.properties" = {
- "node.latency" = "${str.quantum.min}/${str.rate}";
- "resample.quality" = 1;
- };
- };
- };
-}
-
diff --git a/hosts/winter/default.nix b/hosts/winter/default.nix
deleted file mode 100644
index d7c8030..0000000
--- a/hosts/winter/default.nix
+++ /dev/null
@@ -1,47 +0,0 @@
-{ config, overlays, pkgs, ... }: {
- networking.hostName = "winter";
- system.stateVersion = "20.09";
-
- environment.etc = {
- "machine-id".source = "/var/persist/machine-id";
- "ssh/ssh_host_rsa_key".source = "/var/persist/ssh_host_rsa_key";
- "ssh/ssh_host_rsa_key.pub".source = "/var/persist/ssh_host_rsa_key.pub";
- "ssh/ssh_host_ed25519_key".source = "/var/persist/ssh_host_ed25519_key";
- "ssh/ssh_host_ed25519_key.pub".source = "/var/persist/ssh_host_ed25519_key.pub";
- };
- environment.pathsToLink = [ "/share/zsh" ];
- users.mutableUsers = false;
-
- imports = [
- ./audio.nix
- ./gui.nix
- ./hardware-configuration.nix
- ./kernel.nix
- ./networking.nix
- ./packages.nix
- ./security.nix
-
- ../../users/rin
- ];
- nix = rec {
- package = pkgs.nixUnstable;
- binaryCaches = [
- "https://cache.nixos.org?priority=10"
- "https://lava.cachix.org"
- ];
- binaryCachePublicKeys = [
- "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
- "lava.cachix.org-1:8lTWI/3IKWHByzzYHZySunMPYs2eAJw2duL+uLZkSy0="
- ];
- trustedBinaryCaches = binaryCaches;
-
- extraOptions = ''
- experimental-features = nix-command flakes
- '';
- };
- nixpkgs.config.allowUnfree = true;
-
- i18n.defaultLocale = "en_GB.UTF-8";
- console.useXkbConfig = true;
-}
-
diff --git a/hosts/winter/gui.nix b/hosts/winter/gui.nix
deleted file mode 100644
index 15cb649..0000000
--- a/hosts/winter/gui.nix
+++ /dev/null
@@ -1,60 +0,0 @@
-{ config, lib, pkgs, ... }: {
- fonts = {
- enableDefaultFonts = true;
- fontconfig = {
- defaultFonts = {
- serif = ["NotoSerif"];
- sansSerif = ["NotoSans"];
- monospace = ["CascadiaCode"];
- };
- };
- fonts = with pkgs; [
- cascadia-code
- font-awesome-ttf
- font-awesome_4
- hanazono
- material-icons
- noto-fonts
- noto-fonts-cjk
- noto-fonts-extra
- open-sans
- twemoji-color-font
- unifont
- ];
- };
- services.xserver = {
- enable = true;
- autorun = false;
- displayManager = {
- lightdm.enable = lib.mkForce false;
- startx.enable = true;
- xserverArgs = [
- "-ardelay 250"
- "-arinterval 15"
- ];
- };
- desktopManager.xterm.enable = false;
- libinput = {
- enable = true;
- mouse = {
- accelSpeed = "0";
- accelProfile = "flat";
- };
- };
- xkbOptions = "caps:escape";
- windowManager.i3 = {
- enable = true;
- package = pkgs.i3-gaps;
- extraPackages = with pkgs; [
- dunst
- feh
- lxappearance
- maim
- picom
- polybar
- rofi
- xclip
- ];
- };
- };
-}
diff --git a/hosts/winter/hardware-configuration.nix b/hosts/winter/hardware-configuration.nix
deleted file mode 100644
index fee857b..0000000
--- a/hosts/winter/hardware-configuration.nix
+++ /dev/null
@@ -1,63 +0,0 @@
-# Do not modify this file! It was generated by ‘nixos-generate-config’
-# and may be overwritten by future invocations. Please make changes
-# to /etc/nixos/configuration.nix instead.
-{ config, lib, pkgs, modulesPath, ... }:
-
-{
- imports =
- [ (modulesPath + "/installer/scan/not-detected.nix")
- ];
-
- boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" ];
- boot.initrd.kernelModules = [ ];
- boot.kernelModules = [ "kvm-intel" ];
- boot.extraModulePackages = [ ];
-
- fileSystems."/" =
- { device = "rootfs";
- fsType = "tmpfs";
- options = [ "defaults" "size=4G" "mode=755" ];
- };
-
- fileSystems."/boot" =
- { device = "/dev/disk/by-uuid/E8E8-E570";
- fsType = "vfat";
- };
-
- fileSystems."/mnt/butter" =
- { device = "/dev/disk/by-uuid/8f0ba28e-5dff-4a4e-8db0-aa72cc90cb5d";
- fsType = "btrfs";
- options = [ "autodefrag" "compress=zstd:3" "nossd" "nossd_spread" "relatime" "subvolid=5" ];
- };
-
- fileSystems."/nix" =
- { device = "/dev/disk/by-uuid/8f0ba28e-5dff-4a4e-8db0-aa72cc90cb5d";
- fsType = "btrfs";
- options = [ "autodefrag" "compress=zstd:3" "nossd" "nossd_spread" "relatime" "subvolid=258" ];
- };
-
- fileSystems."/home" =
- { device = "/dev/disk/by-uuid/8f0ba28e-5dff-4a4e-8db0-aa72cc90cb5d";
- fsType = "btrfs";
- options = [ "autodefrag" "compress=zstd:3" "nossd" "nossd_spread" "relatime" "subvolid=260" ];
- };
-
- fileSystems."/root" =
- { device = "/dev/disk/by-uuid/8f0ba28e-5dff-4a4e-8db0-aa72cc90cb5d";
- fsType = "btrfs";
- options = [ "autodefrag" "compress=zstd:3" "nossd" "nossd_spread" "relatime" "subvolid=261" ];
- };
-
- fileSystems."/var" =
- { device = "/dev/disk/by-uuid/8f0ba28e-5dff-4a4e-8db0-aa72cc90cb5d";
- fsType = "btrfs";
- options = [ "autodefrag" "compress=zstd:3" "nossd" "nossd_spread" "relatime" "subvolid=259" ];
- };
-
- fileSystems."/mnt/hdd" =
- { device = "/dev/disk/by-uuid/d5e3cfe5-c73a-4695-b81b-fc0215d4cefe";
- fsType = "ext4";
- };
-
- swapDevices = [ ];
-}
diff --git a/hosts/winter/kernel.nix b/hosts/winter/kernel.nix
deleted file mode 100644
index 68f2cf6..0000000
--- a/hosts/winter/kernel.nix
+++ /dev/null
@@ -1,32 +0,0 @@
-{ config, pkgs, ... }: {
- powerManagement.cpuFreqGovernor = "ondemand";
- boot = {
- loader = {
- systemd-boot.enable = true;
- efi.canTouchEfiVariables = true;
- grub = {
- enable = true;
- efiSupport = true;
- device = "nodev";
- };
- };
- blacklistedKernelModules = ["uvcvideo"];
- initrd = {
- includeDefaultModules = false;
- kernelModules = [ "i915" ];
- };
- kernel.sysctl = {
- "kernel.core_pattern" = "|/bin/false";
- "kernel.sysrq" = 1;
- };
- kernelParams = [
- "amdgpu.gpu_recovery=1"
- "amdgpu.si_support=1"
- "radeon.si_support=0"
- "intel_pstate=passive"
- "msr.allow_writes=on"
- ];
- kernelPackages = pkgs.lib.mkForce (pkgs.linuxPackagesFor pkgs.linux-lava);
- };
- zramSwap.enable = true;
-}
diff --git a/hosts/winter/networking.nix b/hosts/winter/networking.nix
deleted file mode 100644
index a504e73..0000000
--- a/hosts/winter/networking.nix
+++ /dev/null
@@ -1,21 +0,0 @@
-{ config, ... }: {
- networking.wireless = {
- enable = true;
- interfaces = [ "wlp3s0" ];
- };
-
- networking.useDHCP = false;
- networking.interfaces.eno1.useDHCP = false;
- networking.interfaces.wlp3s0.useDHCP = false;
-
- networking.interfaces.eno1.ipv4.addresses = [{
- address = "10.0.0.2";
- prefixLength = 24;
- }];
- networking.interfaces.wlp3s0.ipv4.addresses = [{
- address = "192.168.100.13";
- prefixLength = 24;
- }];
- networking.defaultGateway = "192.168.100.1";
- networking.nameservers = ["192.168.100.11"];
-}
diff --git a/hosts/winter/packages.nix b/hosts/winter/packages.nix
deleted file mode 100644
index 6f7edc6..0000000
--- a/hosts/winter/packages.nix
+++ /dev/null
@@ -1,33 +0,0 @@
-{ config, pkgs, ...}: {
- environment.systemPackages = with pkgs; [
- efibootmgr
- git
- gparted
- htop
- libarchive
- lf
- msr-tools
- ncdu
- neovim
- rsync
- wget
-
- gnome3.nautilus
- ];
- environment.variables.EDITOR = "nvim";
-
- hardware.opengl.extraPackages = with pkgs; [
- vaapiIntel
- vaapiVdpau
- libvdpau-va-gl
- intel-ocl
- rocm-opencl-icd
- rocm-opencl-runtime
- ];
- programs.light.enable = true;
- hardware.opentabletdriver.enable = true;
- programs.steam.enable = true;
- services.dbus.packages = [ pkgs.gnome3.dconf pkgs.gcr ];
- services.gnome.sushi.enable = true;
- # services.ipfs.enable = true;
-}
diff --git a/hosts/winter/security.nix b/hosts/winter/security.nix
deleted file mode 100644
index 78748e5..0000000
--- a/hosts/winter/security.nix
+++ /dev/null
@@ -1,19 +0,0 @@
-{ config, pkgs, ... }: {
- networking.firewall.enable = false;
- services.openssh.enable = true;
-
- security = {
- polkit.enable = true;
- sudo.enable = false;
- doas = {
- enable = true;
- extraRules = [
- {
- groups = ["wheel"];
- keepEnv = true;
- persist = true;
- }
- ];
- };
- };
-}
diff --git a/modules/binds.nix b/modules/binds.nix
new file mode 100644
index 0000000..c9ffe18
--- /dev/null
+++ b/modules/binds.nix
@@ -0,0 +1,13 @@
+{ config, lib, ...}: {
+ imports = [ ./options.nix ];
+ fileSystems = lib.mapAttrs (dest: key: let
+ target = if (lib.strings.hasPrefix "/" key)
+ then key
+ else "/persist/binds/${key}";
+ in {
+ depends = [ "/persist" ];
+ device = target;
+ fsType = "none";
+ options = [ "bind" ];
+ }) config.me.binds;
+}
diff --git a/modules/default.nix b/modules/default.nix
new file mode 100644
index 0000000..6775c55
--- /dev/null
+++ b/modules/default.nix
@@ -0,0 +1,80 @@
+{ lib }:
+let
+ getName = path: lib.removeSuffix ".nix" ( # Strip extension
+ lib.last ( # Gets the last part (filename)
+ lib.splitString "/" ( # Splits the path into components
+ builtins.toString path # Converts the path into a string
+ )
+ )
+ );
+ mkAttrsFromPaths = paths: builtins.listToAttrs (
+ builtins.map (path: {
+ name = getName path;
+ value = path;
+ }) paths
+ );
+in {
+ binds = ./binds.nix;
+ options = ./options.nix;
+ services = mkAttrsFromPaths [
+ ./services/banksia.nix
+ ./services/jellyfin.nix
+ ./services/nginx.nix
+ ./services/postgres.nix
+ ./services/sonarr.nix
+ ./services/synapse.nix
+ ./services/syncthing.nix
+ ./services/tmptsync.nix
+ ./services/transmission.nix
+ ./services/unbound.nix
+ ./services/vaultwarden.nix
+ ./services/website.nix
+ ];
+ system = mkAttrsFromPaths [
+ ./system/aagl.nix
+ ./system/audio.nix
+ ./system/base.nix
+ ./system/bluetooth.nix
+ ./system/ccache.nix
+ ./system/corectrl.nix
+ ./system/docker.nix
+ ./system/flatpak.nix
+ ./system/greetd.nix
+ ./system/gui.nix
+ ./system/home-manager.nix
+ ./system/input.nix
+ ./system/kernel.nix
+ ./system/nix.nix
+ ./system/nix-stable.nix
+ ./system/packages.nix
+ ./system/printing.nix
+ ./system/security.nix
+ ./system/snapper.nix
+ ./system/tailscale.nix
+ ./system/virtualisation.nix
+ ./system/wireguard.nix
+ ];
+ user = mkAttrsFromPaths [
+ ./user/catppuccin.nix
+ ./user/comma.nix
+ ./user/direnv.nix
+ ./user/dunst.nix
+ ./user/eww.nix
+ ./user/git.nix
+ ./user/gpg.nix
+ ./user/hypridle.nix
+ ./user/hyprlock.nix
+ ./user/kitty.nix
+ ./user/mpv.nix
+ ./user/neovim.nix
+ ./user/neovim-minimal.nix
+ ./user/npm.nix
+ ./user/obs.nix
+ ./user/rofi.nix
+ ./user/sessionVariables.nix
+ ./user/spicetify.nix
+ ./user/theming.nix
+ ./user/xdg.nix
+ ./user/zsh.nix
+ ];
+}
diff --git a/modules/options.nix b/modules/options.nix
new file mode 100644
index 0000000..e861c12
--- /dev/null
+++ b/modules/options.nix
@@ -0,0 +1,53 @@
+{ config, lib, ... }:
+let
+ inherit (lib)
+ mkOption
+ types;
+in {
+ options.me = {
+ environment = mkOption {
+ type = types.enum [ "desktop" "laptop" "headless" ];
+ default = "desktop";
+ };
+
+ hasFingerprint = mkOption {
+ type = types.bool;
+ default = false;
+ };
+
+ gui = mkOption {
+ type = types.bool;
+ default = config.me.environment != "headless";
+ };
+
+ batteryDevice = mkOption {
+ type = with types; nullOr (uniq str);
+ default = null;
+ };
+
+ kbBacklightDevice = mkOption {
+ type = with types; nullOr (uniq str);
+ default = null;
+ };
+
+ hasBluetooth = mkOption {
+ type = types.bool;
+ default = config.me.environment == "laptop";
+ };
+
+ hasWifi = mkOption {
+ type = types.bool;
+ default = config.me.environment == "laptop";
+ };
+
+ hidpi = mkOption {
+ type = types.bool;
+ default = false;
+ };
+
+ binds = lib.mkOption {
+ type = with lib.types; attrsOf str;
+ default = {};
+ };
+ };
+}
diff --git a/modules/services/banksia.nix b/modules/services/banksia.nix
new file mode 100644
index 0000000..2ace618
--- /dev/null
+++ b/modules/services/banksia.nix
@@ -0,0 +1,11 @@
+# TODO ^^
+{ ... }: {
+ services.nginx.virtualHosts = {
+ "banksia.lava.moe" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ locations."/".return = "302 https://lab.lava.moe/cilly/Banksia";
+ locations."/api".proxyPass = "http://localhost:8080/";
+ };
+ };
+}
diff --git a/modules/services/jellyfin.nix b/modules/services/jellyfin.nix
new file mode 100644
index 0000000..4a52ed6
--- /dev/null
+++ b/modules/services/jellyfin.nix
@@ -0,0 +1,28 @@
+{ ... }:
+let
+ dir = "/persist/jellyfin";
+in
+{
+ fileSystems."/var/lib/jellyfin" = {
+ depends = [ "/persist" ];
+ device = dir;
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ system.activationScripts."jellyfin-create-bind-mount" = {
+ deps = [ "users" "groups" ];
+ text = ''
+ mkdir -p ${dir}
+ chown jellyfin:jellyfin ${dir}
+ chmod 700 ${dir}
+ '';
+ };
+ systemd.tmpfiles.rules = [
+ "d /tmp/jelly-transcodes 700 jellyfin jellyfin"
+ "L+ /var/lib/jellyfin/transcodes - - - - /tmp/jelly-transcodes"
+ ];
+ services.jellyfin = {
+ enable = true;
+ openFirewall = true;
+ };
+}
diff --git a/modules/services/nginx.nix b/modules/services/nginx.nix
new file mode 100644
index 0000000..a02b7e9
--- /dev/null
+++ b/modules/services/nginx.nix
@@ -0,0 +1,28 @@
+{ config, ... }: {
+ networking.firewall.allowedTCPPorts = [ 80 443 ];
+ security.acme = {
+ acceptTerms = true;
+ defaults = {
+ email = "me@lava.moe";
+ group = "nginx";
+ dnsProvider = "cloudflare";
+ environmentFile = config.age.secrets."acme_dns".path;
+ };
+ certs."lava.moe" = {
+ extraDomainNames = [
+ "*.lava.moe"
+ "*.local.lava.moe"
+ ];
+ };
+ certs."cilly.moe" = {};
+ certs."cilly.dev" = {};
+ };
+
+ services.nginx = {
+ enable = true;
+ recommendedTlsSettings = true;
+ recommendedOptimisation = true;
+ recommendedGzipSettings = true;
+ recommendedProxySettings = true;
+ };
+}
diff --git a/modules/services/postgres.nix b/modules/services/postgres.nix
new file mode 100644
index 0000000..bbbeaa1
--- /dev/null
+++ b/modules/services/postgres.nix
@@ -0,0 +1,20 @@
+{ config, lib, pkgs, ... }:
+let
+ dir = "/persist/postgresql/${config.services.postgresql.package.psqlSchema}";
+ uid = toString config.ids.uids.postgres;
+ gid = toString config.ids.gids.postgres;
+in {
+ systemd.tmpfiles.rules = [ "d ${dir} 700 ${uid} ${gid}" ];
+ services.postgresql = {
+ enable = true;
+ dataDir = dir;
+ # TODO: broken :3
+ package = pkgs.postgresql_13;
+ authentication = lib.mkOverride 10 ''
+ #type database DBuser origin-address auth-method
+ local all all trust
+ host all all 127.0.0.1/32 trust
+ host all all ::1/128 trust
+ '';
+ };
+}
diff --git a/modules/services/sonarr.nix b/modules/services/sonarr.nix
new file mode 100644
index 0000000..b64d5ef
--- /dev/null
+++ b/modules/services/sonarr.nix
@@ -0,0 +1,11 @@
+{ ... }:
+let
+ dir = "/persist/sonarr";
+in
+{
+ services.sonarr = {
+ enable = true;
+ dataDir = dir;
+ openFirewall = true;
+ };
+}
diff --git a/modules/services/synapse.nix b/modules/services/synapse.nix
new file mode 100644
index 0000000..030de52
--- /dev/null
+++ b/modules/services/synapse.nix
@@ -0,0 +1,89 @@
+{ config, lib, options, pkgs, ... }:
+let
+ dom = "lava.moe";
+ sub = "matrix.lava.moe";
+ dir = "/persist/matrix-synapse";
+ uid = toString config.ids.uids.matrix-synapse;
+ gid = toString config.ids.gids.matrix-synapse;
+in {
+ networking.firewall.allowedTCPPorts = [ 80 443 ];
+ systemd.tmpfiles.rules = [ "d ${dir} 700 ${uid} ${gid}" ];
+
+ /*services.postgresql = {
+ ensureDatabases = [ "matrix-synapse" ];
+ ensureUsers = [{
+ name = "matrix-synapse";
+ ensurePermissions = {
+ "DATABASE matrix-synapse" = "ALL PRIVILEGES";
+ };
+ }];
+ };*/
+ # TODO this would be bad if we use postgres for other things too
+ services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" ''
+ CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
+ CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
+ TEMPLATE template0
+ LC_COLLATE = "C"
+ LC_CTYPE = "C";
+ '';
+
+ services.nginx = {
+ virtualHosts = {
+ ${dom} = {
+ locations."= /.well-known/matrix/server".extraConfig =
+ let
+ server = { "m.server" = "${sub}:443"; };
+ in ''
+ add_header Content-Type application/json;
+ return 200 '${builtins.toJSON server}';
+ '';
+ locations."= /.well-known/matrix/client".extraConfig =
+ let
+ client = {
+ "m.homeserver" = { "base_url" = "https://${sub}"; };
+ "m.identity_server" = { "base_url" = "https://vector.im"; };
+ };
+ in ''
+ add_header Content-Type application/json;
+ add_header Access-Control-Allow-Origin *;
+ return 200 '${builtins.toJSON client}';
+ '';
+ };
+
+ ${sub} = {
+ forceSSL = true;
+ useACMEHost = dom;
+
+ locations."/".extraConfig = ''
+ return 302 'https://${dom}';
+ '';
+
+ locations."/_matrix" = {
+ proxyPass = "http://[::1]:8008";
+ };
+ };
+ };
+ };
+
+ services.matrix-synapse = {
+ enable = true;
+ dataDir = dir;
+ server_name = dom;
+ logConfig = builtins.replaceStrings [ "INFO" ] [ "WARNING" ] options.services.matrix-synapse.logConfig.default;
+ listeners = [
+ {
+ port = 8008;
+ bind_address = "::1";
+ type = "http";
+ tls = false;
+ x_forwarded = true;
+ resources = [
+ {
+ names = [ "client" "federation" ];
+ compress = false;
+ }
+ ];
+ }
+ ];
+ };
+}
diff --git a/modules/services/syncthing.nix b/modules/services/syncthing.nix
new file mode 100644
index 0000000..db32371
--- /dev/null
+++ b/modules/services/syncthing.nix
@@ -0,0 +1,23 @@
+{ config, ... }:
+let
+ dir = "/persist/shared/.syncthing";
+ user = if config.me.gui then "rin" else "hana";
+ uid = toString config.users.users."${user}".uid;
+ gid = toString config.users.groups.users.gid;
+in
+{
+ systemd.tmpfiles.rules = [
+ "d ${dir}/config 700 ${uid} ${gid}"
+ "d ${dir}/data 700 ${uid} ${gid}"
+ ];
+ systemd.services.syncthing.environment.STNODEFAULTFOLDER = "true";
+ services.syncthing = {
+ enable = true;
+ openDefaultPorts = true;
+ user = user;
+ group = "users";
+ dataDir = "/persist/shared/.syncthing/data";
+ configDir = "/persist/shared/.syncthing/config";
+ guiAddress = if config.me.gui then "127.0.0.1:8384" else ":8384";
+ };
+}
diff --git a/modules/services/tmptsync.nix b/modules/services/tmptsync.nix
new file mode 100644
index 0000000..54004c4
--- /dev/null
+++ b/modules/services/tmptsync.nix
@@ -0,0 +1,32 @@
+{ ... }:
+let
+ dir = "/persist/tmptsync";
+in
+{
+ systemd = {
+ services = {
+ tmptsync-load = {
+ before = [ "basic.target" ];
+ after = [ "local-fs.target" "sysinit.target" ];
+ unitConfig.DefaultDependencies = false;
+
+ environment.FILE = dir;
+ script = "${../../scripts/tmptsync.sh} load";
+ wantedBy = [ "basic.target" ];
+ };
+
+ tmptsync-save = {
+ environment.FILE = dir;
+ script = "${../../scripts/tmptsync.sh} save";
+ wantedBy = [ "basic.target" ];
+ };
+ };
+ timers.tmptsync-save = {
+ timerConfig = {
+ Unit = "tmptsync-save.service";
+ OnBootSec = "30min";
+ OnUnitActiveSec = "2h";
+ };
+ };
+ };
+}
diff --git a/modules/services/transmission.nix b/modules/services/transmission.nix
new file mode 100644
index 0000000..7540d68
--- /dev/null
+++ b/modules/services/transmission.nix
@@ -0,0 +1,18 @@
+{ config, ... }: {
+ networking.firewall.allowedTCPPorts = [ 9091 ];
+ services.transmission = {
+ enable = true;
+ downloadDirPermissions = "775";
+ openFirewall = true;
+ settings = {
+ download-dir = "/persist/transmission/Downloads";
+ incomplete-dir = "/persist/transmission/.incomplete";
+ ratio-limit-enabled = true;
+ rpc-bind-address = "0.0.0.0";
+ rpc-enabled = true;
+ rpc-port = 9091;
+ rpc-host-whitelist = "${config.networking.hostName}";
+ rpc-whitelist = "10.100.0.*,10.0.0.*,192.168.100.*";
+ };
+ };
+}
diff --git a/modules/services/unbound.nix b/modules/services/unbound.nix
new file mode 100644
index 0000000..8aae0fd
--- /dev/null
+++ b/modules/services/unbound.nix
@@ -0,0 +1,62 @@
+{ inputs, pkgs, gcSecrets, ... }:
+let
+ dir = "/persist/unbound";
+
+ converted = pkgs.runCommand "stevenblack-hosts-unbound" {} ''
+ echo "server:" > "$out"
+ grep '^0\.0\.0\.0' "${inputs.stevenblack-hosts}/hosts" | awk '{print "local-zone: \""$2"\" always_refuse"}' | tail -n +2 >> "$out"
+ '';
+in {
+ networking.firewall.interfaces."ve-+" = {
+ allowedUDPPorts = [ 53 853 ];
+ allowedTCPPorts = [ 53 853 ];
+ };
+ networking.firewall.interfaces.wg0 = {
+ allowedUDPPorts = [ 53 853 ];
+ allowedTCPPorts = [ 53 853 ];
+ };
+ systemd.tmpfiles.rules = [ "d ${dir} 700 unbound unbound" ];
+
+ services.unbound = {
+ enable = true;
+ stateDir = dir;
+ settings = {
+ forward-zone = [{
+ name = ".";
+ forward-tls-upstream = true;
+ forward-addr = [
+ "2606:4700:4700::1111@853#cloudflare-dns.com"
+ "2606:4700:4700::1001@853#cloudflare-dns.com"
+ "2001:4860:4860::8888@853#dns.google"
+ "2001:4860:4860::8844@853#dns.google"
+ "1.1.1.1@853#cloudflare-dns.com"
+ "1.0.0.1@853#cloudflare-dns.com"
+ "8.8.8.8@853#dns.google"
+ "8.8.4.4@853#dns.google"
+ ];
+ }];
+
+ server = {
+ interface = [ "0.0.0.0" "::0" ];
+ access-control = [
+ "127.0.0.1/8 allow"
+ "10.0.0.0/8 allow"
+ "100.64.0.0/10 allow"
+ "192.168.100.0/24 allow"
+ "fd0d::/16 allow"
+ "fd7a:115c:a1e0::/48 allow"
+ "${gcSecrets.wireguard.ipv6Subnet}:/80 allow"
+ ];
+ domain-insecure = [ "\"local.lava.moe\"" ];
+ local-zone = [ "\"warden.local.lava.moe.\" redirect" ];
+ local-data = [
+ "\"warden.local.lava.moe. IN A 10.100.0.2\""
+ ];
+ };
+
+ include = "${converted}";
+ };
+ };
+
+ systemd.services.unbound.serviceConfig.ReadWritePaths = [ dir ];
+}
diff --git a/modules/services/vaultwarden.nix b/modules/services/vaultwarden.nix
new file mode 100644
index 0000000..9c8d8b4
--- /dev/null
+++ b/modules/services/vaultwarden.nix
@@ -0,0 +1,32 @@
+{ config, lib, ... }:
+let
+ dir = "/persist/vaultwarden";
+ user = config.users.users.vaultwarden.name;
+ group = config.users.groups.vaultwarden.name;
+in {
+ systemd.tmpfiles.rules = [
+ "d ${dir} 700 ${user} ${group}"
+ "d ${dir}_backup 700 ${user} ${group}"
+ ];
+ services.vaultwarden = {
+ enable = true;
+ backupDir = "${dir}_backup";
+ config = {
+ dataFolder = dir;
+ signupsAllowed = false;
+ domain = "https://warden.local.lava.moe";
+ rocketPort = 8002;
+ };
+ environmentFile = config.age.secrets.warden_admin.path;
+ };
+
+ services.nginx.virtualHosts."warden.local.lava.moe" = {
+ forceSSL = true;
+ useACMEHost = "lava.moe";
+
+ locations."/".proxyPass = "http://localhost:8002";
+ };
+
+ systemd.services.vaultwarden.serviceConfig.ReadWritePaths = [ dir ];
+ systemd.services.backup-vaultwarden.environment.DATA_FOLDER = lib.mkForce dir;
+}
diff --git a/modules/services/website.nix b/modules/services/website.nix
new file mode 100644
index 0000000..3fba609
--- /dev/null
+++ b/modules/services/website.nix
@@ -0,0 +1,43 @@
+{ inputs, pkgs, ... }: let
+ pastel = inputs.pastel.packages.${pkgs.system}.default;
+in {
+ services.nginx.virtualHosts = {
+ "cilly.moe" = {
+ useACMEHost = "cilly.moe";
+ forceSSL = true;
+ root = pastel.outPath;
+ };
+ "cilly.dev" = {
+ useACMEHost = "cilly.dev";
+ forceSSL = true;
+ root = pastel.outPath;
+ };
+ "lava.moe" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ root = inputs.website.outPath;
+ };
+ "cdn.lava.moe" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ extraConfig = ''
+ return 301 https://sh.lava.moe$request_uri;
+ '';
+ };
+ "sh.lava.moe" = {
+ useACMEHost = "lava.moe";
+ forceSSL = true;
+ root = "/persist/cdn";
+ };
+ "_" = {
+ default = true;
+ addSSL = true;
+ # TODO generate this somewhere
+ sslCertificate = "/persist/fakeCerts/fake.crt";
+ sslCertificateKey = "/persist/fakeCerts/fake.key";
+ extraConfig = ''
+ return 444;
+ '';
+ };
+ };
+}
diff --git a/modules/system/aagl.nix b/modules/system/aagl.nix
new file mode 100644
index 0000000..57826c4
--- /dev/null
+++ b/modules/system/aagl.nix
@@ -0,0 +1,6 @@
+{ inputs, ... }: {
+ imports = [ inputs.aagl.nixosModules.default ];
+ nix.settings = inputs.aagl.nixConfig;
+ programs.anime-game-launcher.enable = true;
+ programs.sleepy-launcher.enable = true;
+}
diff --git a/modules/system/audio.nix b/modules/system/audio.nix
new file mode 100644
index 0000000..46d50c0
--- /dev/null
+++ b/modules/system/audio.nix
@@ -0,0 +1,88 @@
+{ config, ... }:
+let
+ int = {
+ quantum = {
+ min = 64;
+ def = 1024;
+ max = 2048;
+ };
+ rate = 48000;
+ };
+ str = {
+ quantum = {
+ min = toString int.quantum.min;
+ def = toString int.quantum.def;
+ max = toString int.quantum.max;
+ };
+ rate = toString int.rate;
+ };
+in {
+ security.rtkit.enable = true;
+ services.pipewire = {
+ enable = true;
+ alsa.enable = true;
+ alsa.support32Bit = true;
+ pulse.enable = true;
+ jack.enable = true;
+ };
+ services.pipewire.extraConfig.pipewire = {
+ "context.properties" = {
+ "default.clock.rate" = int.rate;
+ "default.clock.quantum" = int.quantum.def;
+ "default.clock.min-quantum" = int.quantum.min;
+ "default.clock.max-quantum" = int.quantum.max;
+ };
+
+ "context.modules" = [
+ {
+ name = "libpipewire-module-rtkit";
+ args = {
+ "nice.level" = -15;
+ "rt.prio" = 88;
+ "rt.time.soft" = 200000;
+ "rt.time.hard" = 200000;
+ };
+ }
+ ];
+ "stream.properties" = {
+ "node.latency" = "${str.quantum.min}/${str.rate}";
+ "resample.quality" = 1;
+ };
+ };
+ services.pipewire.extraConfig.pipewire-pulse = {
+ "context.modules" = [
+ {
+ name = "libpipewire-module-rtkit";
+ args = {
+ "nice.level" = -15;
+ "rt.prio" = 88;
+ "rt.time.soft" = 200000;
+ "rt.time.hard" = 200000;
+ };
+ }
+ ];
+ "pulse.properties" = {
+ "pulse.min.req" = "${str.quantum.min}/${str.rate}";
+ "pulse.default.req" = "${str.quantum.def}/${str.rate}";
+ "pulse.max.req" = "${str.quantum.max}/${str.rate}";
+ "pulse.min.quantum" = "${str.quantum.min}/${str.rate}";
+ "pulse.max.quantum" = "${str.quantum.max}/${str.rate}";
+ };
+ "pulse.rules" = [
+ {
+ # Discord notification sounds fix
+ matches = [ { "application.process.binary" = ".DiscordCanary-wrapped"; } ];
+ actions = {
+ update-props = {
+ "pulse.min.quantum" = "1024/48000";
+ };
+ };
+ }
+ ];
+ "stream.properties" = {
+ "node.latency" = "${str.quantum.min}/${str.rate}";
+ "resample.quality" = 1;
+ };
+ };
+}
+
diff --git a/modules/system/base.nix b/modules/system/base.nix
new file mode 100644
index 0000000..c45eb99
--- /dev/null
+++ b/modules/system/base.nix
@@ -0,0 +1,27 @@
+{ config, inputs, modules, ... }: {
+ imports = [ modules.binds modules.options ];
+
+ environment.etc = {
+ "machine-id".source = "/persist/machine-id";
+ "ssh/ssh_host_rsa_key".source = "/persist/ssh_host_rsa_key";
+ "ssh/ssh_host_rsa_key.pub".source = "/persist/ssh_host_rsa_key.pub";
+ "ssh/ssh_host_ed25519_key".source = "/persist/ssh_host_ed25519_key";
+ "ssh/ssh_host_ed25519_key.pub".source = "/persist/ssh_host_ed25519_key.pub";
+ };
+ environment.pathsToLink = [ "/share/zsh" ];
+
+ i18n.defaultLocale = "en_AU.UTF-8";
+ i18n.extraLocales = [ "en_GB.UTF-8/UTF-8" ];
+
+ users.mutableUsers = false;
+
+ system = {
+ configurationRevision = inputs.self.rev;
+ nixos = rec {
+ version = config.system.nixos.release + versionSuffix;
+ versionSuffix = "-${config.system.name}.r${builtins.toString inputs.self.revCount}.${inputs.self.shortRev}";
+ };
+ };
+ nix.registry.config.flake = inputs.self;
+ nix.registry.shells.flake = inputs.self;
+}
diff --git a/modules/system/bluetooth.nix b/modules/system/bluetooth.nix
new file mode 100644
index 0000000..1e2a72e
--- /dev/null
+++ b/modules/system/bluetooth.nix
@@ -0,0 +1,6 @@
+{ ... }: {
+ hardware.bluetooth = {
+ enable = true;
+ powerOnBoot = true;
+ };
+}
diff --git a/modules/system/ccache.nix b/modules/system/ccache.nix
new file mode 100644
index 0000000..b9e0847
--- /dev/null
+++ b/modules/system/ccache.nix
@@ -0,0 +1,3 @@
+{ config, ... }: {
+ programs.ccache.enable = true;
+}
diff --git a/modules/system/corectrl.nix b/modules/system/corectrl.nix
new file mode 100644
index 0000000..6f6ca01
--- /dev/null
+++ b/modules/system/corectrl.nix
@@ -0,0 +1,5 @@
+{ ... }: {
+ programs.corectrl = {
+ enable = true;
+ };
+}
diff --git a/modules/system/docker.nix b/modules/system/docker.nix
new file mode 100644
index 0000000..1ebd190
--- /dev/null
+++ b/modules/system/docker.nix
@@ -0,0 +1,13 @@
+{ pkgs, ... }: {
+ virtualisation.docker = {
+ enable = true;
+ storageDriver = "btrfs";
+ # rootless = {
+ # enable = true;
+ # setSocketVariable = true;
+ # };
+ };
+ environment.systemPackages = [
+ pkgs.docker-compose
+ ];
+}
diff --git a/modules/system/flatpak.nix b/modules/system/flatpak.nix
new file mode 100644
index 0000000..fbb80bb
--- /dev/null
+++ b/modules/system/flatpak.nix
@@ -0,0 +1,8 @@
+{ pkgs, ... }: {
+ services.flatpak.enable = true;
+ xdg.portal = {
+ enable = true;
+ extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
+ config.common.default = "*";
+ };
+}
diff --git a/modules/system/greetd.nix b/modules/system/greetd.nix
new file mode 100644
index 0000000..f220847
--- /dev/null
+++ b/modules/system/greetd.nix
@@ -0,0 +1,18 @@
+{ pkgs, ... }: {
+ services.greetd = {
+ enable = true;
+ settings = {
+ default_session = {
+ command = "${pkgs.tuigreet}/bin/tuigreet --remember --asterisks --time --cmd 'zsh -c \"source $HOME/.config/zsh/.zshrc && Hyprland > $XDG_RUNTIME_DIR/Hyprland.out\"'";
+ user = "greeter";
+ };
+
+ initial_session = {
+ command = "${pkgs.writeShellScript "launch.sh" ''
+ zsh -c "source $HOME/.config/zsh/.zshrc && Hyprland > \"$XDG_RUNTIME_DIR/Hyprland.out\""
+ ''}";
+ user = "rin";
+ };
+ };
+ };
+}
diff --git a/modules/system/gui.nix b/modules/system/gui.nix
new file mode 100644
index 0000000..7028dac
--- /dev/null
+++ b/modules/system/gui.nix
@@ -0,0 +1,31 @@
+{ config, lib, pkgs, ... }: {
+ fonts = {
+ enableDefaultPackages = true;
+ fontconfig = {
+ defaultFonts = {
+ serif = [ "NotoSerif" ];
+ sansSerif = [ "NotoSans" ];
+ monospace = [ "CascadiaCode" ];
+ };
+ };
+ packages = with pkgs; [
+ material-symbols
+ material-icons
+ cascadia-code
+ hanazono
+ noto-fonts
+ noto-fonts-cjk-sans
+ open-sans
+ twemoji-color-font
+ unifont
+ ];
+ };
+ services.xserver = {
+ enable = true;
+ displayManager.lightdm.enable = lib.mkForce false;
+ desktopManager.xterm.enable = false;
+ };
+
+ programs.hyprland.enable = true;
+ security.pam.services.hyprlock = {};
+}
diff --git a/modules/system/home-manager.nix b/modules/system/home-manager.nix
new file mode 100644
index 0000000..7d0f19d
--- /dev/null
+++ b/modules/system/home-manager.nix
@@ -0,0 +1,19 @@
+{ config, inputs, modules, ... }: {
+ imports = [
+ inputs.home-manager.nixosModules.home-manager
+ ];
+ home-manager = {
+ useGlobalPkgs = true;
+ useUserPackages = true;
+ extraSpecialArgs = {
+ inherit inputs modules;
+ sysConfig = config;
+ };
+ sharedModules = [
+ {
+ imports = [ modules.options ];
+ config.me = config.me;
+ }
+ ];
+ };
+}
diff --git a/modules/system/input.nix b/modules/system/input.nix
new file mode 100644
index 0000000..a0bf2ff
--- /dev/null
+++ b/modules/system/input.nix
@@ -0,0 +1,24 @@
+{ ... }: {
+ services.xserver = {
+ displayManager = {
+ xserverArgs = [
+ "-ardelay 150"
+ "-arinterval 15"
+ ];
+ };
+ };
+ services.keyd = {
+ enable = true;
+ keyboards = {
+ default = {
+ ids = [ "*" ];
+ settings = {
+ main = {
+ capslock = "esc";
+ esc = "capslock";
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/modules/system/kernel.nix b/modules/system/kernel.nix
new file mode 100644
index 0000000..c0a1bcf
--- /dev/null
+++ b/modules/system/kernel.nix
@@ -0,0 +1,18 @@
+{ config, pkgs, ... }: {
+ boot = {
+ blacklistedKernelModules = [ "uvcvideo" ];
+ initrd = {
+ includeDefaultModules = false;
+ availableKernelModules = [ "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" ];
+ };
+ kernel.sysctl = {
+ "kernel.core_pattern" = "|/bin/false";
+ "kernel.sysrq" = 1;
+ };
+ };
+ hardware.enableRedistributableFirmware = true;
+ zramSwap = {
+ enable = true;
+ priority = 100;
+ };
+}
diff --git a/modules/system/nix-stable.nix b/modules/system/nix-stable.nix
new file mode 100644
index 0000000..1884c04
--- /dev/null
+++ b/modules/system/nix-stable.nix
@@ -0,0 +1,23 @@
+{ config, lib, pkgs, ... }: {
+ nix = {
+ package = pkgs.nixVersions.latest;
+
+ settings = rec {
+ substituters = [
+ "https://cache.nixos.org?priority=10"
+ "https://lava.cachix.org"
+ ];
+ trusted-public-keys = [
+ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
+ "lava.cachix.org-1:8lTWI/3IKWHByzzYHZySunMPYs2eAJw2duL+uLZkSy0="
+ ];
+ trusted-substituters = substituters;
+ };
+
+ extraOptions = ''
+ experimental-features = nix-command flakes
+ '';
+ };
+ nixpkgs.config.allowUnfree = true;
+ programs.nh.enable = true;
+}
diff --git a/modules/system/nix.nix b/modules/system/nix.nix
new file mode 100644
index 0000000..eb14f73
--- /dev/null
+++ b/modules/system/nix.nix
@@ -0,0 +1,28 @@
+{ config, inputs, pkgs, ... }: {
+ nix = {
+ nixPath = [ "nixpkgs=${inputs.nixpkgs}" ];
+ package = pkgs.nixVersions.latest;
+
+ settings = rec {
+ extra-sandbox-paths = [ config.programs.ccache.cacheDir ];
+ substituters = [
+ "https://cache.nixos.org?priority=10"
+ "https://lava.cachix.org"
+ "https://nix-gaming.cachix.org"
+ ];
+ trusted-public-keys = [
+ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
+ "lava.cachix.org-1:8lTWI/3IKWHByzzYHZySunMPYs2eAJw2duL+uLZkSy0="
+ "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4="
+ ];
+ trusted-substituters = substituters;
+ trusted-users = [ "root" "rin" ];
+ };
+
+ extraOptions = ''
+ experimental-features = nix-command flakes
+ '';
+ };
+ nixpkgs.config.allowUnfree = true;
+ programs.nh.enable = true;
+}
diff --git a/modules/system/packages-gui.nix b/modules/system/packages-gui.nix
new file mode 100644
index 0000000..d853c40
--- /dev/null
+++ b/modules/system/packages-gui.nix
@@ -0,0 +1,26 @@
+{ config, lib, pkgs, ... }: {
+ config = lib.mkIf config.me.gui {
+ environment.systemPackages = with pkgs; [
+ android-tools
+ gparted
+ nautilus
+ ];
+ hardware.graphics.extraPackages = with pkgs; [
+ intel-vaapi-driver
+ libva-vdpau-driver
+ libvdpau-va-gl
+ ];
+ hardware.opentabletdriver.enable = true;
+ hardware.keyboard.qmk.enable = true;
+ programs.steam = {
+ enable = true;
+ package = pkgs.steam.override {
+ extraPkgs = pkgs: with pkgs; [
+ gsettings-desktop-schemas
+ ];
+ };
+ };
+ services.dbus.packages = [ pkgs.dconf pkgs.gcr ];
+ services.gnome.sushi.enable = true;
+ };
+}
diff --git a/modules/system/packages.nix b/modules/system/packages.nix
new file mode 100644
index 0000000..d4e2e3c
--- /dev/null
+++ b/modules/system/packages.nix
@@ -0,0 +1,25 @@
+{ pkgs, ... }: {
+ imports = [ ./packages-gui.nix ];
+ environment.systemPackages = with pkgs; [
+ # ecryptfs
+ efibootmgr
+ fd
+ git
+ git-crypt
+ htop
+ jq
+ kitty.terminfo
+ libarchive
+ lf
+ msr-tools
+ ncdu
+ neovim
+ nfs-utils
+ ntfs3g
+ ripgrep
+ rsync
+ sshfs
+ wget
+ ];
+ environment.variables.EDITOR = "nvim";
+}
diff --git a/modules/system/printing.nix b/modules/system/printing.nix
new file mode 100644
index 0000000..f7ccb20
--- /dev/null
+++ b/modules/system/printing.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }: {
+ services.printing = {
+ enable = true;
+ drivers = with pkgs; [
+ epson-escpr
+ #me.epson-201112j
+ ];
+ };
+}
diff --git a/modules/system/security.nix b/modules/system/security.nix
new file mode 100644
index 0000000..f1f087b
--- /dev/null
+++ b/modules/system/security.nix
@@ -0,0 +1,85 @@
+{ config, lib, pkgs, ... }: {
+ networking.firewall =
+ let
+ iptables = "${pkgs.iptables}/bin/iptables";
+ genCmds = type: ''
+ ${iptables} -${type} nixos-fw -p tcp --source 192.168.0.0/16 -j nixos-fw-accept ${if type == "D" then " || true" else ""}
+ ${iptables} -${type} nixos-fw -p udp --source 192.168.0.0/16 -j nixos-fw-accept ${if type == "D" then " || true" else ""}
+ '';
+ in {
+ enable = true;
+ allowedUDPPortRanges = [ { from = 20000; to = 20100; } ];
+ allowedTCPPortRanges = [ { from = 20000; to = 20100; } ];
+ trustedInterfaces = [ "wg0" ];
+ logRefusedConnections = false;
+
+ extraCommands = genCmds "I";
+ extraStopCommands = genCmds "D";
+ };
+
+ services.openssh = {
+ enable = true;
+ settings = {
+ PermitRootLogin = "no";
+ PasswordAuthentication = false;
+ X11Forwarding = true;
+ };
+
+ hostKeys = [
+ {
+ bits = 4096;
+ path = "/persist/ssh_host_rsa_key";
+ rounds = 100;
+ type = "rsa";
+ }
+ {
+ path = "/persist/ssh_host_ed25519_key";
+ rounds = 100;
+ type = "ed25519";
+ }
+ ];
+ };
+
+ security = {
+ polkit.enable = true;
+ sudo.enable = false;
+ doas = {
+ enable = true;
+ extraRules = [
+ {
+ groups = [ "wheel" ];
+ keepEnv = true;
+ persist = true;
+ }
+ ];
+ };
+ pam = lib.mkIf (config.me.environment != "headless") {
+ u2f = {
+ enable = true;
+ settings = {
+ cue = true;
+ pinverification = 1;
+ };
+ };
+ services.doas.rules.auth = {
+ u2f.settings.pinverification = lib.mkForce 0;
+ u2f_int = lib.mkMerge [
+ {
+ enable = true;
+ order = config.security.pam.services.doas.rules.auth.u2f.order + 1;
+ control = "sufficient";
+ modulePath = "${pkgs.pam_u2f}/lib/security/pam_u2f.so";
+ inherit (config.security.pam.u2f) settings;
+ }
+ {
+ settings = lib.mkForce {
+ interactive = true;
+ pinverification = 0;
+ userpresence = 0;
+ };
+ }
+ ];
+ };
+ };
+ };
+}
diff --git a/modules/system/snapper.nix b/modules/system/snapper.nix
new file mode 100644
index 0000000..60cf41e
--- /dev/null
+++ b/modules/system/snapper.nix
@@ -0,0 +1,17 @@
+{ config, lib, ... }: {
+ services.snapper = {
+ cleanupInterval = "1h";
+ configs.home = {
+ FSTYPE = "btrfs";
+ SUBVOLUME = "/home";
+ TIMELINE_CLEANUP = true;
+ TIMELINE_CREATE = true;
+ TIMELINE_MIN_AGE = "1800";
+ TIMELINE_LIMIT_HOURLY = "5";
+ TIMELINE_LIMIT_DAILY = "7";
+ TIMELINE_LIMIT_WEEKLY = "0";
+ TIMELINE_LIMIT_MONTHLY = "0";
+ TIMELINE_LIMIT_YEARLY = "0";
+ };
+ };
+}
diff --git a/modules/system/tailscale.nix b/modules/system/tailscale.nix
new file mode 100644
index 0000000..5e3e044
--- /dev/null
+++ b/modules/system/tailscale.nix
@@ -0,0 +1,13 @@
+{ config, lib, ... }: {
+ age.secrets.tailscale_auth.file = ../../secrets/tailscale_auth.age;
+ me.binds."/var/lib/tailscale" = "tailscale";
+ networking.firewall.trustedInterfaces = [ "tailscale0" ];
+ networking.firewall.allowedUDPPorts = lib.mkIf (config.me.environment == "headless") [ 123 ];
+
+ services.tailscale = {
+ enable = true;
+ authKeyFile = config.age.secrets.tailscale_auth.path;
+ openFirewall = true;
+ useRoutingFeatures = if config.me.environment == "headless" then "both" else "client";
+ };
+}
diff --git a/modules/system/virtualisation.nix b/modules/system/virtualisation.nix
new file mode 100644
index 0000000..b575f05
--- /dev/null
+++ b/modules/system/virtualisation.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }: {
+ virtualisation = {
+ spiceUSBRedirection.enable = true;
+ libvirtd = {
+ enable = true;
+ qemu.package = pkgs.qemu_kvm.override { smbdSupport = true; };
+ };
+ };
+}
diff --git a/modules/system/wireguard.nix b/modules/system/wireguard.nix
new file mode 100644
index 0000000..71f85ad
--- /dev/null
+++ b/modules/system/wireguard.nix
@@ -0,0 +1,127 @@
+{ config, lib, pkgs, gcSecrets, ... }:
+let
+ port = 51801;
+ serverName = "dandelion";
+ serverInterface = "enp0s6";
+ serverIp = gcSecrets.wireguard.gateway;
+
+ forwarding = {
+ "22727" = [ "10.100.0.3" "7777" ];
+ };
+
+ mapForwards = type:
+ builtins.concatStringsSep "\n" (
+ lib.mapAttrsToList (sport: tuple:
+ let
+ dest = builtins.head tuple;
+ dport = lib.last tuple;
+ in ''
+ ${pkgs.iptables}/bin/iptables -${type} PREROUTING -t nat -i ${serverInterface} -p tcp --dport ${sport} -j DNAT --to ${dest}:${dport}
+ ${pkgs.iptables}/bin/iptables -${type} FORWARD -p tcp -d ${dest} --dport ${dport} -j ACCEPT
+ ${pkgs.iptables}/bin/iptables -${type} PREROUTING -t nat -i ${serverInterface} -p udp --dport ${sport} -j DNAT --to ${dest}:${dport}
+ ${pkgs.iptables}/bin/iptables -${type} FORWARD -p udp -d ${dest} --dport ${dport} -j ACCEPT
+ '') forwarding
+ );
+
+ clients = {
+ hyacinth = {
+ publicKey = "6nVhazYdmC15A/nke9VrqIg3sOBVOmqj4GEsyBq7MVo=";
+ allowedIPs = [ "10.100.0.3/32" "${gcSecrets.wireguard.ipv6Subnet}:3" "fd0d::3" ];
+ interfaces = {
+ wg0 = { peers = [ server6OnlyPeer ]; };
+ wg1 = { peers = [ serverPeer ]; autostart = false; };
+ wg2 = { peers = [ serverLocalOnlyPeer ]; autostart = false; };
+ };
+ };
+ anemone = {
+ publicKey = "px5+JNdAmqBvUC++DhiJrUBRAr+BYP6iYVt4sbhPTWY=";
+ allowedIPs = [ "10.100.0.4/32" "${gcSecrets.wireguard.ipv6Subnet}:4" "fd0d::4" ];
+ interfaces = {
+ wg0 = { peers = [ server6OnlyPeer ]; };
+ wg1 = { peers = [ serverPeer ]; autostart = false; };
+ wg2 = { peers = [ serverLocalOnlyPeer ]; autostart = false; };
+ };
+ };
+ hibiscus = {
+ publicKey = "vQ5a2KMrwi7RCRsD0yvog+n35vQYFuvwiPn+W4lbRBw=";
+ allowedIPs = [ "10.100.0.5/32" "${gcSecrets.wireguard.ipv6Subnet}:5" "fd0d::5" ];
+ interfaces = {
+ wg0 = { peers = [ server6OnlyPeer ]; };
+ wg1 = { peers = [ serverPeer ]; autostart = false; };
+ wg2 = { peers = [ serverLocalOnlyPeer ]; autostart = false; };
+ };
+ };
+ hazel = {
+ publicKey = "0zruTndObzHo+b1rbOuTsxCU97epygZycxXS/lgUHUc=";
+ allowedIPs = [ "10.100.0.21/32" "${gcSecrets.wireguard.ipv6Subnet}:21" "fd0d::21" ];
+ interfaces = {
+ wg0 = {
+ dns = [ "::1" "127.0.0.1" ];
+ peers = [ serverLocalOnlyPeer ];
+ };
+ };
+ };
+ };
+
+ clientPeers = builtins.map (client: builtins.removeAttrs client [ "interfaces" ]) (builtins.attrValues clients);
+ serverPeerWith = ips: {
+ publicKey = "3ugIk2tQZXjAH9/95s63ld2WNUHQrd4Mz5jzbln6oj0=";
+ allowedIPs = ips;
+ endpoint = "${serverIp}:${toString port}";
+ persistentKeepalive = 25;
+ };
+ serverPeer = serverPeerWith [ "0.0.0.0/0" "::/0" ];
+ server6OnlyPeer = serverPeerWith [ "10.100.0.0/24" "::/0" ];
+ serverLocalOnlyPeer = serverPeerWith [ "10.100.0.0/24" "fd0d::/16" ];
+
+ serverConfig = {
+ nat = {
+ enable = true;
+ externalInterface = serverInterface;
+ internalInterfaces = [ "wg0" ];
+ };
+ firewall = {
+ allowedTCPPorts = (builtins.map (s: lib.strings.toInt s) (builtins.attrNames forwarding));
+ allowedUDPPorts = [ port ];
+ };
+
+ wireguard.interfaces.wg0 = {
+ ips = [ "10.100.0.1/24" "${gcSecrets.wireguard.ipv6Subnet}:1" "fd0d::1" ];
+ listenPort = port;
+
+ postSetup = ''
+ ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o ${serverInterface} -j MASQUERADE
+ ${mapForwards "A"}
+ '';
+ postShutdown = ''
+ ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o ${serverInterface} -j MASQUERADE
+ ${mapForwards "D"}
+ '';
+
+ privateKeyFile = config.age.secrets."wg_${serverName}".path;
+ peers = clientPeers;
+ };
+ };
+
+ clientConfig = {
+ wg-quick.interfaces =
+ let
+ client = clients."${config.networking.hostName}";
+ in
+ builtins.mapAttrs (interface: conf: {
+ address = client.allowedIPs;
+ dns = [ "fd0d::1" "10.100.0.1" ];
+ privateKeyFile = config.age.secrets."wg_${config.networking.hostName}".path;
+ } // conf) client.interfaces;
+ };
+in {
+ boot.kernel.sysctl = lib.mkIf (config.networking.hostName == serverName) ({
+ "net.ipv6.conf.all.forwarding" = true;
+ "net.ipv6.conf.default.forwarding" = true;
+ });
+ networking =
+ lib.mkMerge [
+ (lib.mkIf (config.networking.hostName == serverName) serverConfig)
+ (lib.mkIf (config.networking.hostName != serverName) clientConfig)
+ ];
+}
diff --git a/modules/user/catppuccin.nix b/modules/user/catppuccin.nix
new file mode 100644
index 0000000..176b42c
--- /dev/null
+++ b/modules/user/catppuccin.nix
@@ -0,0 +1,75 @@
+{ config, inputs, lib, pkgs, ... }: {
+ imports = [
+ inputs.catppuccin.homeManagerModules.catppuccin
+ ];
+
+ options.catppuccin.colors = lib.mkOption {
+ type = lib.types.attrs;
+ default = (builtins.fromJSON (builtins.readFile "${inputs.catppuccin-palette}/palette.json"))."${config.catppuccin.flavor}".colors;
+ };
+ options.catppuccin.hexcolors = lib.mkOption {
+ type = lib.types.attrs;
+ default = builtins.mapAttrs (name: value: value.hex) config.catppuccin.colors;
+ };
+
+ config = {
+ catppuccin = {
+ accent = lib.mkDefault "pink";
+ flavor = lib.mkDefault "mocha";
+ kitty.enable = true;
+ gtk.enable = true;
+ hyprlock.enable = true;
+ nvim.enable = true;
+ };
+
+ specialisation = {
+ light.configuration.catppuccin.flavor = "latte";
+ dark.configuration.catppuccin.flavor = "mocha";
+ };
+
+ home.packages = [(pkgs.writeShellScriptBin "theme" ''
+ last_path="$HOME/.local/state/last-theme"
+ target="$1"
+ if [ "$target" == "get_last" ]; then
+ if [ ! -e "$last_path" ]; then
+ echo "no last theme found; assuming dark" >&2
+ target="dark"
+ else
+ target=$(cat "$last_path" | tr -d "\n")
+ fi
+ echo "$target"
+ exit 0
+ fi
+ if [ "$target" == "restore" ]; then
+ echo "restoring theme"
+ if [ ! -e "$last_path" ]; then
+ echo "no last theme found; assuming dark" >&2
+ target="dark"
+ else
+ target=$(cat "$last_path" | tr -d "\n")
+ fi
+ fi
+ if [ "$target" != "dark" ] && [ "$target" != "light" ]; then
+ echo "invalid theme, valid values: [dark, light, restore]"
+ exit 1
+ fi
+ current="$HOME/.local/state/home-manager/gcroots/current-home/"
+ cached="$HOME/.local/state/last-parent-specialisation"
+ if [ -d "$current/specialisation" ]; then
+ if [ -d "$cached" ]; then
+ rm -f "$cached"
+ fi
+ ln -sf "$(readlink -f $current)" "$cached"
+ fi
+
+ if [ ! -d "$cached/specialisation" ]; then
+ echo "no specialisations found"
+ exit 1
+ fi
+
+ "$cached/specialisation/$target/activate"
+
+ echo "$target" > "$last_path"
+ '')];
+ };
+}
diff --git a/modules/user/comma.nix b/modules/user/comma.nix
new file mode 100644
index 0000000..5ae7f03
--- /dev/null
+++ b/modules/user/comma.nix
@@ -0,0 +1,7 @@
+{ inputs, ... }: {
+ imports = [
+ inputs.nix-index-database.homeModules.default
+ ];
+ programs.nix-index.enable = true;
+ programs.nix-index-database.comma.enable = true;
+}
diff --git a/modules/user/direnv.nix b/modules/user/direnv.nix
new file mode 100644
index 0000000..2329800
--- /dev/null
+++ b/modules/user/direnv.nix
@@ -0,0 +1,16 @@
+{ config, lib, ... }: {
+ programs.direnv = {
+ enable = true;
+ nix-direnv = {
+ enable = true;
+ };
+ };
+ programs.git.settings.core.excludesFile = ".envrc";
+ # We can't use .source since hm manages this file too
+ xdg.configFile."direnv/direnvrc".text = builtins.readFile ../../res/direnvrc;
+ home.activation = {
+ direnvClearCache = lib.hm.dag.entryAfter ["writeBoundary"] ''
+ $DRY_RUN_CMD rm -rf $VERBOSE_ARG $HOME/.cache/direnv/layouts
+ '';
+ };
+}
diff --git a/modules/user/dunst.nix b/modules/user/dunst.nix
new file mode 100644
index 0000000..2ae1404
--- /dev/null
+++ b/modules/user/dunst.nix
@@ -0,0 +1,71 @@
+{ config, pkgs, ... }:
+let
+ historyScript = pkgs.writeShellScript "dunst_history.sh" ''
+ echo "$(${pkgs.coreutils}/bin/date +%s):$DUNST_TIMESTAMP:$DUNST_APP_NAME:$DUNST_URGENCY:$DUNST_SUMMARY:$DUNST_BODY" >> ${config.xdg.dataHome}/dunst/history
+ '';
+in {
+ systemd.user.tmpfiles.rules = [ "d ${config.xdg.dataHome}/dunst - - - -" ];
+
+ services.dunst = {
+ enable = true;
+ settings = {
+ global = {
+ monitor = 0;
+ follow = "mouse";
+ width = "(100, 450)";
+ origin = "top-right";
+ offset = "24x50";
+ notification_limit = 0;
+ indicate_hidden = true;
+ shrink = true;
+ separator_height = 0;
+ padding = 16;
+ horizontal_padding = 24;
+ frame_width = 0;
+ sort = false;
+ idle_threshold = 60;
+ font = "Open Sans 9";
+ line_height = 4;
+ markup = "full";
+ format = "%s\\n%b";
+ alignment = "left";
+ show_age_threshold = 60;
+ word_wrap = true;
+ ignore_newline = false;
+ stack_duplicates = false;
+ hide_duplicate_count = true;
+ show_indicators = false;
+ icon_position = "left";
+ max_icon_size = 40;
+ sticky_history = true;
+ history_length = 100;
+ browser = "${pkgs.firefox}/bin/firefox -new-tab";
+ always_run_script = true;
+ title = "Dunst";
+ class = "Dunst";
+ corner_radius = 15;
+
+ script = historyScript.outPath;
+ };
+
+ urgency_low = {
+ background = config.catppuccin.hexcolors.crust;
+ foreground = config.catppuccin.hexcolors.text;
+ timeout = 3;
+ };
+
+ urgency_normal = {
+ background = config.catppuccin.hexcolors.crust;
+ foreground = config.catppuccin.hexcolors.text;
+ timeout = 5;
+ };
+
+ urgency_critical = {
+ background = config.catppuccin.hexcolors.crust;
+ foreground = config.catppuccin.hexcolors.text;
+ frame_color = config.catppuccin.hexcolors.red;
+ timeout = 0;
+ };
+ };
+ };
+}
diff --git a/modules/user/eww.nix b/modules/user/eww.nix
new file mode 100644
index 0000000..13db70e
--- /dev/null
+++ b/modules/user/eww.nix
@@ -0,0 +1,29 @@
+{ config, lib, pkgs, ... }:
+let
+ inherit (lib) boolToString defaultTo;
+ res = pkgs.stdenvNoCC.mkDerivation {
+ pname = "eww-wayland-config";
+ version = "1.0.0";
+ dontUnpack = true;
+ installPhase = ''
+ cp -r ${../../res/eww} $out
+
+ substituteInPlace $out/eww.yuck \
+ --replace-fail "_BAT_ENABLED_" "${boolToString (config.me.batteryDevice != null)}" \
+ --replace-fail "_BAT_PATH_" "${defaultTo "" config.me.batteryDevice}" \
+ --replace-fail "_BT_ENABLED_" "${boolToString config.me.hasBluetooth}" \
+ --replace-fail "_WIFI_ENABLED_" "${boolToString config.me.hasWifi}"
+
+ substituteInPlace $out/eww.scss \
+ --replace-fail "EWW_BACKGROUND" "${config.catppuccin.hexcolors.crust}" \
+ --replace-fail "EWW_TEXT" "${config.catppuccin.hexcolors.text}" \
+ --replace-fail "EWW_ACCENT" "${config.catppuccin.hexcolors.${config.catppuccin.accent}}"
+ '';
+ };
+in {
+ home.packages = with pkgs; [ iw socat ];
+ programs.eww = {
+ enable = true;
+ };
+ xdg.configFile."eww".source = res;
+}
diff --git a/modules/user/git.nix b/modules/user/git.nix
new file mode 100644
index 0000000..ca2762e
--- /dev/null
+++ b/modules/user/git.nix
@@ -0,0 +1,16 @@
+{ ... }: {
+ programs.git = {
+ enable = true;
+ signing = {
+ key = "059F098EBF0E9A13E10A46BF6500251E087653C9";
+ signByDefault = true;
+ };
+ settings = {
+ user.name = "Cilly Leang";
+ user.email = "mini@cilly.moe";
+ core.abbrev = 11;
+ safe.directory = "/home/rin/Projects/flakes";
+ init.defaultBranch = "master";
+ };
+ };
+}
diff --git a/modules/user/gpg.nix b/modules/user/gpg.nix
new file mode 100644
index 0000000..dba731f
--- /dev/null
+++ b/modules/user/gpg.nix
@@ -0,0 +1,10 @@
+{ config, pkgs, ... }: {
+ programs.gpg = {
+ enable = true;
+ homedir = "${config.xdg.dataHome}/gnupg";
+ };
+ services.gpg-agent = {
+ enable = true;
+ pinentry.package = pkgs.pinentry-gnome3;
+ };
+}
diff --git a/modules/user/hypridle.nix b/modules/user/hypridle.nix
new file mode 100644
index 0000000..af7af86
--- /dev/null
+++ b/modules/user/hypridle.nix
@@ -0,0 +1,45 @@
+{ config, lib, pkgs, ... }:
+let
+ kblight = "brightnessctl -d ${config.me.kbBacklightDevice}";
+in
+{
+ home.packages = [ config.services.hypridle.package ];
+ services.hypridle = {
+ enable = true;
+ settings = {
+ general = {
+ lock_cmd = "pidof hyprlock || hyprlock";
+ before_sleep_cmd = "${lib.getExe pkgs.playerctl} pause; loginctl lock-session";
+ after_sleep_cmd = "hyprctl dispatch dpms on";
+ };
+
+ listener = lib.optionals (config.me.kbBacklightDevice != null) [
+ {
+ timeout = 120;
+ on-timeout = "${kblight} -s && ${kblight} 0";
+ on-resume = "${kblight} -r";
+ }
+ ] ++ [
+ {
+ timeout = 150;
+ on-timeout = "brightnessctl -s && brightnessctl 50%-";
+ on-resume = "brightnessctl -r";
+ }
+ {
+ timeout = 180;
+ on-timeout = "brightnessctl -r && loginctl lock-session";
+ }
+ {
+ timeout = 195;
+ on-timeout = "hyprctl dispatch dpms off";
+ on-resume = "hyprctl dispatch dpms on";
+ }
+ ] ++ lib.optionals (config.me.environment == "laptop") [
+ {
+ timeout = 600;
+ on-timeout = "systemctl suspend";
+ }
+ ];
+ };
+ };
+}
diff --git a/modules/user/hyprlock.nix b/modules/user/hyprlock.nix
new file mode 100644
index 0000000..529c522
--- /dev/null
+++ b/modules/user/hyprlock.nix
@@ -0,0 +1,148 @@
+{ config, lib, ... }:
+let
+ scaling = if config.me.hidpi then 1 else 0.5;
+ s = value: if builtins.isInt value || builtins.isFloat value
+ then
+ builtins.floor (value * scaling)
+ else if builtins.isList value
+ then
+ lib.strings.concatMapStringsSep "," (v: builtins.toString (scaling * v)) value
+ else
+ builtins.throw "invalid scaled value type ${builtins.typeOf value} for ${value}";
+ sn = value: s (builtins.map (v: (-v)) value);
+in
+{
+ programs.hyprlock = {
+ enable = true;
+ settings = {
+ general = {
+ disable_loading_bar = true;
+ hide_cursor = true;
+ };
+ auth = {
+ fingerprint = {
+ enabled = config.me.hasFingerprint;
+ ready_message = "Scan fingerprint to unlock";
+ };
+ };
+ background = {
+ monitor = "";
+ color = "$base";
+ };
+ shape = lib.optionals (config.me.batteryDevice != null) [
+ # Battery pill
+ {
+ monitor = "";
+ size = s [165 65];
+ color = "$crust";
+ rounding = -1;
+ halign = "right";
+ valign = "top";
+ position = sn [595 10];
+ }
+ ] ++ [
+ # Time pill
+ {
+ monitor = "";
+ size = s [545 65];
+ color = "$crust";
+ rounding = -1;
+ halign = "right";
+ valign = "top";
+ position = sn [40 10];
+ }
+ ];
+ label = lib.optionals config.me.hasFingerprint [
+ # Fingerprint icon
+ {
+ monitor = "";
+ color = "$text";
+ font_family = "Material Symbols Outlined";
+ font_size = s 64;
+ halign = "center";
+ valign = "top";
+ position = sn [0 100];
+ text = "";
+ }
+ # Fingerprint text
+ {
+ monitor = "";
+ color = "$text";
+ text = "$FPRINTPROMPT";
+ font_size = s 25;
+ font_family = "Open Sans";
+ position = sn [0 235];
+ halign = "center";
+ valign = "top";
+ }
+ ] ++ lib.optionals (config.me.batteryDevice != null) [
+ # Battery icon
+ {
+ monitor = "";
+ text = "";
+ color = "$accent";
+ font_family = "Material Symbols Outlined";
+ font_size = s 27;
+ position = sn [695 20];
+ halign = "right";
+ valign = "top";
+ }
+ # Battery percentage
+ {
+ monitor = "";
+ text = ''cmd[update:60000] echo "$(cat /sys/class/power_supply/${config.me.batteryDevice}/capacity)%"'';
+ color = "$text";
+ font_size = s 23;
+ font_family = "Open Sans";
+ position = sn [625 20];
+ halign = "right";
+ valign = "top";
+ }
+ ] ++ [
+ # Time and Date
+ {
+ monitor = "";
+ color = "$text";
+ font_family = "Open Sans";
+ font_size = s 23;
+ halign = "right";
+ valign = "top";
+ position = sn [70 20];
+ text = ''cmd[update:1000] echo "$(date '+%A, %d %B %Y') $(date +%H:%M)$(date +:%S)"'';
+ }
+
+ # Fail text under input
+ {
+ monitor = "";
+ color = "$red";
+ font_family = "Open Sans";
+ font_size = s 25;
+ text = "$FAIL $ATTEMPTS[]";
+ position = sn [0 200];
+ halign = "center";
+ valign = "center";
+ }
+ ];
+ input-field = {
+ monitor = "";
+ size = s [600 120];
+ outline_thickness = s 4;
+ check_color = "$peach";
+ dots_size = 0.2;
+ dots_spacing = 0.2;
+ dots_center = true;
+ fail_text = "";
+ font_color = "$text";
+ inner_color = "$crust";
+ outer_color = "$base";
+ placeholder_text = "Password";
+ fade_on_empty = false;
+ hide_input = false;
+ capslock_color = "$yellow";
+ position = sn [0 47];
+ halign = "center";
+ valign = "center";
+ };
+ };
+ };
+}
diff --git a/modules/user/kitty.nix b/modules/user/kitty.nix
new file mode 100644
index 0000000..ddc189a
--- /dev/null
+++ b/modules/user/kitty.nix
@@ -0,0 +1,19 @@
+{ config, pkgs, ... }: {
+ programs.kitty = {
+ enable = true;
+ font = {
+ package = pkgs.cascadia-code;
+ name = "Cascadia Code PL";
+ size = 13;
+ };
+ settings = {
+ font_features = "-ss01 +ss19";
+ enable_audio_bell = false;
+ color5 = config.catppuccin.hexcolors.mauve;
+ color13 = config.catppuccin.hexcolors.mauve;
+ window_margin_width = 5;
+ scrollback_pager = ''nvim --noplugin -c "set signcolumn=no showtabline=0" -c "silent write! /tmp/kitty_scrollback_buffer | te cat /tmp/kitty_scrollback_buffer - " -c "autocmd VimEnter * normal G"'';
+ scrollback_pager_history_size = 2;
+ };
+ };
+}
diff --git a/users/rin/mpv.nix b/modules/user/mpv.nix
similarity index 62%
rename from users/rin/mpv.nix
rename to modules/user/mpv.nix
index c740392..6ef3da4 100644
--- a/users/rin/mpv.nix
+++ b/modules/user/mpv.nix
@@ -1,7 +1,7 @@
-{ config, pkgs, ... }: {
+{ pkgs, ... }: {
programs.mpv = {
enable = true;
- package = pkgs.wrapMpv pkgs.mpv-unwrapped {
+ package = pkgs.mpv.override {
youtubeSupport = true;
scripts = [ pkgs.mpvScripts.mpris ];
};
diff --git a/modules/user/neovim-minimal.nix b/modules/user/neovim-minimal.nix
new file mode 100644
index 0000000..392097d
--- /dev/null
+++ b/modules/user/neovim-minimal.nix
@@ -0,0 +1,38 @@
+{ config, lib, pkgs, ... }: {
+ systemd.user.tmpfiles.rules = [
+ "D %t/vim/swap 0755 - - - -"
+ "D %t/vim/undo 0755 - - - -"
+ ];
+ programs.neovim = {
+ enable = true;
+ viAlias = true;
+ vimAlias = true;
+ vimdiffAlias = true;
+ withNodeJs = false;
+ withPython3 = false;
+ withRuby = false;
+
+ plugins = with pkgs.vimPlugins; [
+ fzf-vim
+ lualine-nvim
+ tokyonight-nvim
+ vim-fugitive
+ vim-nix
+ vim-repeat
+ vim-signify
+ vim-surround
+
+ (nvim-treesitter.withPlugins (p: with p; [
+ tree-sitter-json
+ tree-sitter-lua
+ tree-sitter-nix
+ tree-sitter-toml
+ tree-sitter-yaml
+ ]))
+ ];
+
+ extraConfig = ''
+ luafile ${../../res/config-minimal.lua}
+ '';
+ };
+}
diff --git a/modules/user/neovim.nix b/modules/user/neovim.nix
new file mode 100644
index 0000000..2b8d4c1
--- /dev/null
+++ b/modules/user/neovim.nix
@@ -0,0 +1,101 @@
+{ config, lib, pkgs, sysConfig, ... }:
+let
+ luaconf = pkgs.writeText "config.lua"
+ (lib.replaceStrings
+ ["{{OMNISHARP_PATH}}" "{{DART_PATH}}" "{{CATPPUCCIN_FLAVOUR}}" "{{USERNAME}}" "{{HOSTNAME}}"]
+ ["${pkgs.omnisharp-roslyn}/bin/OmniSharp" "${pkgs.dart}/bin/dart" config.catppuccin.nvim.flavor config.home.username sysConfig.networking.hostName]
+ (builtins.readFile ../../res/config.lua));
+in {
+ systemd.user.tmpfiles.rules = [
+ "D %t/vim/swap 0755 - - - -"
+ "D %t/vim/undo 0755 - - - -"
+ ];
+ programs.neovim = {
+ enable = true;
+ viAlias = true;
+ vimAlias = true;
+ vimdiffAlias = true;
+ #package = pkgs.neovim-nightly;
+ withNodeJs = true;
+ withPython3 = true;
+ withRuby = false;
+
+ extraPackages = with pkgs; [
+ nixd
+ rust-analyzer
+ texlab
+ astro-language-server
+ tailwindcss-language-server
+ diagnostic-languageserver
+ eslint_d
+ typescript-language-server
+ vscode-langservers-extracted
+ yaml-language-server
+ ];
+
+ plugins = with pkgs.vimPlugins; [
+ autoclose-nvim
+ auto-save-nvim
+ flutter-tools-nvim
+ fzf-vim
+ fzf-lsp-nvim
+ lualine-nvim
+ nvim-ts-autotag
+ nvim-web-devicons
+ plenary-nvim
+ tokyonight-nvim
+ vim-fugitive
+ vim-latex-live-preview
+ vim-nix
+ vim-repeat
+ vim-signify
+ vim-surround
+ vimtex
+ lsp_signature-nvim
+
+ nvim-cmp
+ nvim-dap
+ nvim-highlight-colors
+ nvim-lspconfig
+ cmp-nvim-lsp
+ cmp_luasnip
+ luasnip
+
+ #(pkgs.me.nvim-treesitter-nightly.withPlugins (p: with p; [
+ (nvim-treesitter.withPlugins (p: with p; [
+ tree-sitter-astro
+ tree-sitter-bash
+ tree-sitter-c
+ tree-sitter-c-sharp
+ tree-sitter-cpp
+ tree-sitter-groovy
+ tree-sitter-html
+ tree-sitter-java
+ tree-sitter-javascript
+ tree-sitter-json
+ tree-sitter-kotlin
+ tree-sitter-latex
+ tree-sitter-lua
+ tree-sitter-markdown
+ tree-sitter-nix
+ tree-sitter-php
+ tree-sitter-python
+ tree-sitter-query
+ tree-sitter-regex
+ tree-sitter-rust
+ tree-sitter-swift
+ tree-sitter-toml
+ tree-sitter-tsx
+ tree-sitter-typescript
+ tree-sitter-vim
+ tree-sitter-vimdoc
+ tree-sitter-xml
+ tree-sitter-yaml
+ ]))
+ ];
+
+ extraConfig = ''
+ luafile ${luaconf}
+ '';
+ };
+}
diff --git a/users/rin/npm.nix b/modules/user/npm.nix
similarity index 85%
rename from users/rin/npm.nix
rename to modules/user/npm.nix
index db86429..815cd46 100644
--- a/users/rin/npm.nix
+++ b/modules/user/npm.nix
@@ -1,6 +1,4 @@
{ config, pkgs, ... }: {
- home.packages = [ pkgs.nodejs ];
-
xdg.configFile."npm/npmrc".text = ''
cache=${config.xdg.dataHome}/npm/cache
prefix=${config.xdg.dataHome}/npm
diff --git a/modules/user/obs.nix b/modules/user/obs.nix
new file mode 100644
index 0000000..9ad912e
--- /dev/null
+++ b/modules/user/obs.nix
@@ -0,0 +1,10 @@
+{ pkgs, ... }: {
+ programs.obs-studio = {
+ enable = true;
+ plugins = with pkgs.obs-studio-plugins; [
+ obs-pipewire-audio-capture
+ obs-vaapi
+ obs-vkcapture
+ ];
+ };
+}
diff --git a/modules/user/rofi.nix b/modules/user/rofi.nix
new file mode 100644
index 0000000..1f11d06
--- /dev/null
+++ b/modules/user/rofi.nix
@@ -0,0 +1,22 @@
+{ config, pkgs, ... }:
+let
+ theme = pkgs.stdenvNoCC.mkDerivation {
+ pname = "rofi-theme";
+ version = "1.0.0";
+ dontUnpack = true;
+ installPhase = ''
+ cp ${../../res/theme.rasi} $out
+ substituteInPlace $out \
+ --replace-fail "CAT_BACKGROUND" "${config.catppuccin.hexcolors.crust}" \
+ --replace-fail "CAT_TEXT" "${config.catppuccin.hexcolors.text}" \
+ --replace-fail "CAT_ACCENT" "${config.catppuccin.hexcolors.${config.catppuccin.accent}}" \
+ --replace-fail "CAT_PLACEHOLDER" "${config.catppuccin.hexcolors.overlay1}"
+ '';
+ };
+in {
+ programs.rofi = {
+ enable = true;
+ theme = "theme";
+ };
+ xdg.configFile."rofi/theme.rasi".source = theme;
+}
diff --git a/modules/user/sessionVariables.nix b/modules/user/sessionVariables.nix
new file mode 100644
index 0000000..22a6b09
--- /dev/null
+++ b/modules/user/sessionVariables.nix
@@ -0,0 +1,30 @@
+{ config, ... }: {
+ home.sessionVariables = {
+ PATH = builtins.concatStringsSep ":" [
+ "${config.home.homeDirectory}/.local/bin"
+ "${config.xdg.dataHome}/npm/bin"
+ "$PATH"
+ ];
+
+ EDITOR = "nvim";
+
+ _JAVA_OPTIONS = "-Djava.util.prefs.userRoot=${config.xdg.configHome}/java";
+ CARGO_HOME = "${config.xdg.dataHome}/cargo";
+ DIRENV_LOG_FORMAT = "";
+ FZF_DEFAULT_COMMAND = "fd --type f --hidden --follow --exclude .git";
+ GNUPGHOME = "${config.xdg.dataHome}/gnupg";
+ GTK2_RC_FILES = "${config.xdg.configHome}/gtk-2.0/gtkrc";
+ LESSHISTFILE = "-";
+ LUTRIS_SKIP_INIT = "1";
+ NIXOS_OZONE_WL = "1";
+ NODE_REPL_HISTORY = "${config.xdg.dataHome}/nodejs/repl_history";
+ NPM_CONFIG_USERCONFIG = "${config.xdg.configHome}/npm/npmrc";
+ PUB_CACHE = "${config.xdg.cacheHome}/dart";
+ WGETRC = "${config.xdg.configHome}/wgetrc";
+
+ WINEPREFIX = "${config.xdg.dataHome}/wine64";
+ WINEARCH = "win64";
+ # Stops wine from creating filetype associations
+ WINEDLLOVERRIDES = "winemenubuilder.exe=d";
+ };
+}
diff --git a/modules/user/spicetify.nix b/modules/user/spicetify.nix
new file mode 100644
index 0000000..ec854c4
--- /dev/null
+++ b/modules/user/spicetify.nix
@@ -0,0 +1,50 @@
+{ config, inputs, lib, pkgs, ... }:
+let
+ spicePkgs = inputs.spicetify-nix.legacyPackages.${pkgs.system};
+in
+{
+ imports = [ inputs.spicetify-nix.homeManagerModules.spicetify ];
+
+ programs.spicetify = {
+ enable = true;
+ alwaysEnableDevTools = true;
+ theme = spicePkgs.themes.catppuccin // {
+ additionalCss = ''
+ /* Removes "About the artist" text in now playing menu */
+ .main-nowPlayingView-sectionHeaderText {
+ display: none;
+ }
+
+ /* Removes gradient in now playing menu */
+ .main-nowPlayingView-contextItemInfo:before {
+ background: none;
+ }
+
+ /* Removes gradient above artist image */
+ /* https://stackoverflow.com/a/77015731 < this is so smart */
+ .main-nowPlayingView-aboutArtistV2ImageContainer.main-nowPlayingView-aboutArtistV2Image {
+ background-size: 0% 0%, cover;
+ }
+ '';
+ };
+ colorScheme = config.catppuccin.flavor;
+
+ enabledSnippets = with spicePkgs.snippets; [
+ removeGradient
+ ];
+ enabledCustomApps = with spicePkgs.apps; [
+ lyricsPlus
+ ];
+ enabledExtensions = with spicePkgs.extensions; [
+ fullAppDisplay
+ shuffle
+ hidePodcasts
+
+ songStats
+ history
+ volumePercentage
+ ];
+ };
+
+ home.file.".local/bin/spotify".source = lib.getExe config.programs.spicetify.spicedSpotify;
+}
diff --git a/modules/user/theming.nix b/modules/user/theming.nix
new file mode 100644
index 0000000..00ab88f
--- /dev/null
+++ b/modules/user/theming.nix
@@ -0,0 +1,29 @@
+{ config, pkgs, ... }: {
+ gtk = {
+ enable = true;
+ gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc";
+ font = {
+ package = pkgs.open-sans;
+ name = "Open Sans";
+ size = 11;
+ };
+ gtk3.extraConfig = {
+ gtk-application-prefer-dark-theme = if config.catppuccin.flavor == "latte" then "0" else "1";
+ };
+ gtk4.extraConfig = {
+ gtk-application-prefer-dark-theme = if config.catppuccin.flavor == "latte" then "0" else "1";
+ };
+ };
+
+ dconf.settings = {
+ "org/gnome/desktop/interface".color-scheme = if config.catppuccin.flavor == "latte" then "prefer-light" else "prefer-dark";
+ };
+
+ home.pointerCursor = {
+ package = pkgs.yaru-theme;
+ name = "Yaru";
+ size = 24;
+ gtk.enable = true;
+ x11.enable = true;
+ };
+}
diff --git a/users/rin/xdg.nix b/modules/user/xdg.nix
similarity index 64%
rename from users/rin/xdg.nix
rename to modules/user/xdg.nix
index 1515e08..01802f0 100644
--- a/users/rin/xdg.nix
+++ b/modules/user/xdg.nix
@@ -1,9 +1,11 @@
{ config, ... }:
let
- genMimes = mimeTypes: builtins.listToAttrs (builtins.map (mimeType: {
- name = mimeType;
- value = "brave-browser.desktop";
- }) mimeTypes);
+ genMimes = mimeTypes: builtins.listToAttrs (
+ builtins.map (mimeType: {
+ name = mimeType;
+ value = "firefox.desktop";
+ }) mimeTypes
+ );
mimes = genMimes [
"x-scheme-handler/http"
@@ -17,19 +19,20 @@ let
"application/x-extension-xhtml"
"application/x-extension-xht"
] // {
- # XXX: this thing found it unwritable so it just deletes it and rewrite???
"x-scheme-handler/tg" = "userapp-Kotatogram Desktop-CHJI40.desktop";
+ "image/png" = "feh.desktop";
+ "image/jpeg" = "feh.desktop";
};
in {
xdg = {
enable = true;
mime.enable = true;
- mimeApps = {
- enable = true;
+ # mimeApps = {
+ # enable = true;
- associations.added = mimes;
- defaultApplications = mimes;
- };
+ # associations.added = mimes;
+ # defaultApplications = mimes;
+ # };
};
# XXX: might need to be moved
diff --git a/modules/user/zsh.nix b/modules/user/zsh.nix
new file mode 100644
index 0000000..1eb736c
--- /dev/null
+++ b/modules/user/zsh.nix
@@ -0,0 +1,166 @@
+# vim: ft=nix
+{ config, inputs, pkgs, sysConfig, ... }:
+let
+ lib = pkgs.lib;
+
+ pluginFromInput = name: {
+ inherit name;
+ src = inputs.${name};
+ };
+
+ abbrs = {
+ e = "$EDITOR";
+ rs = "source ~/.config/zsh/.zshrc";
+
+ ll = "ls -al";
+ q = "exit";
+
+ peach = "ssh lava@peach";
+ bunny = "ssh bunny@peach";
+
+ fa = "grep -Inr";
+ fai = "grep -Iinr";
+
+ g1 = "xgamma -gamma 1";
+ g3 = "xgamma -gamma 1.3";
+
+ bat = "echo 'battery' | doas tee /sys/class/drm/card1/device/power_dpm_state";
+ bal = "echo 'balanced' | doas tee /sys/class/drm/card1/device/power_dpm_state";
+ sclk = "doas setclock 50000 70000 800";
+
+ sysu = "doas systemctl restart";
+ sysd = "doas systemctl stop";
+ syss = "doas systemctl status";
+ usysu = "systemctl --user restart";
+ usysd = "systemctl --user stop";
+ usyss = "systemctl --user status";
+ j = "doas journalctl -b";
+ jf = "doas journalctl -f";
+
+ fl = "cd ~/Projects/flakes";
+ nr = "nh os switch";
+ nb = "nh os boot";
+
+ gs = "git status";
+ ga = "git add";
+ gaa = "git add .";
+ gc = "git commit";
+ gac = "git add .; git commit";
+ gcm = "git commit -m";
+ gco = "git checkout";
+ gd = "git diff";
+ gds = "git diff --staged";
+ gf = "git commit --amend --reset-author --no-edit";
+ gfe = "git commit --amend --reset-author";
+ gl = "git log";
+ gr = "git rebase -i";
+ };
+
+ genAbbrs = lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "abbr add -S --quiet ${k}=${lib.escapeShellArg v}") abbrs);
+ cursorShape = ''
+ function zle-keymap-select {
+ if [[ $KEYMAP == vicmd ]] ||
+ [[ $1 = 'block' ]]; then
+ echo -ne '\e[1 q'
+ elif [[ $KEYMAP == main ]] ||
+ [[ $KEYMAP == viins ]] ||
+ [[ $KEYMAP = "" ]] ||
+ [[ $1 = 'beam' ]]; then
+ echo -ne '\e[5 q'
+ fi
+ }
+ zle -N zle-keymap-select
+ zle-line-init() {
+ zle -K viins
+ echo -ne "\e[5 q"
+ }
+ zle -N zle-line-init
+ echo -ne '\e[5 q'
+ preexec() { echo -ne '\e[5 q' ;}
+ '';
+ direnv = ''
+ eval "$(direnv hook zsh)"
+ '';
+ pure = ''
+ autoload -U promptinit; promptinit
+ prompt pure
+ '';
+ viExtraNav = ''
+ bindkey -M menuselect 'h' vi-backward-char
+ bindkey -M menuselect 'k' vi-up-line-or-history
+ bindkey -M menuselect 'l' vi-forward-char
+ bindkey -M menuselect 'j' vi-down-line-or-history
+
+ bindkey -v '^?' backward-delete-char
+ bindkey -v '^R' history-incremental-pattern-search-backward
+ bindkey '^[[A' history-substring-search-up
+ bindkey '^[[B' history-substring-search-down
+ bindkey -M vicmd 'k' history-substring-search-up
+ bindkey -M vicmd 'j' history-substring-search-down
+ '';
+ disableExecute = ''
+ bindkey -a -r ':'
+ '';
+in {
+ programs.zsh = {
+ enable = true;
+ dotDir = "${config.xdg.configHome}/zsh";
+
+ autocd = true;
+ defaultKeymap = "viins";
+
+ history = {
+ extended = true;
+ path = "${config.xdg.dataHome}/zsh/history";
+ save = 10000000;
+ size = 10000000;
+ };
+
+ enableCompletion = true;
+
+ localVariables = {
+ KEYTIMEOUT = "1";
+ #PS1 = "%B%{$fg[red]%}[%{$fg[yellow]%}%n%{$fg[green]%}@%{$fg[blue]%}%M %{$fg[magenta]%}%~%{$fg[red]%}]%{$reset_color%}$%b ";
+ ZSH_AUTOSUGGEST_STRATEGY = [ "completion" ];
+ ZSH_AUTOSUGGEST_USE_ASYNC = true;
+ ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE = 40;
+ };
+
+ shellAliases = {
+ ls = "ls --color=auto --group-directories-first -v";
+ diff = "diff -Naur --color=auto";
+ };
+ initContent = lib.mkMerge [
+ (lib.mkBefore ''
+ autoload -U colors && colors
+ '')
+ (lib.mkOrder 550 ''
+ fpath+=(/run/current-system/sw/share/zsh/site-functions)
+ zstyle ':completion:*' completer _complete
+ zstyle ':completion:*' matcher-list "" 'm:{[:lower:][:upper:]-_}={[:upper:][:lower:]_-}' '+l:|=* r:|=*'
+ zstyle ':completion:*' menu select
+ _comp_options+=(globdots)
+ zmodload zsh/complist
+ '')
+ (lib.concatStringsSep "\n" [
+ pure
+ cursorShape
+ direnv
+ genAbbrs
+ viExtraNav
+ disableExecute
+ ])
+ ];
+
+ plugins = builtins.map (e: pluginFromInput e) [
+ "pure"
+ "zsh-abbr"
+ "zsh-history-substring-search"
+ "fast-syntax-highlighting"
+ ] ++ [{
+ name = "zsh-autosuggestions";
+ src = pkgs.zsh-autosuggestions + "/share/zsh-autosuggestions";
+ file = "zsh-autosuggestions.zsh";
+ }];
+ };
+}
diff --git a/overlays/bitwarden-desktop.nix b/overlays/bitwarden-desktop.nix
new file mode 100644
index 0000000..2d7be24
--- /dev/null
+++ b/overlays/bitwarden-desktop.nix
@@ -0,0 +1,19 @@
+# https://github.com/NixOS/nixpkgs/pull/374068
+self: super: {
+ bitwarden-desktop = super.bitwarden-desktop.overrideAttrs (o: {
+ preBuild = o.preBuild + ''
+ pushd apps/desktop/desktop_native/proxy
+ cargo build --offline --bin desktop_proxy --release
+ popd
+ '';
+ installPhase = builtins.replaceStrings ["runHook preInstall"] [''
+ runHook preInstall
+
+ install -Dm755 -t $out/bin apps/desktop/desktop_native/target/release/desktop_proxy
+
+ mkdir -p $out/lib/mozilla/native-messaging-hosts
+ substituteAll ${./patches/firefox-native-messaging-host.json} $out/lib/mozilla/native-messaging-hosts/com.8bit.bitwarden.json
+
+ ''] o.installPhase;
+ });
+}
diff --git a/overlays/cascadia-code.nix b/overlays/cascadia-code.nix
new file mode 100644
index 0000000..59ce553
--- /dev/null
+++ b/overlays/cascadia-code.nix
@@ -0,0 +1,12 @@
+self: super: {
+ cascadia-code = super.cascadia-code.overrideAttrs(o: {
+ installPhase = (builtins.replaceStrings ["runHook postInstall"] [""] o.installPhase) + ''
+ install -Dm644 otf/static/*.otf -t $out/share/fonts/opentype
+ install -Dm644 ttf/static/*.ttf -t $out/share/fonts/truetype
+ rm $out/share/fonts/opentype/*NF*
+ rm $out/share/fonts/truetype/*NF*
+ runHook postInstall
+ '';
+
+ });
+}
diff --git a/overlays/ccache.nix b/overlays/ccache.nix
new file mode 100644
index 0000000..e88593b
--- /dev/null
+++ b/overlays/ccache.nix
@@ -0,0 +1,25 @@
+self: super: {
+ ccacheWrapper = super.ccacheWrapper.override {
+ extraConfig = ''
+ export CCACHE_COMPRESS=1
+ export CCACHE_DIR="/var/cache/ccache"
+ export CCACHE_UMASK=007
+ if [ ! -d "$CCACHE_DIR" ]; then
+ echo "====="
+ echo "Directory '$CCACHE_DIR' does not exist"
+ echo "Please create it with:"
+ echo " sudo mkdir -m0770 '$CCACHE_DIR'"
+ echo " sudo chown root:nixbld '$CCACHE_DIR'"
+ echo "====="
+ exit 1
+ fi
+ if [ ! -w "$CCACHE_DIR" ]; then
+ echo "====="
+ echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)"
+ echo "Please verify its access permissions"
+ echo "====="
+ exit 1
+ fi
+ '';
+ };
+}
diff --git a/overlays/default.nix b/overlays/default.nix
new file mode 100644
index 0000000..cbe3e7e
--- /dev/null
+++ b/overlays/default.nix
@@ -0,0 +1,12 @@
+builtins.map (path: import path) [
+ ./bitwarden-desktop.nix
+ ./cascadia-code.nix
+ ./ccache.nix
+ ./eww.nix
+ ./jetbrains.nix
+ ./material-icons.nix
+ ./openldap.nix
+ ./steam.nix
+ ./utillinux.nix
+ ./wpa-supplicant.nix
+]
diff --git a/overlays/discord.nix b/overlays/discord.nix
deleted file mode 100644
index a80f48b..0000000
--- a/overlays/discord.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-self: super: {
- discord-canary = super.discord-canary.override rec {
- version = "0.0.125";
- src = builtins.fetchurl {
- url = "https://dl-canary.discordapp.net/apps/linux/${version}/discord-canary-${version}.tar.gz";
- sha256 = "0ly5a6l7rvl54mc39xma14jrcrf11q3ndnkkr16by5hy3palmz9g";
- };
- };
-}
diff --git a/overlays/eww.nix b/overlays/eww.nix
new file mode 100644
index 0000000..8d89aa1
--- /dev/null
+++ b/overlays/eww.nix
@@ -0,0 +1,8 @@
+self: super: {
+ eww = super.eww.overrideAttrs (old: rec {
+ patches = old.patches ++ [
+ # Use normal scroll events instead of smooth scroll ( due to https://bugzilla.gnome.org/show_bug.cgi?id=675959 )
+ ./patches/eww.patch
+ ];
+ });
+}
diff --git a/overlays/jetbrains.nix b/overlays/jetbrains.nix
new file mode 100644
index 0000000..dd1d1ad
--- /dev/null
+++ b/overlays/jetbrains.nix
@@ -0,0 +1,22 @@
+# https://github.com/NixOS/nixpkgs/issues/375254
+self: super: {
+ jetbrains = super.jetbrains // {
+ gateway = let
+ unwrapped = super.jetbrains.gateway;
+ in super.buildFHSEnv {
+ name = "gateway";
+ inherit (unwrapped) version;
+
+ runScript = super.writeScript "gateway-wrapper" ''
+ unset JETBRAINS_CLIENT_JDK
+ exec ${unwrapped}/bin/gateway "$@"
+ '';
+
+ meta = unwrapped.meta;
+
+ passthru = {
+ inherit unwrapped;
+ };
+ };
+ };
+}
diff --git a/overlays/linux-lava.nix b/overlays/linux-lava.nix
new file mode 100644
index 0000000..321532f
--- /dev/null
+++ b/overlays/linux-lava.nix
@@ -0,0 +1,26 @@
+self: super: let
+ llvmPackages = super.llvmPackages_19;
+ clangVersion = super.lib.versions.major llvmPackages.libclang.version;
+ addFlagsScript = "$out/nix-support/add-local-cc-cflags-before.sh";
+ cc = llvmPackages.stdenv.cc.override {
+ # :sob: see https://github.com/NixOS/nixpkgs/issues/142901
+ bintools = llvmPackages.bintools;
+
+ # https://github.com/NixOS/nixpkgs/issues/368850
+ extraBuildCommands = ''
+ cat <(echo "NIX_CC_WRAPPER_SUPPRESS_TARGET_WARNING=1") "${addFlagsScript}" > "${addFlagsScript}.new"
+ mv "${addFlagsScript}.new" "${addFlagsScript}"
+ substituteInPlace "$out/nix-support/cc-cflags" --replace " -nostdlibinc" ""
+ echo " -resource-dir=${llvmPackages.libclang.lib}/lib/clang/${clangVersion}" >> $out/nix-support/cc-cflags
+ '';
+ };
+ stdenv = super.overrideCC llvmPackages.stdenv cc;
+ ccacheStdenv = super.ccacheStdenv.override { inherit stdenv; };
+in {
+ linuxLavaEnv = {
+ inherit llvmPackages clangVersion cc stdenv ccacheStdenv;
+ };
+ rust-bindgen-unwrapped = super.rust-bindgen-unwrapped.override {
+ clang = cc;
+ };
+}
diff --git a/overlays/material-icons.nix b/overlays/material-icons.nix
index 9282bb2..9d1fcf9 100644
--- a/overlays/material-icons.nix
+++ b/overlays/material-icons.nix
@@ -1,17 +1,11 @@
self: super: {
- material-icons = let version = "4.0.0"; in super.fetchFromGitHub {
+ material-icons = let version = "4.0.0"; in (super.fetchFromGitHub {
name = "material-icons-${version}";
owner = "google";
repo = "material-design-icons";
rev = version;
- postFetch = ''
- tar xf $downloadedFile --strip=1
- mkdir -p $out/share/fonts/opentype $out/share/fonts/truetype
- cp font/*.ttf $out/share/fonts/truetype
- cp font/*.otf $out/share/fonts/opentype
- '';
sha256 = "05g5b8dn8vkjv98lmfgbd92wb5i8cfgc9j5f9ai86xl4r58yx10a";
meta = with super.lib; {
@@ -21,5 +15,12 @@ self: super: {
platforms = platforms.all;
maintainers = with maintainers; [ mpcsh ];
};
- };
+ }).overrideAttrs(o: {
+ postFetch = ''
+ tar xf $downloadedFile --strip=1
+ mkdir -p $out/share/fonts/opentype $out/share/fonts/truetype
+ cp font/*.ttf $out/share/fonts/truetype
+ cp font/*.otf $out/share/fonts/opentype
+ '';
+ });
}
diff --git a/overlays/mps-youtube.nix b/overlays/mps-youtube.nix
deleted file mode 100644
index 1c78b38..0000000
--- a/overlays/mps-youtube.nix
+++ /dev/null
@@ -1,10 +0,0 @@
-self: super: {
- mps-youtube = super.mps-youtube.overrideAttrs(old: rec {
- src = super.fetchFromGitHub {
- owner = "louisabraham";
- repo = "mps-youtube";
- rev = "234bc691f43f6df88d831409b2887fda45270636";
- sha256 = "14gsiacd05fsqb62zfapdll8dn1hbfi9vvh4wvk41qbxrla4p7d7";
- };
- });
-}
diff --git a/overlays/openldap.nix b/overlays/openldap.nix
new file mode 100644
index 0000000..f9b2b46
--- /dev/null
+++ b/overlays/openldap.nix
@@ -0,0 +1,9 @@
+self: super: {
+ # openldap i686 fails checks
+ # issue: https://github.com/NixOS/nixpkgs/issues/514113
+ # workaround: https://github.com/NixOS/nixpkgs/issues/513245#issuecomment-4320293674
+ # fix: https://github.com/NixOS/nixpkgs/pull/515956
+ openldap = super.openldap.overrideAttrs {
+ doCheck = !self.stdenv.hostPlatform.isi686;
+ };
+}
diff --git a/overlays/patches/eww.patch b/overlays/patches/eww.patch
new file mode 100644
index 0000000..ce7a685
--- /dev/null
+++ b/overlays/patches/eww.patch
@@ -0,0 +1,23 @@
+diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs
+index 16f1f17d063..08d54cbe343 100644
+--- a/crates/eww/src/widgets/widget_definitions.rs
++++ b/crates/eww/src/widgets/widget_definitions.rs
+@@ -679,11 +679,14 @@ fn build_gtk_event_box(bargs: &mut BuilderArgs) -> Result {
+ // @prop onscroll - event to execute when the user scrolls with the mouse over the widget. The placeholder `{}` used in the command will be replaced with either `up` or `down`.
+ prop(timeout: as_duration = Duration::from_millis(200), onscroll: as_string) {
+ gtk_widget.add_events(gdk::EventMask::SCROLL_MASK);
+- gtk_widget.add_events(gdk::EventMask::SMOOTH_SCROLL_MASK);
+ connect_signal_handler!(gtk_widget, gtk_widget.connect_scroll_event(move |_, evt| {
+- let delta = evt.delta().1;
+- if delta != 0f64 { // Ignore the first event https://bugzilla.gnome.org/show_bug.cgi?id=675959
+- run_command(timeout, &onscroll, &[if delta < 0f64 { "up" } else { "down" }]);
++ let dir = match evt.direction() {
++ gdk::ScrollDirection::Up => "up",
++ gdk::ScrollDirection::Down => "down",
++ _ => "",
++ };
++ if dir != "" {
++ run_command(timeout, &onscroll, &[dir]);
+ }
+ gtk::Inhibit(false)
+ }));
diff --git a/overlays/patches/firefox-native-messaging-host.json b/overlays/patches/firefox-native-messaging-host.json
new file mode 100644
index 0000000..e9f5f99
--- /dev/null
+++ b/overlays/patches/firefox-native-messaging-host.json
@@ -0,0 +1,7 @@
+{
+ "name": "com.8bit.bitwarden",
+ "description": "Bitwarden desktop <-> browser bridge",
+ "path": "@out@/bin/desktop_proxy",
+ "type": "stdio",
+ "allowed_extensions": ["{446900e4-71c2-419f-a6a7-df9c091e268b}"]
+}
diff --git a/overlays/patches/startx.patch b/overlays/patches/startx.patch
deleted file mode 100644
index da1cdea..0000000
--- a/overlays/patches/startx.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-diff --git a/startx.cpp b/startx.cpp
-index 125c398..296b29f 100644
---- a/startx.cpp
-+++ b/startx.cpp
-@@ -47,10 +47,10 @@ XCOMM so export the new PATH just in case the user changes the shell
- export PATH
- #endif
-
--userclientrc=$HOME/.xinitrc
-+userclientrc="${XINITRC:-$HOME/.xinitrc}"
- sysclientrc=XINITDIR/xinitrc
-
--userserverrc=$HOME/.xserverrc
-+userserverrc="${XSERVERRC:-$HOME/.xserverrc}"
- sysserverrc=XINITDIR/xserverrc
- defaultclient=XTERM
- defaultserver=XSERVER
-@@ -270,7 +270,7 @@ if [ x"$enable_xauth" = x1 ] ; then
- dummy=0
-
- XCOMM create a file with auth information for the server. ':0' is a dummy.
-- xserverauthfile=$HOME/.serverauth.$$
-+ xserverauthfile=$XAUTHORITY
- trap "rm -f '$xserverauthfile'" HUP INT QUIT ILL TRAP KILL BUS TERM
- xauth -q -f "$xserverauthfile" << EOF
- add :$dummy . $mcookie
diff --git a/overlays/patches/transcrypt.patch b/overlays/patches/transcrypt.patch
deleted file mode 100644
index aec80dc..0000000
--- a/overlays/patches/transcrypt.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-diff --git a/transcrypt b/transcrypt
-index 610b94f..7cc5035 100755
---- a/transcrypt
-+++ b/transcrypt
-@@ -282,6 +282,7 @@ save_helper_scripts() {
-
- cat <<-'EOF' >"${GIT_DIR}/crypt/clean"
- #!/usr/bin/env bash
-+ PATH="$(transcrypt-depspathprefix 2>/dev/null)$PATH"
- filename=$1
- # ignore empty files
- if [[ -s $filename ]]; then
-@@ -304,6 +305,7 @@ save_helper_scripts() {
-
- cat <<-'EOF' >"${GIT_DIR}/crypt/smudge"
- #!/usr/bin/env bash
-+ PATH="$(transcrypt-depspathprefix 2>/dev/null)$PATH"
- tempfile=$(mktemp 2>/dev/null || mktemp -t tmp)
- trap 'rm -f "$tempfile"' EXIT
- cipher=$(git config --get --local transcrypt.cipher)
-@@ -313,6 +315,7 @@ save_helper_scripts() {
-
- cat <<-'EOF' >"${GIT_DIR}/crypt/textconv"
- #!/usr/bin/env bash
-+ PATH="$(transcrypt-depspathprefix 2>/dev/null)$PATH"
- filename=$1
- # ignore empty files
- if [[ -s $filename ]]; then
-@@ -324,6 +327,7 @@ save_helper_scripts() {
-
- cat <<-'EOF' >"${GIT_DIR}/crypt/merge"
- #!/usr/bin/env bash
-+ PATH="$(transcrypt-depspathprefix 2>/dev/null)$PATH"
-
- # Look up name of local branch/ref to which changes are being merged
- OURS_LABEL=$(git rev-parse --abbrev-ref HEAD)
-@@ -459,7 +463,7 @@ save_configuration() {
- git config merge.crypt.name 'Merge transcrypt secret files'
-
- # add a git alias for listing encrypted files
-- git config alias.ls-crypt "!git -c core.quotePath=false ls-files | git -c core.quotePath=false check-attr --stdin filter | awk 'BEGIN { FS = \":\" }; /crypt$/{ print \$1 }'"
-+ git config alias.ls-crypt "!PATH=\"\$(transcrypt-depspathprefix 2>/dev/null)\$PATH\"; git -c core.quotePath=false ls-files | git -c core.quotePath=false check-attr --stdin filter | awk 'BEGIN { FS = \":\" }; /crypt$/{ print \$1 }'"
- }
-
- # display the current configuration settings
diff --git a/overlays/patches/wpa-supplicant.patch b/overlays/patches/wpa-supplicant.patch
new file mode 100644
index 0000000..7c27be4
--- /dev/null
+++ b/overlays/patches/wpa-supplicant.patch
@@ -0,0 +1,13 @@
+diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in
+index 58a6228..fbe7de3 100644
+--- a/wpa_supplicant/systemd/wpa_supplicant.service.in
++++ b/wpa_supplicant/systemd/wpa_supplicant.service.in
+@@ -7,7 +7,7 @@ Wants=network.target
+ [Service]
+ Type=dbus
+ BusName=fi.w1.wpa_supplicant1
+-ExecStart=@BINDIR@/wpa_supplicant -u
++ExecStart=@BINDIR@/wpa_supplicant -u -q
+
+ [Install]
+ WantedBy=multi-user.target
diff --git a/overlays/picom.nix b/overlays/picom.nix
deleted file mode 100644
index 81e4c5f..0000000
--- a/overlays/picom.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-self: super: {
- picom = super.picom.overrideAttrs(old: {
- src = super.fetchFromGitHub {
- repo = "picom";
-
- owner = "ibhagwan";
- rev = "60eb00ce1b52aee46d343481d0530d5013ab850b";
- sha256 = "1m17znhl42sa6ry31yiy05j5ql6razajzd6s3k2wz4c63rc2fd1w";
-
- # owner = "jonaburg";
- # rev = "a8445684fe18946604848efb73ace9457b29bf80";
- # sha256 = "154s67p3lxdv9is3lnc32j48p7v9n18ga1j8ln1dxcnb38c19rj7";
- };
- });
-}
diff --git a/overlays/polybar.nix b/overlays/polybar.nix
deleted file mode 100644
index 17b201c..0000000
--- a/overlays/polybar.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-self: super: {
- polybar = super.polybar.override { i3Support = true; };
-}
diff --git a/overlays/steam.nix b/overlays/steam.nix
new file mode 100644
index 0000000..d3514f5
--- /dev/null
+++ b/overlays/steam.nix
@@ -0,0 +1,9 @@
+self: super: {
+ steam = super.steam.override {
+ extraPkgs = pkgs: with pkgs; [
+ libkrb5
+ keyutils
+ gamescope
+ ];
+ };
+}
diff --git a/overlays/transcrypt.nix b/overlays/transcrypt.nix
deleted file mode 100644
index cce969a..0000000
--- a/overlays/transcrypt.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-self: super: {
- transcrypt = super.transcrypt.overrideAttrs(o: rec {
- version = "2.1.0";
-
- patches = [ ./patches/transcrypt.patch ];
- src = super.fetchFromGitHub {
- owner = "elasticdog";
- repo = "transcrypt";
- rev = "v${version}";
- sha256 = "0bpz1hazbhfb6pqi68x55kq6a31bgh6vwij836slmi4jqiwvnh5a";
- };
- });
-}
diff --git a/overlays/utillinux.nix b/overlays/utillinux.nix
new file mode 100644
index 0000000..20db08a
--- /dev/null
+++ b/overlays/utillinux.nix
@@ -0,0 +1,4 @@
+self: super: {
+ # Waiting for nixpkgs#349783
+ utillinux = self.util-linux;
+}
diff --git a/overlays/winetricks.nix b/overlays/winetricks.nix
deleted file mode 100644
index 861911a..0000000
--- a/overlays/winetricks.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-self: super: {
- winetricks = super.winetricks.overrideAttrs(old: rec {
- name = "winetricks-20210528-073e2db";
- src = super.fetchFromGitHub {
- repo = "winetricks";
- owner = "Winetricks";
- rev = "073e2db522e7db56f83fab2338d831ac716264cb";
- sha256 = "1fic4wzc3qyw5bki4zx0h9g8yyhh8db806pwm8mz8qv4n7syk4dd";
- };
- });
-}
diff --git a/overlays/wpa-supplicant.nix b/overlays/wpa-supplicant.nix
new file mode 100644
index 0000000..1a2cf86
--- /dev/null
+++ b/overlays/wpa-supplicant.nix
@@ -0,0 +1,6 @@
+self: super: {
+ # Thanks https://discourse.nixos.org/t/journal-logs-spammed-with-ctrl-event-scan-failed/56316/5
+ wpa_supplicant = super.wpa_supplicant.overrideAttrs(o: {
+ patches = o.patches ++ [ ./patches/wpa-supplicant.patch ];
+ });
+}
diff --git a/overlays/xinit.nix b/overlays/xinit.nix
deleted file mode 100644
index f9e13c7..0000000
--- a/overlays/xinit.nix
+++ /dev/null
@@ -1,10 +0,0 @@
-self: super: {
- xorg = super.xorg // {
- xinit = super.xorg.xinit.overrideAttrs(o: {
- # Some info:
- # - Make startx use $XAUTHORITY as server auth files instead of .serverauth.$$
- # - Make startx respect $XINITRC and $XSERVERRC
- patches = o.patches ++ [ ./patches/startx.patch ];
- });
- };
-}
diff --git a/packages/default.nix b/packages/default.nix
new file mode 100644
index 0000000..4ae8658
--- /dev/null
+++ b/packages/default.nix
@@ -0,0 +1,12 @@
+{
+ callPackage,
+ linuxLavaNixpkgs,
+ inputs
+}: {
+ linux-lava = linuxLavaNixpkgs.callPackage ./linux-lava { inherit inputs; };
+ nvim-treesitter-nightly = callPackage ./nvim-treesitter-nightly { inherit inputs; };
+ psensor = callPackage ./psensor { };
+ spotify-adblock = callPackage ./spotify-adblock { inherit inputs; };
+ tree-sitter-jsonc = callPackage ./tree-sitter-jsonc { inherit inputs; };
+ wine-discord-ipc-bridge = callPackage ./wine-discord-ipc-bridge { inherit inputs; };
+}
diff --git a/packages/linux-lava/bluetooth.patch b/packages/linux-lava/bluetooth.patch
new file mode 100644
index 0000000..87e198c
--- /dev/null
+++ b/packages/linux-lava/bluetooth.patch
@@ -0,0 +1,13 @@
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index ef9689f8776..aabbc031b5f 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -759,6 +759,8 @@ static const struct usb_device_id quirks_table[] = {
+ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
++ { USB_DEVICE(0x2c4e, 0x0115), .driver_info = BTUSB_REALTEK |
++ BTUSB_WIDEBAND_SPEECH },
+
+ /* Additional Realtek 8821AE Bluetooth devices */
+ { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
diff --git a/packages/linux-lava/default.nix b/packages/linux-lava/default.nix
index f57ea08..aa288f5 100644
--- a/packages/linux-lava/default.nix
+++ b/packages/linux-lava/default.nix
@@ -1,129 +1,115 @@
-{
- buildLinux,
- kernelPatches,
- lib,
- ...
+{ buildLinux
+, callPackage
+, inputs
+, lib
+, linuxLavaEnv
+, useCcache ? false
+, ...
} @ args:
+
let
- major = "5";
- minor = "12";
- patch = "13";
- tkg = "2da317c20ed6f70085b195639b9aad2cacf31ab5";
+ sources = callPackage ./sources.nix { inherit inputs; };
+ kernel = buildLinux (args // {
+ inherit (sources) src kernelPatches;
+ stdenv = if useCcache then linuxLavaEnv.ccacheStdenv else linuxLavaEnv.stdenv;
+ version = "${sources.version}-tkg-Lava";
+ isZen = true;
+ extraMakeFlags = [ "LLVM=1" "LLVM_IAS=1" ];
+ # TODO:
+ # some stuff is set in pkgs/os-specific/linux/kernel/common-config.nix
+ # but i have no idea how to change it
+ structuredExtraConfig = with lib.kernel; builtins.mapAttrs (_: value: lib.mkForce value) {
+ LOCALVERSION = freeform "-tkg-Lava";
+ ZENIFY = yes;
+ WINESYNC = module;
- mm = "${major}.${minor}";
- mmp = "${major}.${minor}.${patch}";
+ #tkg defaults
+ DYNAMIC_FAULT = no;
+ DEFAULT_FQ_CODEL = no;
+ WERROR = no;
+ NTP_PPS = no;
+ ZSWAP_COMPRESSOR_DEFAULT_LZO = no;
+ PROFILE_ALL_BRANCHES = no;
+ CRYPTO_LZ4 = yes;
+ CRYPTO_LZ4HC = yes;
+ LZ4_COMPRESS = yes;
+ LZ4HC_COMPRESS = yes;
+ ZSWAP_COMPRESSOR_DEFAULT_LZ4 = yes;
+ DEBUG_FORCE_FUNCTION_ALIGN_64B = no;
+ X86_P6_NOP = no;
+ RCU_STRICT_GRACE_PERIOD = no;
+ ZSWAP_COMPRESSOR_DEFAULT = freeform "lz4";
+ CPU_FREQ_DEFAULT_GOV_SCHEDUTIL = yes;
+ CPU_FREQ_DEFAULT_GOV_ONDEMAND = no;
+ CPU_FREQ_DEFAULT_GOV_CONSERVATIVE = no;
+ CPU_FREQ_DEFAULT_GOV_PERFORMANCE = no;
+ CPU_FREQ_DEFAULT_GOV_PERFORMANCE_NODEF = no;
+ BLK_DEV_LOOP = module;
+ I2C_NCT6775 = module; # openrgb
- kernelUrl = name: sha256: builtins.fetchurl {
- inherit sha256;
- url = "https://cdn.kernel.org/pub/linux/kernel/v${major}.x/${name}.xz";
- };
+ # clang/llvm
+ LTO_CLANG_FULL = no;
+ LTO_CLANG_THIN = yes;
+ LTO_NONE = no;
+ KCSAN = no;
+ INIT_ON_FREE_DEFAULT_ON = yes;
+ INIT_STACK_ALL_ZERO = yes;
+ INIT_STACK_NONE = no;
- tkgPatch = name: sha256: {
- inherit name;
- patch = builtins.fetchurl {
- inherit sha256;
- url = "https://raw.githubusercontent.com/Frogging-Family/linux-tkg/${tkg}/linux-tkg-patches/${mm}/${name}.patch";
+ # bore
+ SCHED_BORE = yes;
+ MIN_BASE_SLICE_NS = freeform "2000000";
+
+ # tickless timers
+ HZ_PERIODIC = no;
+ NO_HZ = yes;
+ NO_HZ_COMMON = yes;
+ NO_HZ_FULL = yes;
+ NO_HZ_FULL_NODEF = yes;
+ NO_HZ_IDLE = no;
+ TICK_CPU_ACCOUNTING = no;
+ VIRT_CPU_ACCOUNTING_GEN = yes;
+ CONTEXT_TRACKING = yes;
+ CONTEXT_TRACKING_FORCE = no;
+ HZ_1000 = yes;
+ HZ_1000_NODEF = yes;
+
+ # preempt
+ PREEMPT = yes;
+ PREEMPT_COUNT = yes;
+ PREEMPT_VOLUNTARY = no;
+ PREEMPTION = yes;
+ PREEMPT_DYNAMIC = yes;
+
+ # disable numa
+ NUMA = no;
+ AMD_NUMA = no;
+ ACPI_NUMA = no;
+ X86_64_ACPI_NUMA = no;
+ NODES_SPAN_OTHER_NODES = no;
+ NUMA_EMU = no;
+ NODES_SHIFT = no;
+ NEED_MULTIPLE_NODES = no;
+ USE_PERCPU_NUMA_NODE_ID = no;
+
+ # disable ftrace
+ FUNCTION_TRACER = no;
+ FUNCTION_GRAPH_TRACER = no;
+
+ # disable misc debugging
+ SLUB_DEBUG = no;
+ PM_DEBUG = no;
+ PM_ADVANCED_DEBUG = no;
+ PM_SLEEP_DEBUG = no;
+ ACPI_DEBUG = no;
+ SCHED_DEBUG = no;
+ LATENCYTOP = no;
+ DEBUG_PREEMPT = no;
};
- };
-in buildLinux (args // {
- version = "${mmp}-tkg-Lava";
- isZen = true;
- # TODO:
- # some stuff is set in pkgs/os-specific/linux/kernel/common-config.nix
- # but i have no idea how to change it
- structuredExtraConfig = with lib.kernel; builtins.mapAttrs (_: value: lib.mkForce value) {
- LOCALVERSION = freeform "-tkg-Lava";
- ZENIFY = yes;
- FUTEX2 = yes;
- MHASWELL = yes;
- WINESYNC = module;
-
- # timers
- HZ_PERIODIC = no;
- NO_HZ = yes;
- NO_HZ_COMMON = yes;
- NO_HZ_FULL = yes;
- NO_HZ_IDLE = no;
- CONTEXT_TRACKING = yes;
- CONTEXT_TRACKING_FORCE = yes;
- # HZ_100 = yes;
- HZ_1000 = yes;
- HZ_1000_NODEF = yes;
-
- # preempt
- PREEMPT = yes;
- PREEMPT_COUNT = yes;
- PREEMPT_VOLUNTARY = no;
- PREEMPTION = yes;
- PREEMPT_DYNAMIC = yes;
-
- # scheduler
- # SCHED_ALT = yes;
- # SCHED_PDS = yes;
- CACULE_SCHED = yes;
-
- # cacule stuff
- SCHED_AUTOGROUP = yes;
- BSD_PROCESS_ACCT = no;
- TASK_XACCT = no;
- CGROUP_CPUACCT = no;
- CGROUP_DEBUG = no;
-
- # disable numa
- NUMA = no;
- AMD_NUMA = no;
- X86_64_ACPI_NUMA = no;
- NODES_SPAN_OTHER_NODES = no;
- NUMA_EMU = no;
- NEED_MULTIPLE_NODES = no;
- USE_PERCPU_NUMA_NODE_ID = no;
- ACPI_NUMA = no;
-
- # disable misc debugging
- SLUB_DEBUG = no;
- PM_DEBUG = no;
- PM_ADVANCED_DEBUG = no;
- PM_SLEEP_DEBUG = no;
- ACPI_DEBUG = no;
- SCHED_DEBUG = no;
- LATENCYTOP = no;
- DEBUG_PREEMPT = no;
- };
- ignoreConfigErrors = true;
-
- src = kernelUrl "linux-${mm}.tar" "0rn3z942vjc7bixjw066rm6kcr0x0wzgxqfq1f6xd113pzrgc3bx";
- kernelPatches = [
- # Kernel version patch
- {
- name = "patch-${patch}";
- patch = kernelUrl "patch-${mmp}" "17d38hns5qfbw1pajpa5y38v86r49nqnw7a3pwsay5fapj69z8w4";
- }
-
- # AMD SI manual clocking
- {
- name = "si-clock";
- patch = ./si-manual-clocking.patch;
- }
-
- # Graysky gcc patches
- {
- name = "graysky-gcc";
- patch = builtins.fetchurl {
- url = "https://raw.githubusercontent.com/graysky2/kernel_gcc_patch/d2e7942c19ee568638d3795cf52db5274a90ce0a/more-uarches-for-kernel-5.8+.patch";
- sha256 = "16jbknjlg12jxbj8cjkk01djvr01n9zz7qlzxppcqizmz55vk0wh";
- };
- }
-
- # TK-Glitch patches
- ( tkgPatch "0002-clear-patches" "1h1gx6rq2c961d36z1szqv9xpq1xgz2bhqjsyb03jjdrdzlcv9rm" )
- ( tkgPatch "0003-cacule-${mm}" "1rgdk1x514xsjwcjjcdmggbaj6biql5p41skn98ysqbjaw7k22ib" )
- ( tkgPatch "0003-glitched-base" "1dg177i3y54z5nadc5678hm67angram2vlr314mpxv3jgsh7vj8s" )
- ( tkgPatch "0003-glitched-cfs" "1cm4s72pymxnh37da84qrzvrwbbwagk46m1xsk99ir7cjb1l1zay" )
- # ( tkgPatch "0005-glitched-pds" "0833awp8n9ngyl5spx8znwyw1lj3nacp8vg7ffysw0j5r8akv9pw" )
- ( tkgPatch "0007-v${mm}-fsync" "0mplwdglw58bmkkxix4ccwgax3r02gahax9042dx33mybdnbl0mk" )
- ( tkgPatch "0007-v${mm}-futex2_interface" "1j29zyx2s85scfhbprgb9cs11rp50glbzczl4plphli8wds342pw" )
- ( tkgPatch "0007-v${mm}-winesync" "1av2k86ns0zc3lmgbfdch1z2a808brp2jvsfl4cwwlwwb51qzipp" )
- # ( tkgPatch "0009-prjc_v${mm}-r1" "1z731jiwyc7z4d5hzd6szrxnvw0iygbqx82y2anzm32n22731dqv" )
- ( tkgPatch "0012-misc-additions" "092ws9v1snk61i6x3gbqm5m803zd81wykkdxizn7knvy2r611cbz")
- ];
-} // (args.argsOverride or {}))
+ ignoreConfigErrors = true;
+ } // (args.argsOverride or {}));
+in kernel.overrideAttrs(old: {
+ # :sob: see https://github.com/NixOS/nixpkgs/issues/37249
+ passthru = kernel.passthru;
+ hardeningDisable = (old.hardeningDisable or []) ++ [ "strictoverflow" ];
+})
diff --git a/packages/linux-lava/si-manual-clocking.patch b/packages/linux-lava/si-manual-clocking.patch
deleted file mode 100644
index 9560b54..0000000
--- a/packages/linux-lava/si-manual-clocking.patch
+++ /dev/null
@@ -1,216 +0,0 @@
-From 5d133651479c4be74cd7eb8006fc43366c9b15b9 Mon Sep 17 00:00:00 2001
-From: LavaDesu
-Date: Wed, 3 Mar 2021 17:37:38 +0700
-Subject: [PATCH] Lava's amdgpu patches
-
----
- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 ++
- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 2 +-
- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 111 +++++++++++++++++++-
- drivers/gpu/drm/amd/pm/powerplay/si_dpm.c | 17 +++
- 4 files changed, 130 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
-index 29885febc0b0..2ed893e8983c 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
-@@ -191,6 +191,12 @@ extern int amdgpu_discovery;
- extern int amdgpu_mes;
- extern int amdgpu_noretry;
- extern int amdgpu_force_asic_type;
-+
-+extern __u32 amdgpu_force_mclk;
-+extern __u32 amdgpu_force_sclk;
-+extern __u32 amdgpu_force_vddc;
-+extern __u32 amdgpu_force_vddci;
-+
- #ifdef CONFIG_HSA_AMD
- extern int sched_policy;
- extern bool debug_evictions;
-diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
-index 47e0b48dc26f..f1e4485a60b2 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
-@@ -146,7 +146,7 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
- struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
- int r;
-
-- if (pci_p2pdma_distance_many(adev->pdev, &attach->dev, 1, true) < 0)
-+ if (pci_p2pdma_distance_many(adev->pdev, &attach->dev, 1, amdgpu_dpm == 1) < 0)
- attach->peer2peer = false;
-
- if (attach->dev->driver == adev->dev->driver)
-diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
-index 5fa65f191a37..8a90331da0e5 100644
---- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
-+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
-@@ -39,6 +39,11 @@
- #include
- #include "hwmgr.h"
-
-+__u32 amdgpu_force_mclk = 0;
-+__u32 amdgpu_force_sclk = 0;
-+__u32 amdgpu_force_vddc = 0;
-+__u32 amdgpu_force_vddci = 0;
-+
- static const struct cg_flag_name clocks[] = {
- {AMD_CG_SUPPORT_GFX_FGCG, "Graphics Fine Grain Clock Gating"},
- {AMD_CG_SUPPORT_GFX_MGCG, "Graphics Medium Grain Clock Gating"},
-@@ -2167,6 +2172,94 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev,
- return size;
- }
-
-+/**
-+ * DOC: pp_override_mclk
-+ *
-+ * It's like pp_od_clk_voltage but worse and can potentially destroy your gpu idk
-+ */
-+static ssize_t amdgpu_get_pp_override_mclk(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ DRM_INFO("[Lava] Read pp_override_mclk\n");
-+ return sprintf(buf, "%u", amdgpu_force_mclk);
-+}
-+static ssize_t amdgpu_set_pp_override_mclk(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf,
-+ size_t count)
-+{
-+ sscanf(buf, "%u", &amdgpu_force_mclk);
-+ DRM_INFO("[Lava] Write pp_override_mclk, %u\n", amdgpu_force_mclk);
-+ return count;
-+}
-+
-+/**
-+ * DOC: pp_override_sclk
-+ *
-+ * pp_override_mclk but sclk
-+ */
-+static ssize_t amdgpu_get_pp_override_sclk(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ DRM_INFO("[Lava] Read pp_override_sclk\n");
-+ return sprintf(buf, "%u", amdgpu_force_sclk);
-+}
-+static ssize_t amdgpu_set_pp_override_sclk(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf,
-+ size_t count)
-+{
-+ sscanf(buf, "%u", &amdgpu_force_sclk);
-+ DRM_INFO("[Lava] Write pp_override_sclk, %u\n", amdgpu_force_sclk);
-+ return count;
-+}
-+
-+/**
-+ * DOC: pp_override_vddc
-+ *
-+ * pp_override_mclk but vddc
-+ */
-+static ssize_t amdgpu_get_pp_override_vddc(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ DRM_INFO("[Lava] Read pp_override_vddc\n");
-+ return sprintf(buf, "%u", amdgpu_force_vddc);
-+}
-+static ssize_t amdgpu_set_pp_override_vddc(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf,
-+ size_t count)
-+{
-+ sscanf(buf, "%u", &amdgpu_force_vddc);
-+ DRM_INFO("[Lava] Write pp_override_vddc, %u\n", amdgpu_force_vddc);
-+ return count;
-+}
-+
-+/**
-+ * DOC: pp_override_vddci
-+ *
-+ * pp_override_mclk but vddci
-+ */
-+static ssize_t amdgpu_get_pp_override_vddci(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ DRM_INFO("[Lava] Read pp_override_vddci\n");
-+ return sprintf(buf, "%u", amdgpu_force_vddci);
-+}
-+static ssize_t amdgpu_set_pp_override_vddci(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf,
-+ size_t count)
-+{
-+ sscanf(buf, "%u", &amdgpu_force_vddci);
-+ DRM_INFO("[Lava] Write pp_override_vddci, %u\n", amdgpu_force_vddci);
-+ return count;
-+}
-+
- static struct amdgpu_device_attr amdgpu_device_attrs[] = {
- AMDGPU_DEVICE_ATTR_RW(power_dpm_state, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
- AMDGPU_DEVICE_ATTR_RW(power_dpm_force_performance_level, ATTR_FLAG_BASIC),
-@@ -2193,6 +2286,10 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = {
- AMDGPU_DEVICE_ATTR_RO(unique_id, ATTR_FLAG_BASIC),
- AMDGPU_DEVICE_ATTR_RW(thermal_throttling_logging, ATTR_FLAG_BASIC),
- AMDGPU_DEVICE_ATTR_RO(gpu_metrics, ATTR_FLAG_BASIC),
-+ AMDGPU_DEVICE_ATTR_RW(pp_override_mclk, ATTR_FLAG_BASIC),
-+ AMDGPU_DEVICE_ATTR_RW(pp_override_sclk, ATTR_FLAG_BASIC),
-+ AMDGPU_DEVICE_ATTR_RW(pp_override_vddc, ATTR_FLAG_BASIC),
-+ AMDGPU_DEVICE_ATTR_RW(pp_override_vddci, ATTR_FLAG_BASIC),
- };
-
- static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
-@@ -2220,11 +2317,15 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
- if (asic_type < CHIP_VEGA20)
- *states = ATTR_STATE_UNSUPPORTED;
- } else if (DEVICE_ATTR_IS(pp_od_clk_voltage)) {
-- *states = ATTR_STATE_UNSUPPORTED;
-- if ((is_support_sw_smu(adev) && adev->smu.od_enabled) ||
-- (is_support_sw_smu(adev) && adev->smu.is_apu) ||
-- (!is_support_sw_smu(adev) && hwmgr->od_enabled))
-- *states = ATTR_STATE_SUPPORTED;
-+ *states = ATTR_STATE_SUPPORTED;
-+ } else if (DEVICE_ATTR_IS(pp_override_mclk)) {
-+ *states = ATTR_STATE_SUPPORTED;
-+ } else if (DEVICE_ATTR_IS(pp_override_sclk)) {
-+ *states = ATTR_STATE_SUPPORTED;
-+ } else if (DEVICE_ATTR_IS(pp_override_vddc)) {
-+ *states = ATTR_STATE_SUPPORTED;
-+ } else if (DEVICE_ATTR_IS(pp_override_vddci)) {
-+ *states = ATTR_STATE_SUPPORTED;
- } else if (DEVICE_ATTR_IS(mem_busy_percent)) {
- if (adev->flags & AMD_IS_APU || asic_type == CHIP_VEGA10)
- *states = ATTR_STATE_UNSUPPORTED;
-diff --git a/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c b/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c
-index afa1711c9620..74b847bf83e0 100644
---- a/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c
-+++ b/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c
-@@ -3492,6 +3492,23 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
- &max_mclk_vddc);
-
- for (i = 0; i < ps->performance_level_count; i++) {
-+ if (amdgpu_force_mclk) {
-+ if (ps->performance_levels[i].mclk > amdgpu_force_mclk)
-+ ps->performance_levels[i].mclk = amdgpu_force_mclk;
-+ }
-+ if (amdgpu_force_sclk) {
-+ if (ps->performance_levels[i].sclk > amdgpu_force_sclk)
-+ ps->performance_levels[i].sclk = amdgpu_force_sclk;
-+ }
-+ if (amdgpu_force_vddc) {
-+ if (ps->performance_levels[i].vddc > amdgpu_force_vddc)
-+ ps->performance_levels[i].vddc = amdgpu_force_vddc;
-+ }
-+ if (amdgpu_force_vddci) {
-+ if (ps->performance_levels[i].vddci > amdgpu_force_vddci)
-+ ps->performance_levels[i].vddci = amdgpu_force_vddci;
-+ }
-+
- if (max_sclk_vddc) {
- if (ps->performance_levels[i].sclk > max_sclk_vddc)
- ps->performance_levels[i].sclk = max_sclk_vddc;
---
-2.31.1
-
diff --git a/packages/linux-lava/sources.nix b/packages/linux-lava/sources.nix
new file mode 100644
index 0000000..1ea7dcb
--- /dev/null
+++ b/packages/linux-lava/sources.nix
@@ -0,0 +1,45 @@
+{ fetchFromGitHub, inputs, lib }:
+let
+ version = "7.0.10";
+ kernelHash = "1w4i705i0nl1xqv7fdhdbhy7j3xrzhl31fabs6vmgiw7nf06szxv";
+ kernelPatchHash = "0h7gxqcnww7sj5cdyblzj04775zhavwdylkm2pm91v6xkjbnz1zj";
+
+ mm = lib.versions.majorMinor version;
+ hasPatch = (builtins.length (builtins.splitVersion version)) == 3;
+ tkgPatches = [
+ "0002-clear-patches"
+ "0003-glitched-base"
+ "0001-bore"
+ "0003-glitched-cfs"
+ "0012-misc-additions"
+ ];
+
+ patch = path: {
+ name = "patch-${path}";
+ patch = path;
+ };
+ kernelPatchSrc = {
+ name = "patch";
+ patch = builtins.fetchurl {
+ url = "https://cdn.kernel.org/pub/linux/kernel/v${lib.versions.major version}.x/patch-${version}.xz";
+ sha256 = kernelPatchHash;
+ };
+ };
+in {
+ inherit version;
+
+ src = builtins.fetchurl {
+ url = "https://cdn.kernel.org/pub/linux/kernel/v${lib.versions.major version}.x/linux-${mm}.tar.xz";
+ sha256 = kernelHash;
+ };
+
+ kernelPatches = lib.optionals hasPatch [
+ kernelPatchSrc
+ (patch ./bluetooth.patch)
+ ]
+ ++ builtins.map (name: {
+ inherit name;
+ patch = "${inputs.linux-tkg}/linux-tkg-patches/${mm}/${name}.patch";
+ }) tkgPatches
+ ++ [ ];
+}
diff --git a/packages/nvim-treesitter-nightly/default.nix b/packages/nvim-treesitter-nightly/default.nix
new file mode 100644
index 0000000..eb61436
--- /dev/null
+++ b/packages/nvim-treesitter-nightly/default.nix
@@ -0,0 +1,26 @@
+{
+ inputs,
+ tree-sitter,
+ vimPlugins
+}:
+let
+ nvim-treesitter-nightly = vimPlugins.nvim-treesitter.overrideAttrs(_: {
+ pname = "nvim-treesitter-nightly";
+ version = inputs.nvim-treesitter.lastModifiedDate;
+ src = inputs.nvim-treesitter;
+ });
+in nvim-treesitter-nightly.overrideAttrs(o: {
+ passthru = o.passthru // {
+ unwrapped = nvim-treesitter-nightly;
+ withPlugins = grammarFn: nvim-treesitter-nightly.overrideAttrs (_: {
+ postPatch =
+ let
+ grammars = tree-sitter.withPlugins grammarFn;
+ in
+ ''
+ rm -r parser
+ ln -s ${grammars} parser
+ '';
+ });
+ };
+})
diff --git a/packages/psensor/default.nix b/packages/psensor/default.nix
new file mode 100644
index 0000000..165cc73
--- /dev/null
+++ b/packages/psensor/default.nix
@@ -0,0 +1,53 @@
+{ stdenv
+, lib
+, fetchurl
+, pkg-config
+, lm_sensors
+, libgtop
+, libatasmart
+, gtk3
+, libnotify
+, udisks2
+, wrapGAppsHook3
+, libappindicator
+, linuxPackages
+}:
+let
+ libXNVCtrl = linuxPackages.nvidia_x11.settings.libXNVCtrl;
+in
+stdenv.mkDerivation rec {
+ pname = "psensor";
+
+ version = "1.2.1";
+
+ src = fetchurl {
+ url = "https://wpitchoune.net/psensor/files/psensor-${version}.tar.gz";
+ sha256 = "1ark901va79gfq5p8h8dqypjgm3f8crmj37520q3slwz2rfphkq8";
+ };
+
+ nativeBuildInputs = [ pkg-config wrapGAppsHook3 ];
+
+ buildInputs = [
+ lm_sensors
+ libgtop
+ libatasmart
+ gtk3
+ libnotify
+ udisks2
+ libappindicator
+ ];
+
+ preConfigure = ''
+ NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I${libXNVCtrl}/include -Wno-error"
+ NIX_LDFLAGS="$NIX_LDFLAGS -L${libXNVCtrl}/lib"
+ '';
+
+ meta = with lib; {
+ description = "Graphical hardware monitoring application for Linux";
+ homepage = "https://wpitchoune.net/psensor/";
+ license = licenses.mit;
+ platforms = platforms.linux;
+ maintainers = [ ];
+ mainProgram = "psensor";
+ };
+}
diff --git a/packages/spotify-adblock/0002-allow-setting-config-from-environment-variable.patch b/packages/spotify-adblock/0002-allow-setting-config-from-environment-variable.patch
new file mode 100644
index 0000000..e2f23bc
--- /dev/null
+++ b/packages/spotify-adblock/0002-allow-setting-config-from-environment-variable.patch
@@ -0,0 +1,24 @@
+From 9a6d08d266a5e138c08e822a6ffb761db644aead Mon Sep 17 00:00:00 2001
+From: LavaDesu
+Date: Sun, 19 Sep 2021 11:28:45 +0700
+Subject: [PATCH] allow setting config from environment variable
+
+---
+ src/lib.rs | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/lib.rs b/src/lib.rs
+index 5a0d7bd961e..86f2ac04ebf 100644
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -44,6 +45,7 @@ struct Config {
+ lazy_static! {
+ static ref CONFIG: Config = {
+ let config_paths = vec![
++ PathBuf::from(std::env::var("SPOTIFY_ADBLOCK_CONFIG").unwrap_or("".into())),
+ PathBuf::from("config.toml"),
+ #[allow(deprecated)] // std::env::home_dir() is only broken on Windows
+ std::env::home_dir().unwrap().join(".config/spotify-adblock/config.toml"),
+--
+2.32.0
+
diff --git a/packages/spotify-adblock/default.nix b/packages/spotify-adblock/default.nix
new file mode 100644
index 0000000..57992de
--- /dev/null
+++ b/packages/spotify-adblock/default.nix
@@ -0,0 +1,17 @@
+{ inputs
+, lib
+, rustPlatform
+}:
+rustPlatform.buildRustPackage {
+ pname = "spotify-adblock";
+ version = "1.0";
+ src = inputs.spotify-adblock;
+
+ cargoHash = "sha256-oGpe+kBf6kBboyx/YfbQBt1vvjtXd1n2pOH6FNcbF8M=";
+
+ patches = [ ./0002-allow-setting-config-from-environment-variable.patch ];
+
+ postInstall = ''
+ cp ${inputs.spotify-adblock}/config.toml $out/lib
+ '';
+}
diff --git a/packages/tree-sitter-jsonc/default.nix b/packages/tree-sitter-jsonc/default.nix
new file mode 100644
index 0000000..ad36b85
--- /dev/null
+++ b/packages/tree-sitter-jsonc/default.nix
@@ -0,0 +1,9 @@
+{
+ callPackage,
+ inputs
+}:
+callPackage (inputs.nixpkgs + "/pkgs/development/tools/parsing/tree-sitter/grammar.nix") {} {
+ language = "jsonc";
+ version = "1.0.0";
+ src = inputs.tree-sitter-jsonc;
+}
diff --git a/packages/wine-discord-ipc-bridge/default.nix b/packages/wine-discord-ipc-bridge/default.nix
new file mode 100644
index 0000000..5e7ff2c
--- /dev/null
+++ b/packages/wine-discord-ipc-bridge/default.nix
@@ -0,0 +1,15 @@
+{
+ inputs,
+ pkgsCross,
+ stdenv
+}:
+stdenv.mkDerivation {
+ name = "wine-discord-ipc-bridge.exe";
+ src = inputs.wine-discord-ipc-bridge;
+
+ buildInputs = [ pkgsCross.mingw32.buildPackages.gcc ];
+
+ installPhase = ''
+ cp winediscordipcbridge.exe $out
+ '';
+}
diff --git a/packages/wine-osu/default.nix b/packages/wine-osu/default.nix
deleted file mode 100644
index 955fd00..0000000
--- a/packages/wine-osu/default.nix
+++ /dev/null
@@ -1,51 +0,0 @@
-{
- getPaths,
- winePackages,
- wineUnstable,
- wineStaging,
- ...
-}:
-# TODO: Use winePackages.callPackage
-(wineStaging.overrideDerivation(o: {
- patches = (o.patches or []) ++ getPaths ./patches;
-})).override {
- wineRelease = "staging";
- wineBuild = "wineWow";
-
- pngSupport = true;
- jpegSupport = true;
- tiffSupport = true;
- gettextSupport = true;
- fontconfigSupport = true;
- alsaSupport = true;
- gtkSupport = true;
- openglSupport = true;
- tlsSupport = true;
- gstreamerSupport = true;
- #cupsSupport = true;
- colorManagementSupport = true;
- dbusSupport = true;
- mpg123Support = true;
- #openalSupport = true;
- #openclSupport = true;
- #cairoSupport = true;
- #odbcSupport = true;
- netapiSupport = true;
- cursesSupport = true;
- vaSupport = true;
- pcapSupport = true;
- #v4lSupport = true;
- #saneSupport = true;
- gsmSupport = true;
- #gphoto2Support = true;
- #ldapSupport = true;
- pulseaudioSupport = true;
- udevSupport = true;
- xineramaSupport = true;
- xmlSupport = true;
- vulkanSupport = true;
- sdlSupport = true;
- faudioSupport = true;
- vkd3dSupport = true;
- mingwSupport = true;
-}
diff --git a/packages/wine-osu/patches/0001-Revert-to-5.14-winepulse.drv.patch b/packages/wine-osu/patches/0001-Revert-to-5.14-winepulse.drv.patch
deleted file mode 100644
index db43ff8..0000000
--- a/packages/wine-osu/patches/0001-Revert-to-5.14-winepulse.drv.patch
+++ /dev/null
@@ -1,11241 +0,0 @@
-From a57533f62c21da6029504267288d2cc429b17f9a Mon Sep 17 00:00:00 2001
-From: Sebastian 'gonX' Jensen
-Date: Sun, 20 Jun 2021 17:00:22 +0200
-Subject: [PATCH 1/4] Revert to 5.14 winepulse.drv
-
----
- dlls/mmdevapi/devenum.c | 3 +-
- dlls/mmdevapi/tests/render.c | 29 +-
- dlls/winealsa.drv/mmdevdrv.c | 177 +-
- dlls/wineandroid.drv/mmdevdrv.c | 179 +-
- dlls/winecoreaudio.drv/mmdevdrv.c | 177 +-
- dlls/wineoss.drv/mmdevdrv.c | 177 +-
- dlls/winepulse.drv/Makefile.in | 9 +-
- dlls/winepulse.drv/mmdevdrv.c | 4195 ++++++++++++++++++++++++++---
- dlls/winepulse.drv/mult.c | 2015 --------------
- dlls/winepulse.drv/pulse.c | 1984 --------------
- dlls/winepulse.drv/unixlib.h | 211 --
- include/audioclient.idl | 8 -
- 12 files changed, 4031 insertions(+), 5133 deletions(-)
- delete mode 100644 dlls/winepulse.drv/mult.c
- delete mode 100644 dlls/winepulse.drv/pulse.c
- delete mode 100644 dlls/winepulse.drv/unixlib.h
-
-diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c
-index b17572425f32b603ddec1cc592350b8440bde706..89ca13102804746d0caed9b4b72ee61ac84c8ad9 100644
---- a/dlls/mmdevapi/devenum.c
-+++ b/dlls/mmdevapi/devenum.c
-@@ -554,8 +554,7 @@ static HRESULT WINAPI MMDevice_Activate(IMMDevice *iface, REFIID riid, DWORD cls
- return E_POINTER;
-
- if (IsEqualIID(riid, &IID_IAudioClient) ||
-- IsEqualIID(riid, &IID_IAudioClient2) ||
-- IsEqualIID(riid, &IID_IAudioClient3)){
-+ IsEqualIID(riid, &IID_IAudioClient2)){
- hr = drvs.pGetAudioEndpoint(&This->devguid, iface, (IAudioClient**)ppv);
- }else if (IsEqualIID(riid, &IID_IAudioEndpointVolume) ||
- IsEqualIID(riid, &IID_IAudioEndpointVolumeEx))
-diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c
-index 495c1c6f496f73e7e9b2ba31735b66fd03690a22..2ae777b5ac585c02bf1a95073a9508831b887bda 100644
---- a/dlls/mmdevapi/tests/render.c
-+++ b/dlls/mmdevapi/tests/render.c
-@@ -134,7 +134,6 @@ static void test_audioclient(void)
- {
- IAudioClient *ac;
- IAudioClient2 *ac2;
-- IAudioClient3 *ac3;
- IUnknown *unk;
- HRESULT hr;
- ULONG ref;
-@@ -144,14 +143,6 @@ static void test_audioclient(void)
- BOOL offload_capable;
- AudioClientProperties client_props;
-
-- hr = IMMDevice_Activate(dev, &IID_IAudioClient3, CLSCTX_INPROC_SERVER,
-- NULL, (void**)&ac3);
-- ok(hr == S_OK ||
-- broken(hr == E_NOINTERFACE) /* win8 */,
-- "IAudioClient3 Activation failed with %08x\n", hr);
-- if(hr == S_OK)
-- IAudioClient3_Release(ac3);
--
- hr = IMMDevice_Activate(dev, &IID_IAudioClient2, CLSCTX_INPROC_SERVER,
- NULL, (void**)&ac2);
- ok(hr == S_OK ||
-@@ -276,7 +267,6 @@ static void test_audioclient(void)
- hr = IAudioClient2_SetClientProperties(ac2, NULL);
- ok(hr == E_POINTER, "SetClientProperties with NULL props gave wrong error: %08x\n", hr);
-
-- /* invalid cbSize */
- client_props.cbSize = 0;
- client_props.bIsOffload = FALSE;
- client_props.eCategory = AudioCategory_BackgroundCapableMedia;
-@@ -285,8 +275,7 @@ static void test_audioclient(void)
- hr = IAudioClient2_SetClientProperties(ac2, &client_props);
- ok(hr == E_INVALIDARG, "SetClientProperties with invalid cbSize gave wrong error: %08x\n", hr);
-
-- /* offload consistency */
-- client_props.cbSize = sizeof(client_props) - sizeof(client_props.Options);
-+ client_props.cbSize = sizeof(client_props);
- client_props.bIsOffload = TRUE;
-
- hr = IAudioClient2_SetClientProperties(ac2, &client_props);
-@@ -295,31 +284,15 @@ static void test_audioclient(void)
- else
- ok(hr == S_OK, "SetClientProperties(offload) failed: %08x\n", hr);
-
-- /* disable offload */
- client_props.bIsOffload = FALSE;
- hr = IAudioClient2_SetClientProperties(ac2, &client_props);
- ok(hr == S_OK, "SetClientProperties failed: %08x\n", hr);
-
-- /* Options field added in Win 8.1 */
-- client_props.cbSize = sizeof(client_props);
-- hr = IAudioClient2_SetClientProperties(ac2, &client_props);
-- ok(hr == S_OK ||
-- broken(hr == E_INVALIDARG) /* <= win8 */,
-- "SetClientProperties failed: %08x\n", hr);
--
- IAudioClient2_Release(ac2);
- }
- else
- win_skip("IAudioClient2 is not present on Win <= 7\n");
-
-- hr = IAudioClient_QueryInterface(ac, &IID_IAudioClient3, (void**)&ac3);
-- ok(hr == S_OK ||
-- broken(hr == E_NOINTERFACE) /* win8 */,
-- "Failed to query IAudioClient3 interface: %08x\n", hr);
--
-- if(hr == S_OK)
-- IAudioClient3_Release(ac3);
--
- test_uninitialized(ac);
-
- hr = IAudioClient_Initialize(ac, 3, 0, 5000000, 0, pwfx, NULL);
-diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
-index 5f7d277ce9a354194123dbf3b01ef04f1c31db2d..636a04058056b4a83fd4657a0914c795c244463d 100644
---- a/dlls/winealsa.drv/mmdevdrv.c
-+++ b/dlls/winealsa.drv/mmdevdrv.c
-@@ -90,7 +90,7 @@ typedef struct _AudioSessionWrapper {
- } AudioSessionWrapper;
-
- struct ACImpl {
-- IAudioClient3 IAudioClient3_iface;
-+ IAudioClient2 IAudioClient2_iface;
- IAudioRenderClient IAudioRenderClient_iface;
- IAudioCaptureClient IAudioCaptureClient_iface;
- IAudioClock IAudioClock_iface;
-@@ -174,7 +174,7 @@ static const WCHAR drv_key_devicesW[] = {'S','o','f','t','w','a','r','e','\\',
- 'w','i','n','e','a','l','s','a','.','d','r','v','\\','d','e','v','i','c','e','s',0};
- static const WCHAR guidW[] = {'g','u','i','d',0};
-
--static const IAudioClient3Vtbl AudioClient3_Vtbl;
-+static const IAudioClient2Vtbl AudioClient2_Vtbl;
- static const IAudioRenderClientVtbl AudioRenderClient_Vtbl;
- static const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl;
- static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl;
-@@ -187,9 +187,9 @@ static const IAudioSessionManager2Vtbl AudioSessionManager2_Vtbl;
-
- static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client);
-
--static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface)
-+static inline ACImpl *impl_from_IAudioClient2(IAudioClient2 *iface)
- {
-- return CONTAINING_RECORD(iface, ACImpl, IAudioClient3_iface);
-+ return CONTAINING_RECORD(iface, ACImpl, IAudioClient2_iface);
- }
-
- static inline ACImpl *impl_from_IAudioRenderClient(IAudioRenderClient *iface)
-@@ -831,7 +831,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
- if(!This)
- return E_OUTOFMEMORY;
-
-- This->IAudioClient3_iface.lpVtbl = &AudioClient3_Vtbl;
-+ This->IAudioClient2_iface.lpVtbl = &AudioClient2_Vtbl;
- This->IAudioRenderClient_iface.lpVtbl = &AudioRenderClient_Vtbl;
- This->IAudioCaptureClient_iface.lpVtbl = &AudioCaptureClient_Vtbl;
- This->IAudioClock_iface.lpVtbl = &AudioClock_Vtbl;
-@@ -847,7 +847,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
- return E_UNEXPECTED;
- }
-
-- hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient3_iface, &This->pUnkFTMarshal);
-+ hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient2_iface, &This->pUnkFTMarshal);
- if (FAILED(hr)) {
- HeapFree(GetProcessHeap(), 0, This);
- return hr;
-@@ -894,16 +894,16 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
- This->parent = dev;
- IMMDevice_AddRef(This->parent);
-
-- *out = (IAudioClient *)&This->IAudioClient3_iface;
-- IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ *out = (IAudioClient *)&This->IAudioClient2_iface;
-+ IAudioClient2_AddRef(&This->IAudioClient2_iface);
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient2 *iface,
- REFIID riid, void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
-
- if(!ppv)
-@@ -911,8 +911,7 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- *ppv = NULL;
- if(IsEqualIID(riid, &IID_IUnknown) ||
- IsEqualIID(riid, &IID_IAudioClient) ||
-- IsEqualIID(riid, &IID_IAudioClient2) ||
-- IsEqualIID(riid, &IID_IAudioClient3))
-+ IsEqualIID(riid, &IID_IAudioClient2))
- *ppv = iface;
- else if(IsEqualIID(riid, &IID_IMarshal))
- return IUnknown_QueryInterface(This->pUnkFTMarshal, riid, ppv);
-@@ -925,18 +924,18 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- return E_NOINTERFACE;
- }
-
--static ULONG WINAPI AudioClient_AddRef(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_AddRef(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
- ref = InterlockedIncrement(&This->ref);
- TRACE("(%p) Refcount now %u\n", This, ref);
- return ref;
- }
-
--static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_Release(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
-
- ref = InterlockedDecrement(&This->ref);
-@@ -953,7 +952,7 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
- CloseHandle(event);
- }
-
-- IAudioClient3_Stop(iface);
-+ IAudioClient2_Stop(iface);
- IMMDevice_Release(This->parent);
- IUnknown_Release(This->pUnkFTMarshal);
- This->lock.DebugInfo->Spare[0] = 0;
-@@ -1282,12 +1281,12 @@ static void silence_buffer(ACImpl *This, BYTE *buffer, UINT32 frames)
- memset(buffer, 0, frames * This->fmt->nBlockAlign);
- }
-
--static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_Initialize(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration,
- REFERENCE_TIME period, const WAVEFORMATEX *fmt,
- const GUID *sessionguid)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- snd_pcm_sw_params_t *sw_params = NULL;
- snd_pcm_format_t format;
- unsigned int rate, alsa_period_us;
-@@ -1574,10 +1573,10 @@ exit:
- return hr;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient2 *iface,
- UINT32 *out)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, out);
-
-@@ -1598,10 +1597,10 @@ static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient2 *iface,
- REFERENCE_TIME *latency)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, latency);
-
-@@ -1631,10 +1630,10 @@ static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient2 *iface,
- UINT32 *out)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, out);
-
-@@ -1658,11 +1657,11 @@ static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, const WAVEFORMATEX *fmt,
- WAVEFORMATEX **out)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- snd_pcm_format_mask_t *formats = NULL;
- snd_pcm_format_t format;
- HRESULT hr = S_OK;
-@@ -1809,10 +1808,10 @@ exit:
- return hr;
- }
-
--static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient2 *iface,
- WAVEFORMATEX **pwfx)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- WAVEFORMATEXTENSIBLE *fmt;
- snd_pcm_format_mask_t *formats;
- unsigned int max_rate, max_channels;
-@@ -1940,10 +1939,10 @@ exit:
- return hr;
- }
-
--static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient2 *iface,
- REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p, %p)\n", This, defperiod, minperiod);
-
-@@ -2438,9 +2437,9 @@ static int alsa_rewind_best_effort(ACImpl *This)
- return len;
- }
-
--static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Start(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)\n", This);
-
-@@ -2506,9 +2505,9 @@ static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Stop(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)\n", This);
-
-@@ -2534,9 +2533,9 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Reset(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)\n", This);
-
-@@ -2581,10 +2580,10 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient2 *iface,
- HANDLE event)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, event);
-
-@@ -2616,10 +2615,10 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
-+static HRESULT WINAPI AudioClient_GetService(IAudioClient2 *iface, REFIID riid,
- void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
-
-@@ -2700,10 +2699,10 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
- return E_NOINTERFACE;
- }
-
--static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient2 *iface,
- AUDIO_STREAM_CATEGORY category, BOOL *offload_capable)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(0x%x, %p)\n", This, category, offload_capable);
-
-@@ -2715,83 +2714,42 @@ static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient2 *iface,
- const AudioClientProperties *prop)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, prop);
-
-- if(!legacy_prop)
-+ if(!prop)
- return E_POINTER;
-
-- if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory,
-- prop->Options);
-- }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory);
-- }else{
-- WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
-+ if(prop->cbSize != sizeof(*prop))
- return E_INVALIDARG;
-- }
-
-+ TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-+ prop->bIsOffload,
-+ prop->eCategory,
-+ prop->Options);
-
-- if(legacy_prop->bIsOffload)
-+ if(prop->bIsOffload)
- return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient2 *iface,
- const WAVEFORMATEX *format, BOOL event_driven, REFERENCE_TIME *min_duration,
- REFERENCE_TIME *max_duration)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- FIXME("(%p)->(%p, %u, %p, %p)\n", This, format, event_driven, min_duration, max_duration);
-
- return E_NOTIMPL;
- }
-
--static HRESULT WINAPI AudioClient_GetSharedModeEnginePeriod(IAudioClient3 *iface,
-- const WAVEFORMATEX *format, UINT32 *default_period_frames, UINT32 *unit_period_frames,
-- UINT32 *min_period_frames, UINT32 *max_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p, %p, %p, %p)\n", This, format, default_period_frames, unit_period_frames,
-- min_period_frames, max_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface,
-- WAVEFORMATEX **cur_format, UINT32 *cur_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p)\n", This, cur_format, cur_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_InitializeSharedAudioStream(IAudioClient3 *iface,
-- DWORD flags, UINT32 period_frames, const WAVEFORMATEX *format,
-- const GUID *session_guid)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(0x%x, %u, %p, %s)\n", This, flags, period_frames, format, debugstr_guid(session_guid));
--
-- return E_NOTIMPL;
--}
--
--static const IAudioClient3Vtbl AudioClient3_Vtbl =
-+static const IAudioClient2Vtbl AudioClient2_Vtbl =
- {
- AudioClient_QueryInterface,
- AudioClient_AddRef,
-@@ -2811,9 +2769,6 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl =
- AudioClient_IsOffloadCapable,
- AudioClient_SetClientProperties,
- AudioClient_GetBufferSizeLimits,
-- AudioClient_GetSharedModeEnginePeriod,
-- AudioClient_GetCurrentSharedModeEnginePeriod,
-- AudioClient_InitializeSharedAudioStream,
- };
-
- static HRESULT WINAPI AudioRenderClient_QueryInterface(
-@@ -2844,13 +2799,13 @@ static HRESULT WINAPI AudioRenderClient_QueryInterface(
- static ULONG WINAPI AudioRenderClient_AddRef(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_AddRef(&This->IAudioClient3_iface);
-+ return AudioClient_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioRenderClient_Release(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_Release(&This->IAudioClient3_iface);
-+ return AudioClient_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
-@@ -3010,13 +2965,13 @@ static HRESULT WINAPI AudioCaptureClient_QueryInterface(
- static ULONG WINAPI AudioCaptureClient_AddRef(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioCaptureClient_Release(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
-@@ -3185,13 +3140,13 @@ static HRESULT WINAPI AudioClock_QueryInterface(IAudioClock *iface,
- static ULONG WINAPI AudioClock_AddRef(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock_Release(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock_GetFrequency(IAudioClock *iface, UINT64 *freq)
-@@ -3303,13 +3258,13 @@ static HRESULT WINAPI AudioClock2_QueryInterface(IAudioClock2 *iface,
- static ULONG WINAPI AudioClock2_AddRef(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock2_Release(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock2_GetDevicePosition(IAudioClock2 *iface,
-@@ -3348,7 +3303,7 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client)
- ret->client = client;
- if(client){
- ret->session = client->session;
-- AudioClient_AddRef(&client->IAudioClient3_iface);
-+ AudioClient_AddRef(&client->IAudioClient2_iface);
- }
-
- return ret;
-@@ -3396,7 +3351,7 @@ static ULONG WINAPI AudioSessionControl_Release(IAudioSessionControl2 *iface)
- EnterCriticalSection(&This->client->lock);
- This->client->session_wrapper = NULL;
- LeaveCriticalSection(&This->client->lock);
-- AudioClient_Release(&This->client->IAudioClient3_iface);
-+ AudioClient_Release(&This->client->IAudioClient2_iface);
- }
- HeapFree(GetProcessHeap(), 0, This);
- }
-@@ -3738,13 +3693,13 @@ static HRESULT WINAPI AudioStreamVolume_QueryInterface(
- static ULONG WINAPI AudioStreamVolume_AddRef(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioStreamVolume_Release(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioStreamVolume_GetChannelCount(
-diff --git a/dlls/wineandroid.drv/mmdevdrv.c b/dlls/wineandroid.drv/mmdevdrv.c
-index d9b7cde2c80af90cf44cfe33945a2a43fa41dd4b..aa32c49185501a58941c6065482928654541b6a2 100644
---- a/dlls/wineandroid.drv/mmdevdrv.c
-+++ b/dlls/wineandroid.drv/mmdevdrv.c
-@@ -107,7 +107,7 @@ typedef struct _AudioSessionWrapper {
- } AudioSessionWrapper;
-
- struct ACImpl {
-- IAudioClient3 IAudioClient3_iface;
-+ IAudioClient2 IAudioClient2_iface;
- IAudioRenderClient IAudioRenderClient_iface;
- IAudioCaptureClient IAudioCaptureClient_iface;
- IAudioClock IAudioClock_iface;
-@@ -174,7 +174,7 @@ static struct list g_sessions = LIST_INIT(g_sessions);
-
- static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client);
-
--static const IAudioClient3Vtbl AudioClient3_Vtbl;
-+static const IAudioClient2Vtbl AudioClient2_Vtbl;
- static const IAudioRenderClientVtbl AudioRenderClient_Vtbl;
- static const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl;
- static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl;
-@@ -185,9 +185,9 @@ static const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl;
- static const IChannelAudioVolumeVtbl ChannelAudioVolume_Vtbl;
- static const IAudioSessionManager2Vtbl AudioSessionManager2_Vtbl;
-
--static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface)
-+static inline ACImpl *impl_from_IAudioClient2(IAudioClient2 *iface)
- {
-- return CONTAINING_RECORD(iface, ACImpl, IAudioClient3_iface);
-+ return CONTAINING_RECORD(iface, ACImpl, IAudioClient2_iface);
- }
-
- static inline ACImpl *impl_from_IAudioRenderClient(IAudioRenderClient *iface)
-@@ -377,7 +377,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev,
- if(!This)
- return E_OUTOFMEMORY;
-
-- hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient3_iface, &This->pUnkFTMarshal);
-+ hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient2_iface, &This->pUnkFTMarshal);
- if (FAILED(hr)) {
- HeapFree(GetProcessHeap(), 0, This);
- return hr;
-@@ -385,7 +385,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev,
-
- This->dataflow = flow;
-
-- This->IAudioClient3_iface.lpVtbl = &AudioClient3_Vtbl;
-+ This->IAudioClient2_iface.lpVtbl = &AudioClient2_Vtbl;
- This->IAudioRenderClient_iface.lpVtbl = &AudioRenderClient_Vtbl;
- This->IAudioCaptureClient_iface.lpVtbl = &AudioCaptureClient_Vtbl;
- This->IAudioClock_iface.lpVtbl = &AudioClock_Vtbl;
-@@ -398,16 +398,16 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev,
- This->parent = dev;
- IMMDevice_AddRef(This->parent);
-
-- *out = (IAudioClient *)&This->IAudioClient3_iface;
-- IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ *out = (IAudioClient *)&This->IAudioClient2_iface;
-+ IAudioClient2_AddRef(&This->IAudioClient2_iface);
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient2 *iface,
- REFIID riid, void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
-
- if(!ppv)
-@@ -415,8 +415,7 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- *ppv = NULL;
- if(IsEqualIID(riid, &IID_IUnknown) ||
- IsEqualIID(riid, &IID_IAudioClient) ||
-- IsEqualIID(riid, &IID_IAudioClient2) ||
-- IsEqualIID(riid, &IID_IAudioClient3))
-+ IsEqualIID(riid, &IID_IAudioClient2))
- *ppv = iface;
- else if(IsEqualIID(riid, &IID_IMarshal))
- return IUnknown_QueryInterface(This->pUnkFTMarshal, riid, ppv);
-@@ -428,18 +427,18 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- return E_NOINTERFACE;
- }
-
--static ULONG WINAPI AudioClient_AddRef(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_AddRef(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
- ref = InterlockedIncrement(&This->ref);
- TRACE("(%p) Refcount now %u\n", This, ref);
- return ref;
- }
-
--static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_Release(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
-
- ref = InterlockedDecrement(&This->ref);
-@@ -456,7 +455,7 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
- CloseHandle(event);
- }
-
-- IAudioClient3_Stop(iface);
-+ IAudioClient2_Stop(iface);
-
- IMMDevice_Release(This->parent);
- IUnknown_Release(This->pUnkFTMarshal);
-@@ -786,12 +785,12 @@ static HRESULT try_open_capture_device(SLAndroidDataFormat_PCM_EX *pcm, unsigned
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_Initialize(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration,
- REFERENCE_TIME period, const WAVEFORMATEX *fmt,
- const GUID *sessionguid)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- int i, num_buffers;
- HRESULT hr;
- SLresult sr;
-@@ -1021,10 +1020,10 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient2 *iface,
- UINT32 *frames)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, frames);
-
-@@ -1047,10 +1046,10 @@ static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient2 *iface,
- REFERENCE_TIME *latency)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, latency);
-
-@@ -1073,10 +1072,10 @@ static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient2 *iface,
- UINT32 *numpad)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, numpad);
-
-@@ -1099,11 +1098,11 @@ static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, const WAVEFORMATEX *pwfx,
- WAVEFORMATEX **outpwfx)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- SLAndroidDataFormat_PCM_EX pcm;
- HRESULT hr;
-
-@@ -1135,7 +1134,7 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
-
- if(FAILED(hr)){
- if(outpwfx){
-- hr = IAudioClient3_GetMixFormat(iface, outpwfx);
-+ hr = IAudioClient2_GetMixFormat(iface, outpwfx);
- if(FAILED(hr))
- return hr;
- return S_FALSE;
-@@ -1149,10 +1148,10 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
- return hr;
- }
-
--static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient2 *iface,
- WAVEFORMATEX **pwfx)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- WAVEFORMATEXTENSIBLE *fmt;
-
- TRACE("(%p)->(%p)\n", This, pwfx);
-@@ -1187,10 +1186,10 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient2 *iface,
- REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p, %p)\n", This, defperiod, minperiod);
-
-@@ -1344,9 +1343,9 @@ static void CALLBACK sl_period_callback(void *user, BOOLEAN timer)
- SetEvent(This->event);
- }
-
--static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Start(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- SLresult sr;
-
- TRACE("(%p)\n", This);
-@@ -1398,9 +1397,9 @@ static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Stop(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- SLresult sr;
-
- TRACE("(%p)\n", This);
-@@ -1440,9 +1439,9 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Reset(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- SLresult sr;
-
- TRACE("(%p)\n", This);
-@@ -1497,10 +1496,10 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient2 *iface,
- HANDLE event)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, event);
-
-@@ -1532,10 +1531,10 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
-+static HRESULT WINAPI AudioClient_GetService(IAudioClient2 *iface, REFIID riid,
- void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
-
-@@ -1616,10 +1615,10 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
- return E_NOINTERFACE;
- }
-
--static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient2 *iface,
- AUDIO_STREAM_CATEGORY category, BOOL *offload_capable)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(0x%x, %p)\n", This, category, offload_capable);
-
-@@ -1631,83 +1630,42 @@ static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient2 *iface,
- const AudioClientProperties *prop)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, prop);
-
-- if(!legacy_prop)
-+ if(!prop)
- return E_POINTER;
-
-- if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory,
-- prop->Options);
-- }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory);
-- }else{
-- WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
-+ if(prop->cbSize != sizeof(*prop))
- return E_INVALIDARG;
-- }
-
-+ TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-+ prop->bIsOffload,
-+ prop->eCategory,
-+ prop->Options);
-
-- if(legacy_prop->bIsOffload)
-+ if(prop->bIsOffload)
- return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient2 *iface,
- const WAVEFORMATEX *format, BOOL event_driven, REFERENCE_TIME *min_duration,
- REFERENCE_TIME *max_duration)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- FIXME("(%p)->(%p, %u, %p, %p)\n", This, format, event_driven, min_duration, max_duration);
-
- return E_NOTIMPL;
- }
-
--static HRESULT WINAPI AudioClient_GetSharedModeEnginePeriod(IAudioClient3 *iface,
-- const WAVEFORMATEX *format, UINT32 *default_period_frames, UINT32 *unit_period_frames,
-- UINT32 *min_period_frames, UINT32 *max_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p, %p, %p, %p)\n", This, format, default_period_frames, unit_period_frames,
-- min_period_frames, max_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface,
-- WAVEFORMATEX **cur_format, UINT32 *cur_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p)\n", This, cur_format, cur_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_InitializeSharedAudioStream(IAudioClient3 *iface,
-- DWORD flags, UINT32 period_frames, const WAVEFORMATEX *format,
-- const GUID *session_guid)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(0x%x, %u, %p, %s)\n", This, flags, period_frames, format, debugstr_guid(session_guid));
--
-- return E_NOTIMPL;
--}
--
--static const IAudioClient3Vtbl AudioClient3_Vtbl =
-+static const IAudioClient2Vtbl AudioClient2_Vtbl =
- {
- AudioClient_QueryInterface,
- AudioClient_AddRef,
-@@ -1727,9 +1685,6 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl =
- AudioClient_IsOffloadCapable,
- AudioClient_SetClientProperties,
- AudioClient_GetBufferSizeLimits,
-- AudioClient_GetSharedModeEnginePeriod,
-- AudioClient_GetCurrentSharedModeEnginePeriod,
-- AudioClient_InitializeSharedAudioStream,
- };
-
- static HRESULT WINAPI AudioRenderClient_QueryInterface(
-@@ -1759,13 +1714,13 @@ static HRESULT WINAPI AudioRenderClient_QueryInterface(
- static ULONG WINAPI AudioRenderClient_AddRef(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_AddRef(&This->IAudioClient3_iface);
-+ return AudioClient_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioRenderClient_Release(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_Release(&This->IAudioClient3_iface);
-+ return AudioClient_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
-@@ -1926,13 +1881,13 @@ static HRESULT WINAPI AudioCaptureClient_QueryInterface(
- static ULONG WINAPI AudioCaptureClient_AddRef(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioCaptureClient_Release(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
-@@ -2104,13 +2059,13 @@ static HRESULT WINAPI AudioClock_QueryInterface(IAudioClock *iface,
- static ULONG WINAPI AudioClock_AddRef(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock_Release(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock_GetFrequency(IAudioClock *iface, UINT64 *freq)
-@@ -2200,13 +2155,13 @@ static HRESULT WINAPI AudioClock2_QueryInterface(IAudioClock2 *iface,
- static ULONG WINAPI AudioClock2_AddRef(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock2_Release(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock2_GetDevicePosition(IAudioClock2 *iface,
-@@ -2245,7 +2200,7 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client)
- ret->client = client;
- if(client){
- ret->session = client->session;
-- AudioClient_AddRef(&client->IAudioClient3_iface);
-+ AudioClient_AddRef(&client->IAudioClient2_iface);
- }
-
- return ret;
-@@ -2293,7 +2248,7 @@ static ULONG WINAPI AudioSessionControl_Release(IAudioSessionControl2 *iface)
- EnterCriticalSection(&This->client->lock);
- This->client->session_wrapper = NULL;
- LeaveCriticalSection(&This->client->lock);
-- AudioClient_Release(&This->client->IAudioClient3_iface);
-+ AudioClient_Release(&This->client->IAudioClient2_iface);
- }
- HeapFree(GetProcessHeap(), 0, This);
- }
-@@ -2636,13 +2591,13 @@ static HRESULT WINAPI AudioStreamVolume_QueryInterface(
- static ULONG WINAPI AudioStreamVolume_AddRef(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioStreamVolume_Release(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioStreamVolume_GetChannelCount(
-diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
-index f07f4bae5fb211dabd23ddfc12c889aafb701ab9..03f8a0c030e8fe4ea3a33d8ecfffe428cb181843 100644
---- a/dlls/winecoreaudio.drv/mmdevdrv.c
-+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
-@@ -108,7 +108,7 @@ typedef struct _AudioSessionWrapper {
- } AudioSessionWrapper;
-
- struct ACImpl {
-- IAudioClient3 IAudioClient3_iface;
-+ IAudioClient2 IAudioClient2_iface;
- IAudioRenderClient IAudioRenderClient_iface;
- IAudioCaptureClient IAudioCaptureClient_iface;
- IAudioClock IAudioClock_iface;
-@@ -151,7 +151,7 @@ struct ACImpl {
- OSSpinLock lock;
- };
-
--static const IAudioClient3Vtbl AudioClient3_Vtbl;
-+static const IAudioClient2Vtbl AudioClient2_Vtbl;
- static const IAudioRenderClientVtbl AudioRenderClient_Vtbl;
- static const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl;
- static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl;
-@@ -190,9 +190,9 @@ static struct list g_sessions = LIST_INIT(g_sessions);
- static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client);
- static HRESULT ca_setvol(ACImpl *This, UINT32 index);
-
--static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface)
-+static inline ACImpl *impl_from_IAudioClient2(IAudioClient2 *iface)
- {
-- return CONTAINING_RECORD(iface, ACImpl, IAudioClient3_iface);
-+ return CONTAINING_RECORD(iface, ACImpl, IAudioClient2_iface);
- }
-
- static inline ACImpl *impl_from_IAudioRenderClient(IAudioRenderClient *iface)
-@@ -652,7 +652,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
- if(!This)
- return E_OUTOFMEMORY;
-
-- This->IAudioClient3_iface.lpVtbl = &AudioClient3_Vtbl;
-+ This->IAudioClient2_iface.lpVtbl = &AudioClient2_Vtbl;
- This->IAudioRenderClient_iface.lpVtbl = &AudioRenderClient_Vtbl;
- This->IAudioCaptureClient_iface.lpVtbl = &AudioCaptureClient_Vtbl;
- This->IAudioClock_iface.lpVtbl = &AudioClock_Vtbl;
-@@ -672,7 +672,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
-
- This->lock = 0;
-
-- hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient3_iface, &This->pUnkFTMarshal);
-+ hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient2_iface, &This->pUnkFTMarshal);
- if (FAILED(hr)) {
- HeapFree(GetProcessHeap(), 0, This);
- return hr;
-@@ -688,16 +688,16 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
- return AUDCLNT_E_DEVICE_INVALIDATED;
- }
-
-- *out = (IAudioClient *)&This->IAudioClient3_iface;
-- IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ *out = (IAudioClient *)&This->IAudioClient2_iface;
-+ IAudioClient2_AddRef(&This->IAudioClient2_iface);
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient2 *iface,
- REFIID riid, void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
-
- if(!ppv)
-@@ -705,8 +705,7 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- *ppv = NULL;
- if(IsEqualIID(riid, &IID_IUnknown) ||
- IsEqualIID(riid, &IID_IAudioClient) ||
-- IsEqualIID(riid, &IID_IAudioClient2) ||
-- IsEqualIID(riid, &IID_IAudioClient3))
-+ IsEqualIID(riid, &IID_IAudioClient2))
- *ppv = iface;
- else if(IsEqualIID(riid, &IID_IMarshal))
- return IUnknown_QueryInterface(This->pUnkFTMarshal, riid, ppv);
-@@ -719,18 +718,18 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- return E_NOINTERFACE;
- }
-
--static ULONG WINAPI AudioClient_AddRef(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_AddRef(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
- ref = InterlockedIncrement(&This->ref);
- TRACE("(%p) Refcount now %u\n", This, ref);
- return ref;
- }
-
--static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_Release(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
- ref = InterlockedDecrement(&This->ref);
- TRACE("(%p) Refcount now %u\n", This, ref);
-@@ -1276,12 +1275,12 @@ static HRESULT ca_setup_audiounit(EDataFlow dataflow, AudioComponentInstance uni
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_Initialize(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration,
- REFERENCE_TIME period, const WAVEFORMATEX *fmt,
- const GUID *sessionguid)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- HRESULT hr;
- OSStatus sc;
- int i;
-@@ -1480,10 +1479,10 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient2 *iface,
- UINT32 *frames)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, frames);
-
-@@ -1558,10 +1557,10 @@ static HRESULT ca_get_max_stream_latency(ACImpl *This, UInt32 *max)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient2 *iface,
- REFERENCE_TIME *out)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- UInt32 latency, stream_latency, size;
- AudioObjectPropertyAddress addr;
- OSStatus sc;
-@@ -1623,10 +1622,10 @@ static HRESULT AudioClient_GetCurrentPadding_nolock(ACImpl *This,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient2 *iface,
- UINT32 *numpad)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- HRESULT hr;
-
- TRACE("(%p)->(%p)\n", This, numpad);
-@@ -1643,11 +1642,11 @@ static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
- return hr;
- }
-
--static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, const WAVEFORMATEX *pwfx,
- WAVEFORMATEX **outpwfx)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- AudioStreamBasicDescription dev_desc;
- AudioConverterRef converter;
- AudioComponentInstance unit;
-@@ -1710,7 +1709,7 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
-
- unsupported:
- if(outpwfx){
-- hr = IAudioClient3_GetMixFormat(&This->IAudioClient3_iface, outpwfx);
-+ hr = IAudioClient2_GetMixFormat(&This->IAudioClient2_iface, outpwfx);
- if(FAILED(hr))
- return hr;
- return S_FALSE;
-@@ -1835,10 +1834,10 @@ static void convert_channel_layout(const AudioChannelLayout *ca_layout, WAVEFORM
- fmt->dwChannelMask = ca_mask;
- }
-
--static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient2 *iface,
- WAVEFORMATEX **pwfx)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- WAVEFORMATEXTENSIBLE *fmt;
- OSStatus sc;
- UInt32 size;
-@@ -1954,10 +1953,10 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient2 *iface,
- REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p, %p)\n", This, defperiod, minperiod);
-
-@@ -1980,9 +1979,9 @@ void CALLBACK ca_period_cb(void *user, BOOLEAN timer)
- SetEvent(This->event);
- }
-
--static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Start(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)\n", This);
-
-@@ -2019,9 +2018,9 @@ static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Stop(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)\n", This);
-
-@@ -2044,9 +2043,9 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Reset(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)\n", This);
-
-@@ -2084,10 +2083,10 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient2 *iface,
- HANDLE event)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, event);
-
-@@ -2119,10 +2118,10 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
-+static HRESULT WINAPI AudioClient_GetService(IAudioClient2 *iface, REFIID riid,
- void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
-
-@@ -2203,10 +2202,10 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
- return E_NOINTERFACE;
- }
-
--static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient2 *iface,
- AUDIO_STREAM_CATEGORY category, BOOL *offload_capable)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(0x%x, %p)\n", This, category, offload_capable);
-
-@@ -2218,83 +2217,42 @@ static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient2 *iface,
- const AudioClientProperties *prop)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, prop);
-
-- if(!legacy_prop)
-+ if(!prop)
- return E_POINTER;
-
-- if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory,
-- prop->Options);
-- }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory);
-- }else{
-- WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
-+ if(prop->cbSize != sizeof(*prop))
- return E_INVALIDARG;
-- }
-
-+ TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-+ prop->bIsOffload,
-+ prop->eCategory,
-+ prop->Options);
-
-- if(legacy_prop->bIsOffload)
-+ if(prop->bIsOffload)
- return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient2 *iface,
- const WAVEFORMATEX *format, BOOL event_driven, REFERENCE_TIME *min_duration,
- REFERENCE_TIME *max_duration)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- FIXME("(%p)->(%p, %u, %p, %p)\n", This, format, event_driven, min_duration, max_duration);
-
- return E_NOTIMPL;
- }
-
--static HRESULT WINAPI AudioClient_GetSharedModeEnginePeriod(IAudioClient3 *iface,
-- const WAVEFORMATEX *format, UINT32 *default_period_frames, UINT32 *unit_period_frames,
-- UINT32 *min_period_frames, UINT32 *max_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p, %p, %p, %p)\n", This, format, default_period_frames, unit_period_frames,
-- min_period_frames, max_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface,
-- WAVEFORMATEX **cur_format, UINT32 *cur_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p)\n", This, cur_format, cur_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_InitializeSharedAudioStream(IAudioClient3 *iface,
-- DWORD flags, UINT32 period_frames, const WAVEFORMATEX *format,
-- const GUID *session_guid)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(0x%x, %u, %p, %s)\n", This, flags, period_frames, format, debugstr_guid(session_guid));
--
-- return E_NOTIMPL;
--}
--
--static const IAudioClient3Vtbl AudioClient3_Vtbl =
-+static const IAudioClient2Vtbl AudioClient2_Vtbl =
- {
- AudioClient_QueryInterface,
- AudioClient_AddRef,
-@@ -2314,9 +2272,6 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl =
- AudioClient_IsOffloadCapable,
- AudioClient_SetClientProperties,
- AudioClient_GetBufferSizeLimits,
-- AudioClient_GetSharedModeEnginePeriod,
-- AudioClient_GetCurrentSharedModeEnginePeriod,
-- AudioClient_InitializeSharedAudioStream,
- };
-
- static HRESULT WINAPI AudioRenderClient_QueryInterface(
-@@ -2347,13 +2302,13 @@ static HRESULT WINAPI AudioRenderClient_QueryInterface(
- static ULONG WINAPI AudioRenderClient_AddRef(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_AddRef(&This->IAudioClient3_iface);
-+ return AudioClient_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioRenderClient_Release(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_Release(&This->IAudioClient3_iface);
-+ return AudioClient_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
-@@ -2504,13 +2459,13 @@ static HRESULT WINAPI AudioCaptureClient_QueryInterface(
- static ULONG WINAPI AudioCaptureClient_AddRef(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioCaptureClient_Release(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
-@@ -2672,13 +2627,13 @@ static HRESULT WINAPI AudioClock_QueryInterface(IAudioClock *iface,
- static ULONG WINAPI AudioClock_AddRef(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock_Release(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock_GetFrequency(IAudioClock *iface, UINT64 *freq)
-@@ -2768,13 +2723,13 @@ static HRESULT WINAPI AudioClock2_QueryInterface(IAudioClock2 *iface,
- static ULONG WINAPI AudioClock2_AddRef(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock2_Release(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock2_GetDevicePosition(IAudioClock2 *iface,
-@@ -2813,7 +2768,7 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client)
- ret->client = client;
- if(client){
- ret->session = client->session;
-- IAudioClient3_AddRef(&client->IAudioClient3_iface);
-+ AudioClient2_AddRef(&client->IAudioClient2_iface);
- }
-
- return ret;
-@@ -2861,7 +2816,7 @@ static ULONG WINAPI AudioSessionControl_Release(IAudioSessionControl2 *iface)
- OSSpinLockLock(&This->client->lock);
- This->client->session_wrapper = NULL;
- OSSpinLockUnlock(&This->client->lock);
-- AudioClient_Release(&This->client->IAudioClient3_iface);
-+ AudioClient_Release(&This->client->IAudioClient2_iface);
- }
- HeapFree(GetProcessHeap(), 0, This);
- }
-@@ -3256,13 +3211,13 @@ static HRESULT WINAPI AudioStreamVolume_QueryInterface(
- static ULONG WINAPI AudioStreamVolume_AddRef(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioStreamVolume_Release(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioStreamVolume_GetChannelCount(
-diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c
-index db2c6b23914d5e49ed7f125f16749f1f4cee45d2..3a3cb57b642493f5bc2cc01f002300497e78a625 100644
---- a/dlls/wineoss.drv/mmdevdrv.c
-+++ b/dlls/wineoss.drv/mmdevdrv.c
-@@ -90,7 +90,7 @@ typedef struct _AudioSessionWrapper {
- } AudioSessionWrapper;
-
- struct ACImpl {
-- IAudioClient3 IAudioClient3_iface;
-+ IAudioClient2 IAudioClient2_iface;
- IAudioRenderClient IAudioRenderClient_iface;
- IAudioCaptureClient IAudioCaptureClient_iface;
- IAudioClock IAudioClock_iface;
-@@ -168,7 +168,7 @@ static struct list g_sessions = LIST_INIT(g_sessions);
-
- static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client);
-
--static const IAudioClient3Vtbl AudioClient3_Vtbl;
-+static const IAudioClient2Vtbl AudioClient2_Vtbl;
- static const IAudioRenderClientVtbl AudioRenderClient_Vtbl;
- static const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl;
- static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl;
-@@ -179,9 +179,9 @@ static const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl;
- static const IChannelAudioVolumeVtbl ChannelAudioVolume_Vtbl;
- static const IAudioSessionManager2Vtbl AudioSessionManager2_Vtbl;
-
--static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface)
-+static inline ACImpl *impl_from_IAudioClient2(IAudioClient2 *iface)
- {
-- return CONTAINING_RECORD(iface, ACImpl, IAudioClient3_iface);
-+ return CONTAINING_RECORD(iface, ACImpl, IAudioClient2_iface);
- }
-
- static inline ACImpl *impl_from_IAudioRenderClient(IAudioRenderClient *iface)
-@@ -605,7 +605,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev,
- if(!This)
- return E_OUTOFMEMORY;
-
-- hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient3_iface, &This->pUnkFTMarshal);
-+ hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient2_iface, &This->pUnkFTMarshal);
- if (FAILED(hr)) {
- HeapFree(GetProcessHeap(), 0, This);
- return hr;
-@@ -652,7 +652,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev,
- TRACE("min_channels: %d\n", This->ai.min_channels);
- TRACE("max_channels: %d\n", This->ai.max_channels);
-
-- This->IAudioClient3_iface.lpVtbl = &AudioClient3_Vtbl;
-+ This->IAudioClient2_iface.lpVtbl = &AudioClient2_Vtbl;
- This->IAudioRenderClient_iface.lpVtbl = &AudioRenderClient_Vtbl;
- This->IAudioCaptureClient_iface.lpVtbl = &AudioCaptureClient_Vtbl;
- This->IAudioClock_iface.lpVtbl = &AudioClock_Vtbl;
-@@ -665,16 +665,16 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev,
- This->parent = dev;
- IMMDevice_AddRef(This->parent);
-
-- *out = (IAudioClient *)&This->IAudioClient3_iface;
-- IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ *out = (IAudioClient *)&This->IAudioClient2_iface;
-+ IAudioClient2_AddRef(&This->IAudioClient2_iface);
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient2 *iface,
- REFIID riid, void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
-
- if(!ppv)
-@@ -682,8 +682,7 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- *ppv = NULL;
- if(IsEqualIID(riid, &IID_IUnknown) ||
- IsEqualIID(riid, &IID_IAudioClient) ||
-- IsEqualIID(riid, &IID_IAudioClient2) ||
-- IsEqualIID(riid, &IID_IAudioClient3))
-+ IsEqualIID(riid, &IID_IAudioClient2))
- *ppv = iface;
- else if(IsEqualIID(riid, &IID_IMarshal))
- return IUnknown_QueryInterface(This->pUnkFTMarshal, riid, ppv);
-@@ -695,18 +694,18 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- return E_NOINTERFACE;
- }
-
--static ULONG WINAPI AudioClient_AddRef(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_AddRef(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
- ref = InterlockedIncrement(&This->ref);
- TRACE("(%p) Refcount now %u\n", This, ref);
- return ref;
- }
-
--static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_Release(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
-
- ref = InterlockedDecrement(&This->ref);
-@@ -723,7 +722,7 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
- CloseHandle(event);
- }
-
-- IAudioClient3_Stop(iface);
-+ IAudioClient2_Stop(iface);
- IMMDevice_Release(This->parent);
- IUnknown_Release(This->pUnkFTMarshal);
- This->lock.DebugInfo->Spare[0] = 0;
-@@ -1030,12 +1029,12 @@ static HRESULT get_audio_session(const GUID *sessionguid,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_Initialize(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration,
- REFERENCE_TIME period, const WAVEFORMATEX *fmt,
- const GUID *sessionguid)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- int i;
- HRESULT hr;
-
-@@ -1160,10 +1159,10 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient2 *iface,
- UINT32 *frames)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, frames);
-
-@@ -1186,10 +1185,10 @@ static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient2 *iface,
- REFERENCE_TIME *latency)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, latency);
-
-@@ -1212,10 +1211,10 @@ static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient2 *iface,
- UINT32 *numpad)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, numpad);
-
-@@ -1238,11 +1237,11 @@ static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, const WAVEFORMATEX *pwfx,
- WAVEFORMATEX **outpwfx)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- int fd = -1;
- HRESULT ret;
-
-@@ -1284,10 +1283,10 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
- return ret;
- }
-
--static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient2 *iface,
- WAVEFORMATEX **pwfx)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- WAVEFORMATEXTENSIBLE *fmt;
- int formats;
-
-@@ -1377,10 +1376,10 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient2 *iface,
- REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p, %p)\n", This, defperiod, minperiod);
-
-@@ -1561,9 +1560,9 @@ static void CALLBACK oss_period_callback(void *user, BOOLEAN timer)
- SetEvent(This->event);
- }
-
--static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Start(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)\n", This);
-
-@@ -1598,9 +1597,9 @@ static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Stop(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)\n", This);
-
-@@ -1624,9 +1623,9 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Reset(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)\n", This);
-
-@@ -1662,10 +1661,10 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient2 *iface,
- HANDLE event)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, event);
-
-@@ -1697,10 +1696,10 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
-+static HRESULT WINAPI AudioClient_GetService(IAudioClient2 *iface, REFIID riid,
- void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
-
-@@ -1781,10 +1780,10 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
- return E_NOINTERFACE;
- }
-
--static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient2 *iface,
- AUDIO_STREAM_CATEGORY category, BOOL *offload_capable)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(0x%x, %p)\n", This, category, offload_capable);
-
-@@ -1796,83 +1795,42 @@ static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient2 *iface,
- const AudioClientProperties *prop)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, prop);
-
-- if(!legacy_prop)
-+ if(!prop)
- return E_POINTER;
-
-- if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory,
-- prop->Options);
-- }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory);
-- }else{
-- WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
-+ if(prop->cbSize != sizeof(*prop))
- return E_INVALIDARG;
-- }
-
-+ TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-+ prop->bIsOffload,
-+ prop->eCategory,
-+ prop->Options);
-
-- if(legacy_prop->bIsOffload)
-+ if(prop->bIsOffload)
- return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient2 *iface,
- const WAVEFORMATEX *format, BOOL event_driven, REFERENCE_TIME *min_duration,
- REFERENCE_TIME *max_duration)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- FIXME("(%p)->(%p, %u, %p, %p)\n", This, format, event_driven, min_duration, max_duration);
-
- return E_NOTIMPL;
- }
-
--static HRESULT WINAPI AudioClient_GetSharedModeEnginePeriod(IAudioClient3 *iface,
-- const WAVEFORMATEX *format, UINT32 *default_period_frames, UINT32 *unit_period_frames,
-- UINT32 *min_period_frames, UINT32 *max_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p, %p, %p, %p)\n", This, format, default_period_frames, unit_period_frames,
-- min_period_frames, max_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface,
-- WAVEFORMATEX **cur_format, UINT32 *cur_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p)\n", This, cur_format, cur_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_InitializeSharedAudioStream(IAudioClient3 *iface,
-- DWORD flags, UINT32 period_frames, const WAVEFORMATEX *format,
-- const GUID *session_guid)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(0x%x, %u, %p, %s)\n", This, flags, period_frames, format, debugstr_guid(session_guid));
--
-- return E_NOTIMPL;
--}
--
--static const IAudioClient3Vtbl AudioClient3_Vtbl =
-+static const IAudioClient2Vtbl AudioClient2_Vtbl =
- {
- AudioClient_QueryInterface,
- AudioClient_AddRef,
-@@ -1892,9 +1850,6 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl =
- AudioClient_IsOffloadCapable,
- AudioClient_SetClientProperties,
- AudioClient_GetBufferSizeLimits,
-- AudioClient_GetSharedModeEnginePeriod,
-- AudioClient_GetCurrentSharedModeEnginePeriod,
-- AudioClient_InitializeSharedAudioStream,
- };
-
- static HRESULT WINAPI AudioRenderClient_QueryInterface(
-@@ -1924,13 +1879,13 @@ static HRESULT WINAPI AudioRenderClient_QueryInterface(
- static ULONG WINAPI AudioRenderClient_AddRef(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_AddRef(&This->IAudioClient3_iface);
-+ return AudioClient_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioRenderClient_Release(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_Release(&This->IAudioClient3_iface);
-+ return AudioClient_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
-@@ -2090,13 +2045,13 @@ static HRESULT WINAPI AudioCaptureClient_QueryInterface(
- static ULONG WINAPI AudioCaptureClient_AddRef(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioCaptureClient_Release(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
-@@ -2266,13 +2221,13 @@ static HRESULT WINAPI AudioClock_QueryInterface(IAudioClock *iface,
- static ULONG WINAPI AudioClock_AddRef(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock_Release(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock_GetFrequency(IAudioClock *iface, UINT64 *freq)
-@@ -2375,13 +2330,13 @@ static HRESULT WINAPI AudioClock2_QueryInterface(IAudioClock2 *iface,
- static ULONG WINAPI AudioClock2_AddRef(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock2_Release(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock2_GetDevicePosition(IAudioClock2 *iface,
-@@ -2420,7 +2375,7 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client)
- ret->client = client;
- if(client){
- ret->session = client->session;
-- AudioClient_AddRef(&client->IAudioClient3_iface);
-+ AudioClient_AddRef(&client->IAudioClient2_iface);
- }
-
- return ret;
-@@ -2468,7 +2423,7 @@ static ULONG WINAPI AudioSessionControl_Release(IAudioSessionControl2 *iface)
- EnterCriticalSection(&This->client->lock);
- This->client->session_wrapper = NULL;
- LeaveCriticalSection(&This->client->lock);
-- AudioClient_Release(&This->client->IAudioClient3_iface);
-+ AudioClient_Release(&This->client->IAudioClient2_iface);
- }
- HeapFree(GetProcessHeap(), 0, This);
- }
-@@ -2811,13 +2766,13 @@ static HRESULT WINAPI AudioStreamVolume_QueryInterface(
- static ULONG WINAPI AudioStreamVolume_AddRef(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioStreamVolume_Release(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioStreamVolume_GetChannelCount(
-diff --git a/dlls/winepulse.drv/Makefile.in b/dlls/winepulse.drv/Makefile.in
-index 4bf053d4e54f1790ef08bba4ef8330bd41a1f133..3082ed8a69ef642da648b1311b601e6d69a60d7c 100644
---- a/dlls/winepulse.drv/Makefile.in
-+++ b/dlls/winepulse.drv/Makefile.in
-@@ -1,11 +1,8 @@
- MODULE = winepulse.drv
- IMPORTS = dxguid uuid winmm user32 advapi32 ole32
--EXTRALIBS = $(PULSE_LIBS) $(PTHREAD_LIBS) -Wl,--subsystem,native
-+EXTRALIBS = $(PULSE_LIBS) $(PTHREAD_LIBS)
- EXTRAINCL = $(PULSE_CFLAGS)
--
--EXTRADLLFLAGS = -mno-cygwin
-+EXTRADEFS = -DWINE_NO_NAMELESS_EXTENSION
-
- C_SRCS = \
-- mmdevdrv.c \
-- mult.c \
-- pulse.c
-+ mmdevdrv.c
-diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c
-index 67a42de97f96278b32988bdad5d168547edbe8f8..07407089ac5af65eb13d6e00b6d0969a61ec5589 100644
---- a/dlls/winepulse.drv/mmdevdrv.c
-+++ b/dlls/winepulse.drv/mmdevdrv.c
-@@ -18,15 +18,28 @@
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-+#define NONAMELESSUNION
- #define COBJMACROS
-+#define _GNU_SOURCE
-+
-+#include "config.h"
-+#include
-+#include
-
- #include
--#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include
-
- #include "windef.h"
- #include "winbase.h"
--#include "winternl.h"
-+#include "winnls.h"
-+#include "winreg.h"
- #include "wine/debug.h"
-+#include "wine/unicode.h"
- #include "wine/list.h"
-
- #include "ole2.h"
-@@ -43,12 +56,8 @@
- #include "endpointvolume.h"
- #include "audiopolicy.h"
-
--#include "unixlib.h"
--
- WINE_DEFAULT_DEBUG_CHANNEL(pulse);
-
--static UINT64 pulse_handle;
--
- #define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
-
- /* From */
-@@ -59,33 +68,52 @@ enum DriverPriority {
- Priority_Preferred
- };
-
--static struct pulse_config pulse_config;
-+static const REFERENCE_TIME MinimumPeriod = 30000;
-+static const REFERENCE_TIME DefaultPeriod = 100000;
-+
-+static pa_context *pulse_ctx;
-+static pa_mainloop *pulse_ml;
-
- static HANDLE pulse_thread;
-+static pthread_mutex_t pulse_lock;
-+static pthread_cond_t pulse_cond = PTHREAD_COND_INITIALIZER;
- static struct list g_sessions = LIST_INIT(g_sessions);
-
-+static UINT g_phys_speakers_mask = 0;
-+
-+/* Mixer format + period times */
-+static WAVEFORMATEXTENSIBLE pulse_fmt[2];
-+static REFERENCE_TIME pulse_min_period[2], pulse_def_period[2];
-+
- static GUID pulse_render_guid =
- { 0xfd47d9cc, 0x4218, 0x4135, { 0x9c, 0xe2, 0x0c, 0x19, 0x5c, 0x87, 0x40, 0x5b } };
- static GUID pulse_capture_guid =
- { 0x25da76d0, 0x033c, 0x4235, { 0x90, 0x02, 0x19, 0xf4, 0x88, 0x94, 0xac, 0x6f } };
-
--static CRITICAL_SECTION session_cs;
--static CRITICAL_SECTION_DEBUG session_cs_debug = {
-- 0, 0, &session_cs,
-- { &session_cs_debug.ProcessLocksList,
-- &session_cs_debug.ProcessLocksList },
-- 0, 0, { (DWORD_PTR)(__FILE__ ": session_cs") }
--};
--static CRITICAL_SECTION session_cs = { &session_cs_debug, -1, 0, 0, 0, 0 };
-+static UINT8 mult_alaw_sample(UINT8, float);
-+static UINT8 mult_ulaw_sample(UINT8, float);
-
- BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, void *reserved)
- {
- if (reason == DLL_PROCESS_ATTACH) {
-+ pthread_mutexattr_t attr;
-+
- DisableThreadLibraryCalls(dll);
-- if (__wine_init_unix_lib(dll, reason, NULL, &pulse_handle))
-- return FALSE;
-+
-+ pthread_mutexattr_init(&attr);
-+ pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
-+
-+ if (pthread_mutex_init(&pulse_lock, &attr) != 0)
-+ pthread_mutex_init(&pulse_lock, NULL);
- } else if (reason == DLL_PROCESS_DETACH) {
-- __wine_init_unix_lib(dll, reason, NULL, NULL);
-+ if (pulse_thread)
-+ SetThreadPriority(pulse_thread, 0);
-+ if (pulse_ctx) {
-+ pa_context_disconnect(pulse_ctx);
-+ pa_context_unref(pulse_ctx);
-+ }
-+ if (pulse_ml)
-+ pa_mainloop_quit(pulse_ml, 0);
- if (pulse_thread) {
- WaitForSingleObject(pulse_thread, INFINITE);
- CloseHandle(pulse_thread);
-@@ -121,8 +149,15 @@ typedef struct _AudioSessionWrapper {
- AudioSession *session;
- } AudioSessionWrapper;
-
-+typedef struct _ACPacket {
-+ struct list entry;
-+ UINT64 qpcpos;
-+ BYTE *data;
-+ UINT32 discont;
-+} ACPacket;
-+
- struct ACImpl {
-- IAudioClient3 IAudioClient3_iface;
-+ IAudioClient2 IAudioClient2_iface;
- IAudioRenderClient IAudioRenderClient_iface;
- IAudioCaptureClient IAudioCaptureClient_iface;
- IAudioClock IAudioClock_iface;
-@@ -131,22 +166,36 @@ struct ACImpl {
- IUnknown *marshal;
- IMMDevice *parent;
- struct list entry;
-- float *vol;
-+ float vol[PA_CHANNELS_MAX];
-
- LONG ref;
- EDataFlow dataflow;
-- UINT32 channel_count;
-- HANDLE timer;
-+ DWORD flags;
-+ AUDCLNT_SHAREMODE share;
-+ HANDLE event;
-+
-+ INT32 locked;
-+ UINT32 bufsize_frames, bufsize_bytes, capture_period, pad, started, peek_ofs, wri_offs_bytes, lcl_offs_bytes;
-+ UINT32 tmp_buffer_bytes, held_bytes, peek_len, peek_buffer_len;
-+ BYTE *local_buffer, *tmp_buffer, *peek_buffer;
-+ void *locked_ptr;
-+
-+ pa_stream *stream;
-+ pa_sample_spec ss;
-+ pa_channel_map map;
-+ pa_buffer_attr attr;
-
-- struct pulse_stream *pulse_stream;
-+ INT64 clock_lastpos, clock_written;
-
- AudioSession *session;
- AudioSessionWrapper *session_wrapper;
-+ struct list packet_free_head;
-+ struct list packet_filled_head;
- };
-
--static const WCHAR defaultW[] = L"Pulseaudio";
-+static const WCHAR defaultW[] = {'P','u','l','s','e','a','u','d','i','o',0};
-
--static const IAudioClient3Vtbl AudioClient3_Vtbl;
-+static const IAudioClient2Vtbl AudioClient2_Vtbl;
- static const IAudioRenderClientVtbl AudioRenderClient_Vtbl;
- static const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl;
- static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl;
-@@ -158,9 +207,9 @@ static const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl;
-
- static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client);
-
--static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface)
-+static inline ACImpl *impl_from_IAudioClient2(IAudioClient2 *iface)
- {
-- return CONTAINING_RECORD(iface, ACImpl, IAudioClient3_iface);
-+ return CONTAINING_RECORD(iface, ACImpl, IAudioClient2_iface);
- }
-
- static inline ACImpl *impl_from_IAudioRenderClient(IAudioRenderClient *iface)
-@@ -203,65 +252,896 @@ static inline ACImpl *impl_from_IAudioStreamVolume(IAudioStreamVolume *iface)
- return CONTAINING_RECORD(iface, ACImpl, IAudioStreamVolume_iface);
- }
-
--static void pulse_call(enum unix_funcs code, void *params)
-+/* Following pulseaudio design here, mainloop has the lock taken whenever
-+ * it is handling something for pulse, and the lock is required whenever
-+ * doing any pa_* call that can affect the state in any way
-+ *
-+ * pa_cond_wait is used when waiting on results, because the mainloop needs
-+ * the same lock taken to affect the state
-+ *
-+ * This is basically the same as the pa_threaded_mainloop implementation,
-+ * but that cannot be used because it uses pthread_create directly
-+ *
-+ * pa_threaded_mainloop_(un)lock -> pthread_mutex_(un)lock
-+ * pa_threaded_mainloop_signal -> pthread_cond_broadcast
-+ * pa_threaded_mainloop_wait -> pthread_cond_wait
-+ */
-+
-+static int pulse_poll_func(struct pollfd *ufds, unsigned long nfds, int timeout, void *userdata) {
-+ int r;
-+ pthread_mutex_unlock(&pulse_lock);
-+ r = poll(ufds, nfds, timeout);
-+ pthread_mutex_lock(&pulse_lock);
-+ return r;
-+}
-+
-+static DWORD CALLBACK pulse_mainloop_thread(void *tmp) {
-+ int ret;
-+ pulse_ml = pa_mainloop_new();
-+ pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL);
-+ pthread_mutex_lock(&pulse_lock);
-+ pthread_cond_broadcast(&pulse_cond);
-+ pa_mainloop_run(pulse_ml, &ret);
-+ pthread_mutex_unlock(&pulse_lock);
-+ pa_mainloop_free(pulse_ml);
-+ return ret;
-+}
-+
-+static void pulse_contextcallback(pa_context *c, void *userdata)
- {
-- NTSTATUS status;
-- status = __wine_unix_call(pulse_handle, code, params);
-- assert(!status);
-+ switch (pa_context_get_state(c)) {
-+ default:
-+ FIXME("Unhandled state: %i\n", pa_context_get_state(c));
-+ return;
-+
-+ case PA_CONTEXT_CONNECTING:
-+ case PA_CONTEXT_UNCONNECTED:
-+ case PA_CONTEXT_AUTHORIZING:
-+ case PA_CONTEXT_SETTING_NAME:
-+ case PA_CONTEXT_TERMINATED:
-+ TRACE("State change to %i\n", pa_context_get_state(c));
-+ return;
-+
-+ case PA_CONTEXT_READY:
-+ TRACE("Ready\n");
-+ break;
-+
-+ case PA_CONTEXT_FAILED:
-+ WARN("Context failed: %s\n", pa_strerror(pa_context_errno(c)));
-+ break;
-+ }
-+ pthread_cond_broadcast(&pulse_cond);
- }
-
--static void pulse_release_stream(struct pulse_stream *stream, HANDLE timer)
-+static void pulse_stream_state(pa_stream *s, void *user)
- {
-- struct release_stream_params params;
-- params.stream = stream;
-- params.timer = timer;
-- pulse_call(release_stream, ¶ms);
-+ pa_stream_state_t state = pa_stream_get_state(s);
-+ TRACE("Stream state changed to %i\n", state);
-+ pthread_cond_broadcast(&pulse_cond);
- }
-
--static DWORD CALLBACK pulse_mainloop_thread(void *event)
-+static const enum pa_channel_position pulse_pos_from_wfx[] = {
-+ PA_CHANNEL_POSITION_FRONT_LEFT,
-+ PA_CHANNEL_POSITION_FRONT_RIGHT,
-+ PA_CHANNEL_POSITION_FRONT_CENTER,
-+ PA_CHANNEL_POSITION_LFE,
-+ PA_CHANNEL_POSITION_REAR_LEFT,
-+ PA_CHANNEL_POSITION_REAR_RIGHT,
-+ PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
-+ PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
-+ PA_CHANNEL_POSITION_REAR_CENTER,
-+ PA_CHANNEL_POSITION_SIDE_LEFT,
-+ PA_CHANNEL_POSITION_SIDE_RIGHT,
-+ PA_CHANNEL_POSITION_TOP_CENTER,
-+ PA_CHANNEL_POSITION_TOP_FRONT_LEFT,
-+ PA_CHANNEL_POSITION_TOP_FRONT_CENTER,
-+ PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,
-+ PA_CHANNEL_POSITION_TOP_REAR_LEFT,
-+ PA_CHANNEL_POSITION_TOP_REAR_CENTER,
-+ PA_CHANNEL_POSITION_TOP_REAR_RIGHT
-+};
-+
-+static DWORD pulse_channel_map_to_channel_mask(const pa_channel_map *map)
- {
-- struct main_loop_params params;
-- params.event = event;
-- pulse_call(main_loop, ¶ms);
-- return 0;
-+ int i;
-+ DWORD mask = 0;
-+
-+ for (i = 0; i < map->channels; ++i) {
-+ switch (map->map[i]) {
-+ default: FIXME("Unhandled channel %s\n", pa_channel_position_to_string(map->map[i])); break;
-+ case PA_CHANNEL_POSITION_FRONT_LEFT: mask |= SPEAKER_FRONT_LEFT; break;
-+ case PA_CHANNEL_POSITION_MONO:
-+ case PA_CHANNEL_POSITION_FRONT_CENTER: mask |= SPEAKER_FRONT_CENTER; break;
-+ case PA_CHANNEL_POSITION_FRONT_RIGHT: mask |= SPEAKER_FRONT_RIGHT; break;
-+ case PA_CHANNEL_POSITION_REAR_LEFT: mask |= SPEAKER_BACK_LEFT; break;
-+ case PA_CHANNEL_POSITION_REAR_CENTER: mask |= SPEAKER_BACK_CENTER; break;
-+ case PA_CHANNEL_POSITION_REAR_RIGHT: mask |= SPEAKER_BACK_RIGHT; break;
-+ case PA_CHANNEL_POSITION_LFE: mask |= SPEAKER_LOW_FREQUENCY; break;
-+ case PA_CHANNEL_POSITION_SIDE_LEFT: mask |= SPEAKER_SIDE_LEFT; break;
-+ case PA_CHANNEL_POSITION_SIDE_RIGHT: mask |= SPEAKER_SIDE_RIGHT; break;
-+ case PA_CHANNEL_POSITION_TOP_CENTER: mask |= SPEAKER_TOP_CENTER; break;
-+ case PA_CHANNEL_POSITION_TOP_FRONT_LEFT: mask |= SPEAKER_TOP_FRONT_LEFT; break;
-+ case PA_CHANNEL_POSITION_TOP_FRONT_CENTER: mask |= SPEAKER_TOP_FRONT_CENTER; break;
-+ case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT: mask |= SPEAKER_TOP_FRONT_RIGHT; break;
-+ case PA_CHANNEL_POSITION_TOP_REAR_LEFT: mask |= SPEAKER_TOP_BACK_LEFT; break;
-+ case PA_CHANNEL_POSITION_TOP_REAR_CENTER: mask |= SPEAKER_TOP_BACK_CENTER; break;
-+ case PA_CHANNEL_POSITION_TOP_REAR_RIGHT: mask |= SPEAKER_TOP_BACK_RIGHT; break;
-+ case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: mask |= SPEAKER_FRONT_LEFT_OF_CENTER; break;
-+ case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: mask |= SPEAKER_FRONT_RIGHT_OF_CENTER; break;
-+ }
-+ }
-+
-+ return mask;
- }
-
--static char *get_application_name(void)
-+/* For most hardware on Windows, users must choose a configuration with an even
-+ * number of channels (stereo, quad, 5.1, 7.1). Users can then disable
-+ * channels, but those channels are still reported to applications from
-+ * GetMixFormat! Some applications behave badly if given an odd number of
-+ * channels (e.g. 2.1). Here, we find the nearest configuration that Windows
-+ * would report for a given channel layout. */
-+static void convert_channel_map(const pa_channel_map *pa_map, WAVEFORMATEXTENSIBLE *fmt)
- {
-+ DWORD pa_mask = pulse_channel_map_to_channel_mask(pa_map);
-+
-+ TRACE("got mask for PA: 0x%x\n", pa_mask);
-+
-+ if (pa_map->channels == 1)
-+ {
-+ fmt->Format.nChannels = 1;
-+ fmt->dwChannelMask = pa_mask;
-+ return;
-+ }
-+
-+ /* compare against known configurations and find smallest configuration
-+ * which is a superset of the given speakers */
-+
-+ if (pa_map->channels <= 2 &&
-+ (pa_mask & ~KSAUDIO_SPEAKER_STEREO) == 0)
-+ {
-+ fmt->Format.nChannels = 2;
-+ fmt->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
-+ return;
-+ }
-+
-+ if (pa_map->channels <= 4 &&
-+ (pa_mask & ~KSAUDIO_SPEAKER_QUAD) == 0)
-+ {
-+ fmt->Format.nChannels = 4;
-+ fmt->dwChannelMask = KSAUDIO_SPEAKER_QUAD;
-+ return;
-+ }
-+
-+ if (pa_map->channels <= 4 &&
-+ (pa_mask & ~KSAUDIO_SPEAKER_SURROUND) == 0)
-+ {
-+ fmt->Format.nChannels = 4;
-+ fmt->dwChannelMask = KSAUDIO_SPEAKER_SURROUND;
-+ return;
-+ }
-+
-+ if (pa_map->channels <= 6 &&
-+ (pa_mask & ~KSAUDIO_SPEAKER_5POINT1) == 0)
-+ {
-+ fmt->Format.nChannels = 6;
-+ fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
-+ return;
-+ }
-+
-+ if (pa_map->channels <= 6 &&
-+ (pa_mask & ~KSAUDIO_SPEAKER_5POINT1_SURROUND) == 0)
-+ {
-+ fmt->Format.nChannels = 6;
-+ fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND;
-+ return;
-+ }
-+
-+ if (pa_map->channels <= 8 &&
-+ (pa_mask & ~KSAUDIO_SPEAKER_7POINT1) == 0)
-+ {
-+ fmt->Format.nChannels = 8;
-+ fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1;
-+ return;
-+ }
-+
-+ if (pa_map->channels <= 8 &&
-+ (pa_mask & ~KSAUDIO_SPEAKER_7POINT1_SURROUND) == 0)
-+ {
-+ fmt->Format.nChannels = 8;
-+ fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
-+ return;
-+ }
-+
-+ /* oddball format, report truthfully */
-+ fmt->Format.nChannels = pa_map->channels;
-+ fmt->dwChannelMask = pa_mask;
-+}
-+
-+static void pulse_probe_settings(int render, WAVEFORMATEXTENSIBLE *fmt) {
-+ WAVEFORMATEX *wfx = &fmt->Format;
-+ pa_stream *stream;
-+ pa_channel_map map;
-+ pa_sample_spec ss;
-+ pa_buffer_attr attr;
-+ int ret;
-+ unsigned int length = 0;
-+
-+ pa_channel_map_init_auto(&map, 2, PA_CHANNEL_MAP_ALSA);
-+ ss.rate = 48000;
-+ ss.format = PA_SAMPLE_FLOAT32LE;
-+ ss.channels = map.channels;
-+
-+ attr.maxlength = -1;
-+ attr.tlength = -1;
-+ attr.minreq = attr.fragsize = pa_frame_size(&ss);
-+ attr.prebuf = 0;
-+
-+ stream = pa_stream_new(pulse_ctx, "format test stream", &ss, &map);
-+ if (stream)
-+ pa_stream_set_state_callback(stream, pulse_stream_state, NULL);
-+ if (!stream)
-+ ret = -1;
-+ else if (render)
-+ ret = pa_stream_connect_playback(stream, NULL, &attr,
-+ PA_STREAM_START_CORKED|PA_STREAM_FIX_RATE|PA_STREAM_FIX_CHANNELS|PA_STREAM_EARLY_REQUESTS, NULL, NULL);
-+ else
-+ ret = pa_stream_connect_record(stream, NULL, &attr, PA_STREAM_START_CORKED|PA_STREAM_FIX_RATE|PA_STREAM_FIX_CHANNELS|PA_STREAM_EARLY_REQUESTS);
-+ if (ret >= 0) {
-+ while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
-+ pa_stream_get_state(stream) == PA_STREAM_CREATING)
-+ {}
-+ if (pa_stream_get_state(stream) == PA_STREAM_READY) {
-+ ss = *pa_stream_get_sample_spec(stream);
-+ map = *pa_stream_get_channel_map(stream);
-+ if (render)
-+ length = pa_stream_get_buffer_attr(stream)->minreq;
-+ else
-+ length = pa_stream_get_buffer_attr(stream)->fragsize;
-+ pa_stream_disconnect(stream);
-+ while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
-+ pa_stream_get_state(stream) == PA_STREAM_READY)
-+ {}
-+ }
-+ }
-+
-+ if (stream)
-+ pa_stream_unref(stream);
-+
-+ if (length)
-+ pulse_def_period[!render] = pulse_min_period[!render] = pa_bytes_to_usec(10 * length, &ss);
-+
-+ if (pulse_min_period[!render] < MinimumPeriod)
-+ pulse_min_period[!render] = MinimumPeriod;
-+
-+ if (pulse_def_period[!render] < DefaultPeriod)
-+ pulse_def_period[!render] = DefaultPeriod;
-+
-+ wfx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
-+ wfx->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
-+
-+ convert_channel_map(&map, fmt);
-+
-+ wfx->wBitsPerSample = 8 * pa_sample_size_of_format(ss.format);
-+ wfx->nSamplesPerSec = ss.rate;
-+ wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8;
-+ wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign;
-+ if (ss.format != PA_SAMPLE_S24_32LE)
-+ fmt->Samples.wValidBitsPerSample = wfx->wBitsPerSample;
-+ else
-+ fmt->Samples.wValidBitsPerSample = 24;
-+ if (ss.format == PA_SAMPLE_FLOAT32LE)
-+ fmt->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
-+ else
-+ fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
-+}
-+
-+static HRESULT pulse_connect(void)
-+{
-+ int len;
- WCHAR path[MAX_PATH], *name;
-- size_t len;
- char *str;
-
-+ if (!pulse_thread)
-+ {
-+ if (!(pulse_thread = CreateThread(NULL, 0, pulse_mainloop_thread, NULL, 0, NULL)))
-+ {
-+ ERR("Failed to create mainloop thread.\n");
-+ return E_FAIL;
-+ }
-+ SetThreadPriority(pulse_thread, THREAD_PRIORITY_TIME_CRITICAL);
-+ pthread_cond_wait(&pulse_cond, &pulse_lock);
-+ }
-+
-+ if (pulse_ctx && PA_CONTEXT_IS_GOOD(pa_context_get_state(pulse_ctx)))
-+ return S_OK;
-+ if (pulse_ctx)
-+ pa_context_unref(pulse_ctx);
-+
- GetModuleFileNameW(NULL, path, ARRAY_SIZE(path));
-- name = wcsrchr(path, '\\');
-+ name = strrchrW(path, '\\');
- if (!name)
- name = path;
- else
- name++;
-- len = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL);
-- if (!(str = malloc(len)))
-- return NULL;
-+ len = WideCharToMultiByte(CP_UNIXCP, 0, name, -1, NULL, 0, NULL, NULL);
-+ str = pa_xmalloc(len);
- WideCharToMultiByte(CP_UNIXCP, 0, name, -1, str, len, NULL, NULL);
-- return str;
-+ TRACE("Name: %s\n", str);
-+ pulse_ctx = pa_context_new(pa_mainloop_get_api(pulse_ml), str);
-+ pa_xfree(str);
-+ if (!pulse_ctx) {
-+ ERR("Failed to create context\n");
-+ return E_FAIL;
-+ }
-+
-+ pa_context_set_state_callback(pulse_ctx, pulse_contextcallback, NULL);
-+
-+ TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(pulse_ctx), PA_API_VERSION);
-+ if (pa_context_connect(pulse_ctx, NULL, 0, NULL) < 0)
-+ goto fail;
-+
-+ /* Wait for connection */
-+ while (pthread_cond_wait(&pulse_cond, &pulse_lock)) {
-+ pa_context_state_t state = pa_context_get_state(pulse_ctx);
-+
-+ if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED)
-+ goto fail;
-+
-+ if (state == PA_CONTEXT_READY)
-+ break;
-+ }
-+
-+ TRACE("Connected to server %s with protocol version: %i.\n",
-+ pa_context_get_server(pulse_ctx),
-+ pa_context_get_server_protocol_version(pulse_ctx));
-+ return S_OK;
-+
-+fail:
-+ pa_context_unref(pulse_ctx);
-+ pulse_ctx = NULL;
-+ return E_FAIL;
- }
-
--static DWORD WINAPI pulse_timer_cb(void *user)
-+/* For default PulseAudio render device, OR together all of the
-+ * PKEY_AudioEndpoint_PhysicalSpeakers values of the sinks. */
-+static void pulse_phys_speakers_cb(pa_context *c, const pa_sink_info *i, int eol, void *userdata)
- {
-- struct timer_loop_params params;
-- ACImpl *This = user;
-- params.stream = This->pulse_stream;
-- pulse_call(timer_loop, ¶ms);
-- return 0;
-+ if (i)
-+ g_phys_speakers_mask |= pulse_channel_map_to_channel_mask(&i->channel_map);
-+}
-+
-+/* some poorly-behaved applications call audio functions during DllMain, so we
-+ * have to do as much as possible without creating a new thread. this function
-+ * sets up a synchronous connection to verify the server is running and query
-+ * static data. */
-+static HRESULT pulse_test_connect(void)
-+{
-+ int len, ret;
-+ WCHAR path[MAX_PATH], *name;
-+ char *str;
-+ pa_operation *o;
-+
-+ pulse_ml = pa_mainloop_new();
-+
-+ pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL);
-+
-+ GetModuleFileNameW(NULL, path, ARRAY_SIZE(path));
-+ name = strrchrW(path, '\\');
-+ if (!name)
-+ name = path;
-+ else
-+ name++;
-+ len = WideCharToMultiByte(CP_UNIXCP, 0, name, -1, NULL, 0, NULL, NULL);
-+ str = pa_xmalloc(len);
-+ WideCharToMultiByte(CP_UNIXCP, 0, name, -1, str, len, NULL, NULL);
-+ TRACE("Name: %s\n", str);
-+ pulse_ctx = pa_context_new(pa_mainloop_get_api(pulse_ml), str);
-+ pa_xfree(str);
-+ if (!pulse_ctx) {
-+ ERR("Failed to create context\n");
-+ pa_mainloop_free(pulse_ml);
-+ pulse_ml = NULL;
-+ return E_FAIL;
-+ }
-+
-+ pa_context_set_state_callback(pulse_ctx, pulse_contextcallback, NULL);
-+
-+ TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(pulse_ctx), PA_API_VERSION);
-+ if (pa_context_connect(pulse_ctx, NULL, 0, NULL) < 0)
-+ goto fail;
-+
-+ /* Wait for connection */
-+ while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0) {
-+ pa_context_state_t state = pa_context_get_state(pulse_ctx);
-+
-+ if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED)
-+ goto fail;
-+
-+ if (state == PA_CONTEXT_READY)
-+ break;
-+ }
-+
-+ if (pa_context_get_state(pulse_ctx) != PA_CONTEXT_READY)
-+ goto fail;
-+
-+ TRACE("Test-connected to server %s with protocol version: %i.\n",
-+ pa_context_get_server(pulse_ctx),
-+ pa_context_get_server_protocol_version(pulse_ctx));
-+
-+ pulse_probe_settings(1, &pulse_fmt[0]);
-+ pulse_probe_settings(0, &pulse_fmt[1]);
-+
-+ g_phys_speakers_mask = 0;
-+ o = pa_context_get_sink_info_list(pulse_ctx, &pulse_phys_speakers_cb, NULL);
-+ if (o) {
-+ while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
-+ pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-+ {}
-+ pa_operation_unref(o);
-+ }
-+
-+ pa_context_unref(pulse_ctx);
-+ pulse_ctx = NULL;
-+ pa_mainloop_free(pulse_ml);
-+ pulse_ml = NULL;
-+
-+ return S_OK;
-+
-+fail:
-+ pa_context_unref(pulse_ctx);
-+ pulse_ctx = NULL;
-+ pa_mainloop_free(pulse_ml);
-+ pulse_ml = NULL;
-+
-+ return E_FAIL;
-+}
-+
-+static HRESULT pulse_stream_valid(ACImpl *This) {
-+ if (!This->stream)
-+ return AUDCLNT_E_NOT_INITIALIZED;
-+ if (pa_stream_get_state(This->stream) != PA_STREAM_READY)
-+ return AUDCLNT_E_DEVICE_INVALIDATED;
-+ return S_OK;
-+}
-+
-+static void silence_buffer(pa_sample_format_t format, BYTE *buffer, UINT32 bytes)
-+{
-+ memset(buffer, format == PA_SAMPLE_U8 ? 0x80 : 0, bytes);
-+}
-+
-+static void pulse_free_noop(void *buf)
-+{
-+}
-+
-+enum write_buffer_flags
-+{
-+ WINEPULSE_WRITE_NOFREE = 0x01,
-+ WINEPULSE_WRITE_SILENT = 0x02
-+};
-+
-+static int write_buffer(const ACImpl *This, BYTE *buffer, UINT32 bytes,
-+ enum write_buffer_flags flags)
-+{
-+ float vol[PA_CHANNELS_MAX];
-+ BOOL adjust = FALSE;
-+ UINT32 i, channels;
-+ BYTE *end;
-+
-+ if (!bytes) return 0;
-+ if (This->session->mute || (flags & WINEPULSE_WRITE_SILENT))
-+ {
-+ silence_buffer(This->ss.format, buffer, bytes);
-+ goto write;
-+ }
-+
-+ /* Adjust the buffer based on the volume for each channel */
-+ channels = This->ss.channels;
-+ for (i = 0; i < channels; i++)
-+ {
-+ vol[i] = This->vol[i] * This->session->master_vol * This->session->channel_vols[i];
-+ adjust |= vol[i] != 1.0f;
-+ }
-+ if (!adjust) goto write;
-+
-+ end = buffer + bytes;
-+ switch (This->ss.format)
-+ {
-+#ifndef WORDS_BIGENDIAN
-+#define PROCESS_BUFFER(type) do \
-+{ \
-+ type *p = (type*)buffer; \
-+ do \
-+ { \
-+ for (i = 0; i < channels; i++) \
-+ p[i] = p[i] * vol[i]; \
-+ p += i; \
-+ } while ((BYTE*)p != end); \
-+} while (0)
-+ case PA_SAMPLE_S16LE:
-+ PROCESS_BUFFER(INT16);
-+ break;
-+ case PA_SAMPLE_S32LE:
-+ PROCESS_BUFFER(INT32);
-+ break;
-+ case PA_SAMPLE_FLOAT32LE:
-+ PROCESS_BUFFER(float);
-+ break;
-+#undef PROCESS_BUFFER
-+ case PA_SAMPLE_S24_32LE:
-+ {
-+ UINT32 *p = (UINT32*)buffer;
-+ do
-+ {
-+ for (i = 0; i < channels; i++)
-+ {
-+ p[i] = (INT32)((INT32)(p[i] << 8) * vol[i]);
-+ p[i] >>= 8;
-+ }
-+ p += i;
-+ } while ((BYTE*)p != end);
-+ break;
-+ }
-+ case PA_SAMPLE_S24LE:
-+ {
-+ /* do it 12 bytes at a time until it is no longer possible */
-+ UINT32 *q = (UINT32*)buffer;
-+ BYTE *p;
-+
-+ i = 0;
-+ while (end - (BYTE*)q >= 12)
-+ {
-+ UINT32 v[4], k;
-+ v[0] = q[0] << 8;
-+ v[1] = q[1] << 16 | (q[0] >> 16 & ~0xff);
-+ v[2] = q[2] << 24 | (q[1] >> 8 & ~0xff);
-+ v[3] = q[2] & ~0xff;
-+ for (k = 0; k < 4; k++)
-+ {
-+ v[k] = (INT32)((INT32)v[k] * vol[i]);
-+ if (++i == channels) i = 0;
-+ }
-+ *q++ = v[0] >> 8 | (v[1] & ~0xff) << 16;
-+ *q++ = v[1] >> 16 | (v[2] & ~0xff) << 8;
-+ *q++ = v[2] >> 24 | (v[3] & ~0xff);
-+ }
-+ p = (BYTE*)q;
-+ while (p != end)
-+ {
-+ UINT32 v = (INT32)((INT32)(p[0] << 8 | p[1] << 16 | p[2] << 24) * vol[i]);
-+ *p++ = v >> 8 & 0xff;
-+ *p++ = v >> 16 & 0xff;
-+ *p++ = v >> 24;
-+ if (++i == channels) i = 0;
-+ }
-+ break;
-+ }
-+#endif
-+ case PA_SAMPLE_U8:
-+ {
-+ UINT8 *p = (UINT8*)buffer;
-+ do
-+ {
-+ for (i = 0; i < channels; i++)
-+ p[i] = (int)((p[i] - 128) * vol[i]) + 128;
-+ p += i;
-+ } while ((BYTE*)p != end);
-+ break;
-+ }
-+ case PA_SAMPLE_ALAW:
-+ {
-+ UINT8 *p = (UINT8*)buffer;
-+ do
-+ {
-+ for (i = 0; i < channels; i++)
-+ p[i] = mult_alaw_sample(p[i], vol[i]);
-+ p += i;
-+ } while ((BYTE*)p != end);
-+ break;
-+ }
-+ case PA_SAMPLE_ULAW:
-+ {
-+ UINT8 *p = (UINT8*)buffer;
-+ do
-+ {
-+ for (i = 0; i < channels; i++)
-+ p[i] = mult_ulaw_sample(p[i], vol[i]);
-+ p += i;
-+ } while ((BYTE*)p != end);
-+ break;
-+ }
-+ default:
-+ TRACE("Unhandled format %i, not adjusting volume.\n", This->ss.format);
-+ break;
-+ }
-+
-+write:
-+ return pa_stream_write(This->stream, buffer, bytes,
-+ (flags & WINEPULSE_WRITE_NOFREE) ? pulse_free_noop : NULL,
-+ 0, PA_SEEK_RELATIVE);
- }
-
--static void set_stream_volumes(ACImpl *This)
-+static void dump_attr(const pa_buffer_attr *attr) {
-+ TRACE("maxlength: %u\n", attr->maxlength);
-+ TRACE("minreq: %u\n", attr->minreq);
-+ TRACE("fragsize: %u\n", attr->fragsize);
-+ TRACE("tlength: %u\n", attr->tlength);
-+ TRACE("prebuf: %u\n", attr->prebuf);
-+}
-+
-+static void pulse_op_cb(pa_stream *s, int success, void *user) {
-+ TRACE("Success: %i\n", success);
-+ *(int*)user = success;
-+ pthread_cond_broadcast(&pulse_cond);
-+}
-+
-+static void pulse_attr_update(pa_stream *s, void *user) {
-+ const pa_buffer_attr *attr = pa_stream_get_buffer_attr(s);
-+ TRACE("New attributes or device moved:\n");
-+ dump_attr(attr);
-+}
-+
-+/* Here's the buffer setup:
-+ *
-+ * vvvvvvvv sent to HW already
-+ * vvvvvvvv in Pulse buffer but rewindable
-+ * [dddddddddddddddd] Pulse buffer
-+ * [dddddddddddddddd--------] mmdevapi buffer
-+ * ^^^^^^^^^^^^^^^^ pad
-+ * ^ lcl_offs_bytes
-+ * ^^^^^^^^^ held_bytes
-+ * ^ wri_offs_bytes
-+ *
-+ * GetCurrentPadding is pad
-+ *
-+ * During pulse_wr_callback, we decrement pad, fill Pulse buffer, and move
-+ * lcl_offs forward
-+ *
-+ * During Stop, we flush the Pulse buffer
-+ */
-+static void pulse_wr_callback(pa_stream *s, size_t bytes, void *userdata)
- {
-- struct set_volumes_params params;
-- params.stream = This->pulse_stream;
-- params.master_volume = This->session->mute ? 0.0f : This->session->master_vol;
-- params.volumes = This->vol;
-- params.session_volumes = This->session->channel_vols;
-- pulse_call(set_volumes, ¶ms);
-+ ACImpl *This = userdata;
-+ UINT32 oldpad = This->pad;
-+
-+ if(This->local_buffer){
-+ UINT32 to_write;
-+ BYTE *buf = This->local_buffer + This->lcl_offs_bytes;
-+
-+ if(This->pad > bytes){
-+ This->clock_written += bytes;
-+ This->pad -= bytes;
-+ }else{
-+ This->clock_written += This->pad;
-+ This->pad = 0;
-+ }
-+
-+ bytes = min(bytes, This->held_bytes);
-+
-+ if(This->lcl_offs_bytes + bytes > This->bufsize_bytes){
-+ to_write = This->bufsize_bytes - This->lcl_offs_bytes;
-+ TRACE("writing small chunk of %u bytes\n", to_write);
-+ write_buffer(This, buf, to_write, 0);
-+ This->held_bytes -= to_write;
-+ to_write = bytes - to_write;
-+ This->lcl_offs_bytes = 0;
-+ buf = This->local_buffer;
-+ }else
-+ to_write = bytes;
-+
-+ TRACE("writing main chunk of %u bytes\n", to_write);
-+ write_buffer(This, buf, to_write, 0);
-+ This->lcl_offs_bytes += to_write;
-+ This->lcl_offs_bytes %= This->bufsize_bytes;
-+ This->held_bytes -= to_write;
-+ }else{
-+ if (bytes < This->bufsize_bytes)
-+ This->pad = This->bufsize_bytes - bytes;
-+ else
-+ This->pad = 0;
-+
-+ if (oldpad == This->pad)
-+ return;
-+
-+ assert(oldpad > This->pad);
-+
-+ This->clock_written += oldpad - This->pad;
-+ TRACE("New pad: %zu (-%zu)\n", This->pad / pa_frame_size(&This->ss), (oldpad - This->pad) / pa_frame_size(&This->ss));
-+ }
-+
-+ if (This->event)
-+ SetEvent(This->event);
-+}
-+
-+static void pulse_underflow_callback(pa_stream *s, void *userdata)
-+{
-+ WARN("Underflow\n");
-+}
-+
-+/* Latency is periodically updated even when nothing is played,
-+ * because of PA_STREAM_AUTO_TIMING_UPDATE so use it as timer
-+ *
-+ * Perfect for passing all tests :)
-+ */
-+static void pulse_latency_callback(pa_stream *s, void *userdata)
-+{
-+ ACImpl *This = userdata;
-+ if (!This->pad && This->event)
-+ SetEvent(This->event);
-+}
-+
-+static void pulse_started_callback(pa_stream *s, void *userdata)
-+{
-+ TRACE("(Re)started playing\n");
-+}
-+
-+static void pulse_rd_loop(ACImpl *This, size_t bytes)
-+{
-+ while (bytes >= This->capture_period) {
-+ ACPacket *p, *next;
-+ LARGE_INTEGER stamp, freq;
-+ BYTE *dst, *src;
-+ size_t src_len, copy, rem = This->capture_period;
-+ if (!(p = (ACPacket*)list_head(&This->packet_free_head))) {
-+ p = (ACPacket*)list_head(&This->packet_filled_head);
-+ if (!p->discont) {
-+ next = (ACPacket*)p->entry.next;
-+ next->discont = 1;
-+ } else
-+ p = (ACPacket*)list_tail(&This->packet_filled_head);
-+ assert(This->pad == This->bufsize_bytes);
-+ } else {
-+ assert(This->pad < This->bufsize_bytes);
-+ This->pad += This->capture_period;
-+ assert(This->pad <= This->bufsize_bytes);
-+ }
-+ QueryPerformanceCounter(&stamp);
-+ QueryPerformanceFrequency(&freq);
-+ p->qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
-+ p->discont = 0;
-+ list_remove(&p->entry);
-+ list_add_tail(&This->packet_filled_head, &p->entry);
-+
-+ dst = p->data;
-+ while (rem) {
-+ if (This->peek_len) {
-+ copy = min(rem, This->peek_len - This->peek_ofs);
-+
-+ memcpy(dst, This->peek_buffer + This->peek_ofs, copy);
-+
-+ rem -= copy;
-+ dst += copy;
-+ This->peek_ofs += copy;
-+ if(This->peek_len == This->peek_ofs)
-+ This->peek_len = 0;
-+ } else {
-+ pa_stream_peek(This->stream, (const void**)&src, &src_len);
-+
-+ copy = min(rem, src_len);
-+
-+ memcpy(dst, src, rem);
-+
-+ dst += copy;
-+ rem -= copy;
-+
-+ if (copy < src_len) {
-+ if (src_len > This->peek_buffer_len) {
-+ HeapFree(GetProcessHeap(), 0, This->peek_buffer);
-+ This->peek_buffer = HeapAlloc(GetProcessHeap(), 0, src_len);
-+ This->peek_buffer_len = src_len;
-+ }
-+
-+ memcpy(This->peek_buffer, src + copy, src_len - copy);
-+ This->peek_len = src_len - copy;
-+ This->peek_ofs = 0;
-+ }
-+
-+ pa_stream_drop(This->stream);
-+ }
-+ }
-+
-+ bytes -= This->capture_period;
-+ }
-+}
-+
-+static void pulse_rd_drop(ACImpl *This, size_t bytes)
-+{
-+ while (bytes >= This->capture_period) {
-+ size_t src_len, copy, rem = This->capture_period;
-+ while (rem) {
-+ const void *src;
-+ pa_stream_peek(This->stream, &src, &src_len);
-+ assert(src_len);
-+ assert(This->peek_ofs < src_len);
-+ src_len -= This->peek_ofs;
-+ assert(src_len <= bytes);
-+
-+ copy = rem;
-+ if (copy > src_len)
-+ copy = src_len;
-+
-+ src_len -= copy;
-+ rem -= copy;
-+
-+ if (!src_len) {
-+ This->peek_ofs = 0;
-+ pa_stream_drop(This->stream);
-+ } else
-+ This->peek_ofs += copy;
-+ bytes -= copy;
-+ }
-+ }
-+}
-+
-+static void pulse_rd_callback(pa_stream *s, size_t bytes, void *userdata)
-+{
-+ ACImpl *This = userdata;
-+
-+ TRACE("Readable total: %zu, fragsize: %u\n", bytes, pa_stream_get_buffer_attr(s)->fragsize);
-+ assert(bytes >= This->peek_ofs);
-+ bytes -= This->peek_ofs;
-+ if (bytes < This->capture_period)
-+ return;
-+
-+ if (This->started)
-+ pulse_rd_loop(This, bytes);
-+ else
-+ pulse_rd_drop(This, bytes);
-+
-+ if (This->event)
-+ SetEvent(This->event);
-+}
-+
-+static HRESULT pulse_stream_connect(ACImpl *This, UINT32 period_bytes) {
-+ int ret;
-+ char buffer[64];
-+ static LONG number;
-+ pa_buffer_attr attr;
-+ if (This->stream) {
-+ pa_stream_disconnect(This->stream);
-+ while (pa_stream_get_state(This->stream) == PA_STREAM_READY)
-+ pthread_cond_wait(&pulse_cond, &pulse_lock);
-+ pa_stream_unref(This->stream);
-+ }
-+ ret = InterlockedIncrement(&number);
-+ sprintf(buffer, "audio stream #%i", ret);
-+ This->stream = pa_stream_new(pulse_ctx, buffer, &This->ss, &This->map);
-+
-+ if (!This->stream) {
-+ WARN("pa_stream_new returned error %i\n", pa_context_errno(pulse_ctx));
-+ return AUDCLNT_E_ENDPOINT_CREATE_FAILED;
-+ }
-+
-+ pa_stream_set_state_callback(This->stream, pulse_stream_state, This);
-+ pa_stream_set_buffer_attr_callback(This->stream, pulse_attr_update, This);
-+ pa_stream_set_moved_callback(This->stream, pulse_attr_update, This);
-+
-+ /* PulseAudio will fill in correct values */
-+ attr.minreq = attr.fragsize = period_bytes;
-+ attr.maxlength = attr.tlength = This->bufsize_bytes;
-+ attr.prebuf = pa_frame_size(&This->ss);
-+ dump_attr(&attr);
-+ if (This->dataflow == eRender)
-+ ret = pa_stream_connect_playback(This->stream, NULL, &attr,
-+ PA_STREAM_START_CORKED|PA_STREAM_START_UNMUTED|PA_STREAM_AUTO_TIMING_UPDATE|PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_EARLY_REQUESTS, NULL, NULL);
-+ else
-+ ret = pa_stream_connect_record(This->stream, NULL, &attr,
-+ PA_STREAM_START_CORKED|PA_STREAM_START_UNMUTED|PA_STREAM_AUTO_TIMING_UPDATE|PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_EARLY_REQUESTS);
-+ if (ret < 0) {
-+ WARN("Returns %i\n", ret);
-+ return AUDCLNT_E_ENDPOINT_CREATE_FAILED;
-+ }
-+ while (pa_stream_get_state(This->stream) == PA_STREAM_CREATING)
-+ pthread_cond_wait(&pulse_cond, &pulse_lock);
-+ if (pa_stream_get_state(This->stream) != PA_STREAM_READY)
-+ return AUDCLNT_E_ENDPOINT_CREATE_FAILED;
-+
-+ if (This->dataflow == eRender) {
-+ pa_stream_set_write_callback(This->stream, pulse_wr_callback, This);
-+ pa_stream_set_underflow_callback(This->stream, pulse_underflow_callback, This);
-+ pa_stream_set_started_callback(This->stream, pulse_started_callback, This);
-+ } else
-+ pa_stream_set_read_callback(This->stream, pulse_rd_callback, This);
-+ return S_OK;
- }
-
- HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, const WCHAR ***ids, GUID **keys,
-@@ -301,19 +1181,17 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, const WCHAR ***ids, GUID **
-
- int WINAPI AUDDRV_GetPriority(void)
- {
-- struct test_connect_params params;
-- char *name;
--
-- params.name = name = get_application_name();
-- params.config = &pulse_config;
-- pulse_call(test_connect, ¶ms);
-- free(name);
-- return SUCCEEDED(params.result) ? Priority_Preferred : Priority_Unavailable;
-+ HRESULT hr;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_test_connect();
-+ pthread_mutex_unlock(&pulse_lock);
-+ return SUCCEEDED(hr) ? Priority_Preferred : Priority_Unavailable;
- }
-
- HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient **out)
- {
- ACImpl *This;
-+ int i;
- EDataFlow dataflow;
- HRESULT hr;
-
-@@ -331,7 +1209,7 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
- if (!This)
- return E_OUTOFMEMORY;
-
-- This->IAudioClient3_iface.lpVtbl = &AudioClient3_Vtbl;
-+ This->IAudioClient2_iface.lpVtbl = &AudioClient2_Vtbl;
- This->IAudioRenderClient_iface.lpVtbl = &AudioRenderClient_Vtbl;
- This->IAudioCaptureClient_iface.lpVtbl = &AudioCaptureClient_Vtbl;
- This->IAudioClock_iface.lpVtbl = &AudioClock_Vtbl;
-@@ -339,24 +1217,26 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
- This->IAudioStreamVolume_iface.lpVtbl = &AudioStreamVolume_Vtbl;
- This->dataflow = dataflow;
- This->parent = dev;
-+ for (i = 0; i < PA_CHANNELS_MAX; ++i)
-+ This->vol[i] = 1.f;
-
-- hr = CoCreateFreeThreadedMarshaler((IUnknown*)&This->IAudioClient3_iface, &This->marshal);
-+ hr = CoCreateFreeThreadedMarshaler((IUnknown*)&This->IAudioClient2_iface, &This->marshal);
- if (hr) {
- HeapFree(GetProcessHeap(), 0, This);
- return hr;
- }
- IMMDevice_AddRef(This->parent);
-
-- *out = (IAudioClient *)&This->IAudioClient3_iface;
-- IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ *out = (IAudioClient *)&This->IAudioClient2_iface;
-+ IAudioClient2_AddRef(&This->IAudioClient2_iface);
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient2 *iface,
- REFIID riid, void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
-
-@@ -366,8 +1246,7 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- *ppv = NULL;
- if (IsEqualIID(riid, &IID_IUnknown) ||
- IsEqualIID(riid, &IID_IAudioClient) ||
-- IsEqualIID(riid, &IID_IAudioClient2) ||
-- IsEqualIID(riid, &IID_IAudioClient3))
-+ IsEqualIID(riid, &IID_IAudioClient2))
- *ppv = iface;
- if (*ppv) {
- IUnknown_AddRef((IUnknown*)*ppv);
-@@ -381,31 +1260,39 @@ static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface,
- return E_NOINTERFACE;
- }
-
--static ULONG WINAPI AudioClient_AddRef(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_AddRef(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
- ref = InterlockedIncrement(&This->ref);
- TRACE("(%p) Refcount now %u\n", This, ref);
- return ref;
- }
-
--static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
-+static ULONG WINAPI AudioClient_Release(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- ULONG ref;
- ref = InterlockedDecrement(&This->ref);
- TRACE("(%p) Refcount now %u\n", This, ref);
- if (!ref) {
-- if (This->pulse_stream) {
-- pulse_release_stream(This->pulse_stream, This->timer);
-- This->pulse_stream = NULL;
-- EnterCriticalSection(&session_cs);
-+ if (This->stream) {
-+ pthread_mutex_lock(&pulse_lock);
-+ if (PA_STREAM_IS_GOOD(pa_stream_get_state(This->stream))) {
-+ pa_stream_disconnect(This->stream);
-+ while (PA_STREAM_IS_GOOD(pa_stream_get_state(This->stream)))
-+ pthread_cond_wait(&pulse_cond, &pulse_lock);
-+ }
-+ pa_stream_unref(This->stream);
-+ This->stream = NULL;
- list_remove(&This->entry);
-- LeaveCriticalSection(&session_cs);
-+ pthread_mutex_unlock(&pulse_lock);
- }
- IUnknown_Release(This->marshal);
- IMMDevice_Release(This->parent);
-+ HeapFree(GetProcessHeap(), 0, This->tmp_buffer);
-+ HeapFree(GetProcessHeap(), 0, This->peek_buffer);
-+ HeapFree(GetProcessHeap(), 0, This->local_buffer);
- HeapFree(GetProcessHeap(), 0, This);
- }
- return ref;
-@@ -466,6 +1353,32 @@ static WAVEFORMATEX *clone_format(const WAVEFORMATEX *fmt)
- return ret;
- }
-
-+static DWORD get_channel_mask(unsigned int channels)
-+{
-+ switch(channels) {
-+ case 0:
-+ return 0;
-+ case 1:
-+ return KSAUDIO_SPEAKER_MONO;
-+ case 2:
-+ return KSAUDIO_SPEAKER_STEREO;
-+ case 3:
-+ return KSAUDIO_SPEAKER_STEREO | SPEAKER_LOW_FREQUENCY;
-+ case 4:
-+ return KSAUDIO_SPEAKER_QUAD; /* not _SURROUND */
-+ case 5:
-+ return KSAUDIO_SPEAKER_QUAD | SPEAKER_LOW_FREQUENCY;
-+ case 6:
-+ return KSAUDIO_SPEAKER_5POINT1; /* not 5POINT1_SURROUND */
-+ case 7:
-+ return KSAUDIO_SPEAKER_5POINT1 | SPEAKER_BACK_CENTER;
-+ case 8:
-+ return KSAUDIO_SPEAKER_7POINT1_SURROUND; /* Vista deprecates 7POINT1 */
-+ }
-+ FIXME("Unknown speaker configuration: %u\n", channels);
-+ return 0;
-+}
-+
- static void session_init_vols(AudioSession *session, UINT channels)
- {
- if (session->channel_count < channels) {
-@@ -545,24 +1458,127 @@ static HRESULT get_audio_session(const GUID *sessionguid,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
-+static HRESULT pulse_spec_from_waveformat(ACImpl *This, const WAVEFORMATEX *fmt)
-+{
-+ pa_channel_map_init(&This->map);
-+ This->ss.rate = fmt->nSamplesPerSec;
-+ This->ss.format = PA_SAMPLE_INVALID;
-+
-+ switch(fmt->wFormatTag) {
-+ case WAVE_FORMAT_IEEE_FLOAT:
-+ if (!fmt->nChannels || fmt->nChannels > 2 || fmt->wBitsPerSample != 32)
-+ break;
-+ This->ss.format = PA_SAMPLE_FLOAT32LE;
-+ pa_channel_map_init_auto(&This->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
-+ break;
-+ case WAVE_FORMAT_PCM:
-+ if (!fmt->nChannels || fmt->nChannels > 2)
-+ break;
-+ if (fmt->wBitsPerSample == 8)
-+ This->ss.format = PA_SAMPLE_U8;
-+ else if (fmt->wBitsPerSample == 16)
-+ This->ss.format = PA_SAMPLE_S16LE;
-+ else
-+ return AUDCLNT_E_UNSUPPORTED_FORMAT;
-+ pa_channel_map_init_auto(&This->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
-+ break;
-+ case WAVE_FORMAT_EXTENSIBLE: {
-+ WAVEFORMATEXTENSIBLE *wfe = (WAVEFORMATEXTENSIBLE*)fmt;
-+ DWORD mask = wfe->dwChannelMask;
-+ DWORD i = 0, j;
-+ if (fmt->cbSize != (sizeof(*wfe) - sizeof(*fmt)) && fmt->cbSize != sizeof(*wfe))
-+ break;
-+ if (IsEqualGUID(&wfe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) &&
-+ (!wfe->Samples.wValidBitsPerSample || wfe->Samples.wValidBitsPerSample == 32) &&
-+ fmt->wBitsPerSample == 32)
-+ This->ss.format = PA_SAMPLE_FLOAT32LE;
-+ else if (IsEqualGUID(&wfe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) {
-+ DWORD valid = wfe->Samples.wValidBitsPerSample;
-+ if (!valid)
-+ valid = fmt->wBitsPerSample;
-+ if (!valid || valid > fmt->wBitsPerSample)
-+ break;
-+ switch (fmt->wBitsPerSample) {
-+ case 8:
-+ if (valid == 8)
-+ This->ss.format = PA_SAMPLE_U8;
-+ break;
-+ case 16:
-+ if (valid == 16)
-+ This->ss.format = PA_SAMPLE_S16LE;
-+ break;
-+ case 24:
-+ if (valid == 24)
-+ This->ss.format = PA_SAMPLE_S24LE;
-+ break;
-+ case 32:
-+ if (valid == 24)
-+ This->ss.format = PA_SAMPLE_S24_32LE;
-+ else if (valid == 32)
-+ This->ss.format = PA_SAMPLE_S32LE;
-+ break;
-+ default:
-+ return AUDCLNT_E_UNSUPPORTED_FORMAT;
-+ }
-+ }
-+ This->map.channels = fmt->nChannels;
-+ if (!mask || (mask & (SPEAKER_ALL|SPEAKER_RESERVED)))
-+ mask = get_channel_mask(fmt->nChannels);
-+ for (j = 0; j < ARRAY_SIZE(pulse_pos_from_wfx) && i < fmt->nChannels; ++j) {
-+ if (mask & (1 << j))
-+ This->map.map[i++] = pulse_pos_from_wfx[j];
-+ }
-+
-+ /* Special case for mono since pulse appears to map it differently */
-+ if (mask == SPEAKER_FRONT_CENTER)
-+ This->map.map[0] = PA_CHANNEL_POSITION_MONO;
-+
-+ if (i < fmt->nChannels || (mask & SPEAKER_RESERVED)) {
-+ This->map.channels = 0;
-+ ERR("Invalid channel mask: %i/%i and %x(%x)\n", i, fmt->nChannels, mask, wfe->dwChannelMask);
-+ break;
-+ }
-+ break;
-+ }
-+ case WAVE_FORMAT_ALAW:
-+ case WAVE_FORMAT_MULAW:
-+ if (fmt->wBitsPerSample != 8) {
-+ FIXME("Unsupported bpp %u for LAW\n", fmt->wBitsPerSample);
-+ return AUDCLNT_E_UNSUPPORTED_FORMAT;
-+ }
-+ if (fmt->nChannels != 1 && fmt->nChannels != 2) {
-+ FIXME("Unsupported channels %u for LAW\n", fmt->nChannels);
-+ return AUDCLNT_E_UNSUPPORTED_FORMAT;
-+ }
-+ This->ss.format = fmt->wFormatTag == WAVE_FORMAT_MULAW ? PA_SAMPLE_ULAW : PA_SAMPLE_ALAW;
-+ pa_channel_map_init_auto(&This->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
-+ break;
-+ default:
-+ WARN("Unhandled tag %x\n", fmt->wFormatTag);
-+ return AUDCLNT_E_UNSUPPORTED_FORMAT;
-+ }
-+ This->ss.channels = This->map.channels;
-+ if (!pa_channel_map_valid(&This->map) || This->ss.format == PA_SAMPLE_INVALID) {
-+ ERR("Invalid format! Channel spec valid: %i, format: %i\n", pa_channel_map_valid(&This->map), This->ss.format);
-+ return AUDCLNT_E_UNSUPPORTED_FORMAT;
-+ }
-+ return S_OK;
-+}
-+
-+static HRESULT WINAPI AudioClient_Initialize(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration,
- REFERENCE_TIME period, const WAVEFORMATEX *fmt,
- const GUID *sessionguid)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- struct create_stream_params params;
-- unsigned int i, channel_count;
-- struct pulse_stream *stream;
-- char *name;
-- HRESULT hr;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ HRESULT hr = S_OK;
-+ UINT period_bytes;
-
- TRACE("(%p)->(%x, %x, %s, %s, %p, %s)\n", This, mode, flags,
- wine_dbgstr_longlong(duration), wine_dbgstr_longlong(period), fmt, debugstr_guid(sessionguid));
-
- if (!fmt)
- return E_POINTER;
-- dump_fmt(fmt);
-
- if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE)
- return E_INVALIDARG;
-@@ -583,134 +1599,223 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
- return E_INVALIDARG;
- }
-
-- EnterCriticalSection(&session_cs);
-+ pthread_mutex_lock(&pulse_lock);
-
-- if (This->pulse_stream) {
-- LeaveCriticalSection(&session_cs);
-- return AUDCLNT_E_ALREADY_INITIALIZED;
-- }
--
-- if (!pulse_thread)
-- {
-- HANDLE event = CreateEventW(NULL, TRUE, FALSE, NULL);
-- if (!(pulse_thread = CreateThread(NULL, 0, pulse_mainloop_thread, event, 0, NULL)))
-- {
-- ERR("Failed to create mainloop thread.\n");
-- LeaveCriticalSection(&session_cs);
-- CloseHandle(event);
-- return E_FAIL;
-- }
-- SetThreadPriority(pulse_thread, THREAD_PRIORITY_TIME_CRITICAL);
-- WaitForSingleObject(event, INFINITE);
-- CloseHandle(event);
-- }
--
-- params.name = name = get_application_name();
-- params.dataflow = This->dataflow;
-- params.mode = mode;
-- params.flags = flags;
-- params.duration = duration;
-- params.fmt = fmt;
-- params.stream = &stream;
-- params.channel_count = &channel_count;
-- pulse_call(create_stream, ¶ms);
-- free(name);
-- if (FAILED(hr = params.result))
-- {
-- LeaveCriticalSection(&session_cs);
-+ hr = pulse_connect();
-+ if (FAILED(hr)) {
-+ pthread_mutex_unlock(&pulse_lock);
- return hr;
- }
-
-- if (!(This->vol = malloc(channel_count * sizeof(*This->vol))))
-- {
-- pulse_release_stream(stream, NULL);
-- LeaveCriticalSection(&session_cs);
-- return E_OUTOFMEMORY;
-+ if (This->stream) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return AUDCLNT_E_ALREADY_INITIALIZED;
- }
-- for (i = 0; i < channel_count; i++)
-- This->vol[i] = 1.f;
-
-- hr = get_audio_session(sessionguid, This->parent, channel_count, &This->session);
-+ hr = pulse_spec_from_waveformat(This, fmt);
-+ TRACE("Obtaining format returns %08x\n", hr);
-+ dump_fmt(fmt);
-+
- if (FAILED(hr))
-- {
-- free(This->vol);
-- This->vol = NULL;
-- LeaveCriticalSection(&session_cs);
-- pulse_release_stream(stream, NULL);
-- return E_OUTOFMEMORY;
-- }
-+ goto exit;
-
-- This->pulse_stream = stream;
-- This->channel_count = channel_count;
-- list_add_tail(&This->session->clients, &This->entry);
-- set_stream_volumes(This);
-+ if (mode == AUDCLNT_SHAREMODE_SHARED) {
-+ REFERENCE_TIME def = pulse_def_period[This->dataflow == eCapture];
-+ REFERENCE_TIME min = pulse_min_period[This->dataflow == eCapture];
-
-- LeaveCriticalSection(&session_cs);
-- return S_OK;
-+ /* Switch to low latency mode if below 2 default periods,
-+ * which is 20 ms by default, this will increase the amount
-+ * of interrupts but allows very low latency. In dsound I
-+ * managed to get a total latency of ~8ms, which is well below
-+ * default
-+ */
-+ if (duration < 2 * def)
-+ period = min;
-+ else
-+ period = def;
-+ if (duration < 2 * period)
-+ duration = 2 * period;
-+
-+ /* Uh oh, really low latency requested.. */
-+ if (duration <= 2 * period)
-+ period /= 2;
-+ }
-+ period_bytes = pa_frame_size(&This->ss) * MulDiv(period, This->ss.rate, 10000000);
-+
-+ if (duration < 20000000)
-+ This->bufsize_frames = ceil((duration / 10000000.) * fmt->nSamplesPerSec);
-+ else
-+ This->bufsize_frames = 2 * fmt->nSamplesPerSec;
-+ This->bufsize_bytes = This->bufsize_frames * pa_frame_size(&This->ss);
-+
-+ This->share = mode;
-+ This->flags = flags;
-+ hr = pulse_stream_connect(This, period_bytes);
-+ if (SUCCEEDED(hr)) {
-+ UINT32 unalign;
-+ const pa_buffer_attr *attr = pa_stream_get_buffer_attr(This->stream);
-+ This->attr = *attr;
-+ /* Update frames according to new size */
-+ dump_attr(attr);
-+ if (This->dataflow == eRender) {
-+ if (attr->tlength < This->bufsize_bytes) {
-+ TRACE("PulseAudio buffer too small (%u < %u), using tmp buffer\n", attr->tlength, This->bufsize_bytes);
-+
-+ This->local_buffer = HeapAlloc(GetProcessHeap(), 0, This->bufsize_bytes);
-+ if(!This->local_buffer)
-+ hr = E_OUTOFMEMORY;
-+ }
-+ } else {
-+ UINT32 i, capture_packets;
-+
-+ This->capture_period = period_bytes = attr->fragsize;
-+ if ((unalign = This->bufsize_bytes % period_bytes))
-+ This->bufsize_bytes += period_bytes - unalign;
-+ This->bufsize_frames = This->bufsize_bytes / pa_frame_size(&This->ss);
-+
-+ capture_packets = This->bufsize_bytes / This->capture_period;
-+
-+ This->local_buffer = HeapAlloc(GetProcessHeap(), 0, This->bufsize_bytes + capture_packets * sizeof(ACPacket));
-+ if (!This->local_buffer)
-+ hr = E_OUTOFMEMORY;
-+ else {
-+ ACPacket *cur_packet = (ACPacket*)((char*)This->local_buffer + This->bufsize_bytes);
-+ BYTE *data = This->local_buffer;
-+ silence_buffer(This->ss.format, This->local_buffer, This->bufsize_bytes);
-+ list_init(&This->packet_free_head);
-+ list_init(&This->packet_filled_head);
-+ for (i = 0; i < capture_packets; ++i, ++cur_packet) {
-+ list_add_tail(&This->packet_free_head, &cur_packet->entry);
-+ cur_packet->data = data;
-+ data += This->capture_period;
-+ }
-+ assert(!This->capture_period || This->bufsize_bytes == This->capture_period * capture_packets);
-+ assert(!capture_packets || data - This->bufsize_bytes == This->local_buffer);
-+ }
-+ }
-+ }
-+ if (SUCCEEDED(hr))
-+ hr = get_audio_session(sessionguid, This->parent, fmt->nChannels, &This->session);
-+ if (SUCCEEDED(hr))
-+ list_add_tail(&This->session->clients, &This->entry);
-+
-+exit:
-+ if (FAILED(hr)) {
-+ HeapFree(GetProcessHeap(), 0, This->local_buffer);
-+ This->local_buffer = NULL;
-+ if (This->stream) {
-+ pa_stream_disconnect(This->stream);
-+ pa_stream_unref(This->stream);
-+ This->stream = NULL;
-+ }
-+ }
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient2 *iface,
- UINT32 *out)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- struct get_buffer_size_params params;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ HRESULT hr;
-
- TRACE("(%p)->(%p)\n", This, out);
-
- if (!out)
- return E_POINTER;
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-
-- params.stream = This->pulse_stream;
-- params.size = out;
-- pulse_call(get_buffer_size, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (SUCCEEDED(hr))
-+ *out = This->bufsize_frames;
-+ pthread_mutex_unlock(&pulse_lock);
-+
-+ return hr;
- }
-
--static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient2 *iface,
- REFERENCE_TIME *latency)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- struct get_latency_params params;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ const pa_buffer_attr *attr;
-+ REFERENCE_TIME lat;
-+ HRESULT hr;
-
- TRACE("(%p)->(%p)\n", This, latency);
-
- if (!latency)
- return E_POINTER;
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-
-- params.stream = This->pulse_stream;
-- params.latency = latency;
-- pulse_call(get_latency, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr)) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
-+ }
-+ attr = pa_stream_get_buffer_attr(This->stream);
-+ if (This->dataflow == eRender){
-+ lat = attr->minreq / pa_frame_size(&This->ss);
-+ lat += pulse_def_period[0];
-+ }else
-+ lat = attr->fragsize / pa_frame_size(&This->ss);
-+ *latency = 10000000;
-+ *latency *= lat;
-+ *latency /= This->ss.rate;
-+ pthread_mutex_unlock(&pulse_lock);
-+ TRACE("Latency: %u ms\n", (DWORD)(*latency / 10000));
-+ return S_OK;
-+}
-+
-+static void ACImpl_GetRenderPad(ACImpl *This, UINT32 *out)
-+{
-+ *out = This->pad / pa_frame_size(&This->ss);
-+}
-+
-+static void ACImpl_GetCapturePad(ACImpl *This, UINT32 *out)
-+{
-+ ACPacket *packet = This->locked_ptr;
-+ if (!packet && !list_empty(&This->packet_filled_head)) {
-+ packet = (ACPacket*)list_head(&This->packet_filled_head);
-+ This->locked_ptr = packet;
-+ list_remove(&packet->entry);
-+ }
-+ if (out)
-+ *out = This->pad / pa_frame_size(&This->ss);
- }
-
--static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient2 *iface,
- UINT32 *out)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- struct get_current_padding_params params;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ HRESULT hr;
-
- TRACE("(%p)->(%p)\n", This, out);
-
- if (!out)
- return E_POINTER;
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-
-- params.stream = This->pulse_stream;
-- params.padding = out;
-- pulse_call(get_current_padding, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr)) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
-+ }
-+
-+ if (This->dataflow == eRender)
-+ ACImpl_GetRenderPad(This, out);
-+ else
-+ ACImpl_GetCapturePad(This, out);
-+ pthread_mutex_unlock(&pulse_lock);
-+
-+ TRACE("%p Pad: %u ms (%u)\n", This, MulDiv(*out, 1000, This->ss.rate), *out);
-+ return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient2 *iface,
- AUDCLNT_SHAREMODE mode, const WAVEFORMATEX *fmt,
- WAVEFORMATEX **out)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
- HRESULT hr = S_OK;
- WAVEFORMATEX *closest = NULL;
- BOOL exclusive;
-@@ -859,27 +1964,28 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface,
- return hr;
- }
-
--static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient2 *iface,
- WAVEFORMATEX **pwfx)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ WAVEFORMATEXTENSIBLE *fmt = &pulse_fmt[This->dataflow == eCapture];
-
- TRACE("(%p)->(%p)\n", This, pwfx);
-
- if (!pwfx)
- return E_POINTER;
-
-- *pwfx = clone_format(&pulse_config.modes[This->dataflow == eCapture].format.Format);
-+ *pwfx = clone_format(&fmt->Format);
- if (!*pwfx)
- return E_OUTOFMEMORY;
- dump_fmt(*pwfx);
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient2 *iface,
- REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p, %p)\n", This, defperiod, minperiod);
-
-@@ -887,90 +1993,187 @@ static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
- return E_POINTER;
-
- if (defperiod)
-- *defperiod = pulse_config.modes[This->dataflow == eCapture].def_period;
-+ *defperiod = pulse_def_period[This->dataflow == eCapture];
- if (minperiod)
-- *minperiod = pulse_config.modes[This->dataflow == eCapture].min_period;
-+ *minperiod = pulse_min_period[This->dataflow == eCapture];
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Start(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- struct start_params params;
-- HRESULT hr;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ HRESULT hr = S_OK;
-+ int success;
-+ pa_operation *o;
-
- TRACE("(%p)\n", This);
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
--
-- params.stream = This->pulse_stream;
-- pulse_call(start, ¶ms);
-- if (FAILED(hr = params.result))
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr)) {
-+ pthread_mutex_unlock(&pulse_lock);
- return hr;
-+ }
-
-- if (!This->timer) {
-- This->timer = CreateThread(NULL, 0, pulse_timer_cb, This, 0, NULL);
-- SetThreadPriority(This->timer, THREAD_PRIORITY_TIME_CRITICAL);
-+ if ((This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) && !This->event) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return AUDCLNT_E_EVENTHANDLE_NOT_SET;
- }
-
-- return S_OK;
-+ if (This->started) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return AUDCLNT_E_NOT_STOPPED;
-+ }
-+
-+ if (pa_stream_is_corked(This->stream)) {
-+ o = pa_stream_cork(This->stream, 0, pulse_op_cb, &success);
-+ if (o) {
-+ while(pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-+ pthread_cond_wait(&pulse_cond, &pulse_lock);
-+ pa_operation_unref(o);
-+ } else
-+ success = 0;
-+ if (!success)
-+ hr = E_FAIL;
-+ }
-+
-+ if (SUCCEEDED(hr)) {
-+ This->started = TRUE;
-+ if (This->dataflow == eRender && This->event)
-+ pa_stream_set_latency_update_callback(This->stream, pulse_latency_callback, This);
-+ }
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
- }
-
--static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Stop(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- struct stop_params params;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ HRESULT hr = S_OK;
-+ pa_operation *o;
-+ int success;
-
- TRACE("(%p)\n", This);
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr)) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
-+ }
-+
-+ if (!This->started) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return S_FALSE;
-+ }
-
-- params.stream = This->pulse_stream;
-- pulse_call(stop, ¶ms);
-- return params.result;
-+ if (This->dataflow == eRender) {
-+ o = pa_stream_cork(This->stream, 1, pulse_op_cb, &success);
-+ if (o) {
-+ while(pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-+ pthread_cond_wait(&pulse_cond, &pulse_lock);
-+ pa_operation_unref(o);
-+ } else
-+ success = 0;
-+ if (!success)
-+ hr = E_FAIL;
-+ }
-+ if (SUCCEEDED(hr)) {
-+ This->started = FALSE;
-+ }
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
- }
-
--static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
-+static HRESULT WINAPI AudioClient_Reset(IAudioClient2 *iface)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- struct reset_params params;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ HRESULT hr = S_OK;
-
- TRACE("(%p)\n", This);
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr)) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
-+ }
-+
-+ if (This->started) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return AUDCLNT_E_NOT_STOPPED;
-+ }
-+
-+ if (This->locked) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return AUDCLNT_E_BUFFER_OPERATION_PENDING;
-+ }
-+
-+ if (This->dataflow == eRender) {
-+ /* If there is still data in the render buffer it needs to be removed from the server */
-+ int success = 0;
-+ if (This->pad) {
-+ pa_operation *o = pa_stream_flush(This->stream, pulse_op_cb, &success);
-+ if (o) {
-+ while(pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-+ pthread_cond_wait(&pulse_cond, &pulse_lock);
-+ pa_operation_unref(o);
-+ }
-+ }
-+ if (success || !This->pad){
-+ This->clock_lastpos = This->clock_written = This->pad = 0;
-+ This->wri_offs_bytes = This->lcl_offs_bytes = This->held_bytes = 0;
-+ }
-+ } else {
-+ ACPacket *p;
-+ This->clock_written += This->pad;
-+ This->pad = 0;
-+
-+ if ((p = This->locked_ptr)) {
-+ This->locked_ptr = NULL;
-+ list_add_tail(&This->packet_free_head, &p->entry);
-+ }
-+ list_move_tail(&This->packet_free_head, &This->packet_filled_head);
-+ }
-+ pthread_mutex_unlock(&pulse_lock);
-
-- params.stream = This->pulse_stream;
-- pulse_call(reset, ¶ms);
-- return params.result;
-+ return hr;
- }
-
--static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient2 *iface,
- HANDLE event)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- struct set_event_handle_params params;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ HRESULT hr;
-
- TRACE("(%p)->(%p)\n", This, event);
-
- if (!event)
- return E_INVALIDARG;
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-
-- params.stream = This->pulse_stream;
-- params.event = event;
-- pulse_call(set_event_handle, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr)) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
-+ }
-+
-+ if (!(This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK))
-+ hr = AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED;
-+ else if (This->event)
-+ hr = HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
-+ else
-+ This->event = event;
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
- }
-
--static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
-+static HRESULT WINAPI AudioClient_GetService(IAudioClient2 *iface, REFIID riid,
- void **ppv)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-+ HRESULT hr;
-
- TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
-
-@@ -978,8 +2181,11 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
- return E_POINTER;
- *ppv = NULL;
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ pthread_mutex_unlock(&pulse_lock);
-+ if (FAILED(hr))
-+ return hr;
-
- if (IsEqualIID(riid, &IID_IAudioRenderClient)) {
- if (This->dataflow != eRender)
-@@ -1018,10 +2224,10 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
- return E_NOINTERFACE;
- }
-
--static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient2 *iface,
- AUDIO_STREAM_CATEGORY category, BOOL *offload_capable)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(0x%x, %p)\n", This, category, offload_capable);
-
-@@ -1033,83 +2239,42 @@ static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient2 *iface,
- const AudioClientProperties *prop)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-- const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop;
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- TRACE("(%p)->(%p)\n", This, prop);
-
-- if(!legacy_prop)
-+ if(!prop)
- return E_POINTER;
-
-- if(legacy_prop->cbSize == sizeof(AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory,
-- prop->Options);
-- }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){
-- TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n",
-- legacy_prop->bIsOffload,
-- legacy_prop->eCategory);
-- }else{
-- WARN("Unsupported Size = %d\n", legacy_prop->cbSize);
-+ if(prop->cbSize != sizeof(*prop))
- return E_INVALIDARG;
-- }
-
-+ TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n",
-+ prop->bIsOffload,
-+ prop->eCategory,
-+ prop->Options);
-
-- if(legacy_prop->bIsOffload)
-+ if(prop->bIsOffload)
- return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE;
-
- return S_OK;
- }
-
--static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient3 *iface,
-+static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient2 *iface,
- const WAVEFORMATEX *format, BOOL event_driven, REFERENCE_TIME *min_duration,
- REFERENCE_TIME *max_duration)
- {
-- ACImpl *This = impl_from_IAudioClient3(iface);
-+ ACImpl *This = impl_from_IAudioClient2(iface);
-
- FIXME("(%p)->(%p, %u, %p, %p)\n", This, format, event_driven, min_duration, max_duration);
-
- return E_NOTIMPL;
- }
-
--static HRESULT WINAPI AudioClient_GetSharedModeEnginePeriod(IAudioClient3 *iface,
-- const WAVEFORMATEX *format, UINT32 *default_period_frames, UINT32 *unit_period_frames,
-- UINT32 *min_period_frames, UINT32 *max_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p, %p, %p, %p)\n", This, format, default_period_frames, unit_period_frames,
-- min_period_frames, max_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface,
-- WAVEFORMATEX **cur_format, UINT32 *cur_period_frames)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(%p, %p)\n", This, cur_format, cur_period_frames);
--
-- return E_NOTIMPL;
--}
--
--static HRESULT WINAPI AudioClient_InitializeSharedAudioStream(IAudioClient3 *iface,
-- DWORD flags, UINT32 period_frames, const WAVEFORMATEX *format,
-- const GUID *session_guid)
--{
-- ACImpl *This = impl_from_IAudioClient3(iface);
--
-- FIXME("(%p)->(0x%x, %u, %p, %s)\n", This, flags, period_frames, format, debugstr_guid(session_guid));
--
-- return E_NOTIMPL;
--}
--
--static const IAudioClient3Vtbl AudioClient3_Vtbl =
-+static const IAudioClient2Vtbl AudioClient2_Vtbl =
- {
- AudioClient_QueryInterface,
- AudioClient_AddRef,
-@@ -1129,9 +2294,6 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl =
- AudioClient_IsOffloadCapable,
- AudioClient_SetClientProperties,
- AudioClient_GetBufferSizeLimits,
-- AudioClient_GetSharedModeEnginePeriod,
-- AudioClient_GetCurrentSharedModeEnginePeriod,
-- AudioClient_InitializeSharedAudioStream,
- };
-
- static HRESULT WINAPI AudioRenderClient_QueryInterface(
-@@ -1162,52 +2324,192 @@ static HRESULT WINAPI AudioRenderClient_QueryInterface(
- static ULONG WINAPI AudioRenderClient_AddRef(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_AddRef(&This->IAudioClient3_iface);
-+ return AudioClient_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioRenderClient_Release(IAudioRenderClient *iface)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- return AudioClient_Release(&This->IAudioClient3_iface);
-+ return AudioClient_Release(&This->IAudioClient2_iface);
-+}
-+
-+static void alloc_tmp_buffer(ACImpl *This, UINT32 bytes)
-+{
-+ if(This->tmp_buffer_bytes >= bytes)
-+ return;
-+
-+ HeapFree(GetProcessHeap(), 0, This->tmp_buffer);
-+ This->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, bytes);
-+ This->tmp_buffer_bytes = bytes;
- }
-
- static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
- UINT32 frames, BYTE **data)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- struct get_render_buffer_params params;
-+ size_t avail, req, bytes = frames * pa_frame_size(&This->ss);
-+ UINT32 pad;
-+ HRESULT hr = S_OK;
-+ int ret = -1;
-
- TRACE("(%p)->(%u, %p)\n", This, frames, data);
-
- if (!data)
- return E_POINTER;
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
- *data = NULL;
-
-- params.stream = This->pulse_stream;
-- params.frames = frames;
-- params.data = data;
-- pulse_call(get_render_buffer, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr) || This->locked) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return FAILED(hr) ? hr : AUDCLNT_E_OUT_OF_ORDER;
-+ }
-+ if (!frames) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return S_OK;
-+ }
-+
-+ ACImpl_GetRenderPad(This, &pad);
-+ avail = This->bufsize_frames - pad;
-+ if (avail < frames || bytes > This->bufsize_bytes) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ WARN("Wanted to write %u, but only %zu available\n", frames, avail);
-+ return AUDCLNT_E_BUFFER_TOO_LARGE;
-+ }
-+
-+ if(This->local_buffer){
-+ if(This->wri_offs_bytes + bytes > This->bufsize_bytes){
-+ alloc_tmp_buffer(This, bytes);
-+ *data = This->tmp_buffer;
-+ This->locked = -frames;
-+ }else{
-+ *data = This->local_buffer + This->wri_offs_bytes;
-+ This->locked = frames;
-+ }
-+ }else{
-+ req = bytes;
-+ ret = pa_stream_begin_write(This->stream, &This->locked_ptr, &req);
-+ if (ret < 0 || req < bytes) {
-+ FIXME("%p Not using pulse locked data: %i %zu/%u %u/%u\n", This, ret, req/pa_frame_size(&This->ss), frames, pad, This->bufsize_frames);
-+ if (ret >= 0)
-+ pa_stream_cancel_write(This->stream);
-+ alloc_tmp_buffer(This, bytes);
-+ *data = This->tmp_buffer;
-+ This->locked_ptr = NULL;
-+ } else
-+ *data = This->locked_ptr;
-+
-+ This->locked = frames;
-+ }
-+
-+ silence_buffer(This->ss.format, *data, bytes);
-+
-+ pthread_mutex_unlock(&pulse_lock);
-+
-+ return hr;
-+}
-+
-+static void pulse_wrap_buffer(ACImpl *This, BYTE *buffer, UINT32 written_bytes)
-+{
-+ UINT32 chunk_bytes = This->bufsize_bytes - This->wri_offs_bytes;
-+
-+ if(written_bytes <= chunk_bytes){
-+ memcpy(This->local_buffer + This->wri_offs_bytes, buffer, written_bytes);
-+ }else{
-+ memcpy(This->local_buffer + This->wri_offs_bytes, buffer, chunk_bytes);
-+ memcpy(This->local_buffer, buffer + chunk_bytes,
-+ written_bytes - chunk_bytes);
-+ }
- }
-
- static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
- IAudioRenderClient *iface, UINT32 written_frames, DWORD flags)
- {
- ACImpl *This = impl_from_IAudioRenderClient(iface);
-- struct release_render_buffer_params params;
-+ UINT32 written_bytes = written_frames * pa_frame_size(&This->ss);
-
- TRACE("(%p)->(%u, %x)\n", This, written_frames, flags);
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-+ pthread_mutex_lock(&pulse_lock);
-+ if (!This->locked || !written_frames) {
-+ if (This->locked_ptr)
-+ pa_stream_cancel_write(This->stream);
-+ This->locked = 0;
-+ This->locked_ptr = NULL;
-+ pthread_mutex_unlock(&pulse_lock);
-+ return written_frames ? AUDCLNT_E_OUT_OF_ORDER : S_OK;
-+ }
-+
-+ if (This->locked < written_frames) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return AUDCLNT_E_INVALID_SIZE;
-+ }
-+
-+ if(This->local_buffer){
-+ BYTE *buffer;
-+
-+ if(This->locked >= 0)
-+ buffer = This->local_buffer + This->wri_offs_bytes;
-+ else
-+ buffer = This->tmp_buffer;
-+
-+ if(flags & AUDCLNT_BUFFERFLAGS_SILENT)
-+ silence_buffer(This->ss.format, buffer, written_bytes);
-+
-+ if(This->locked < 0)
-+ pulse_wrap_buffer(This, buffer, written_bytes);
-+
-+ This->wri_offs_bytes += written_bytes;
-+ This->wri_offs_bytes %= This->bufsize_bytes;
-+
-+ This->pad += written_bytes;
-+ This->held_bytes += written_bytes;
-+
-+ if(This->held_bytes == This->pad){
-+ int e;
-+ UINT32 to_write = min(This->attr.tlength, written_bytes);
-+
-+ /* nothing in PA, so send data immediately */
-+
-+ TRACE("pre-writing %u bytes\n", to_write);
-+
-+ e = write_buffer(This, buffer, to_write, 0);
-+ if(e)
-+ ERR("pa_stream_write failed: 0x%x\n", e);
-+
-+ This->lcl_offs_bytes += to_write;
-+ This->lcl_offs_bytes %= This->bufsize_bytes;
-+ This->held_bytes -= to_write;
-+ }
-+
-+ }else{
-+ enum write_buffer_flags wr_flags = 0;
-+
-+ if (flags & AUDCLNT_BUFFERFLAGS_SILENT) wr_flags |= WINEPULSE_WRITE_SILENT;
-+ if (!This->locked_ptr) wr_flags |= WINEPULSE_WRITE_NOFREE;
-+
-+ write_buffer(This, This->locked_ptr ? This->locked_ptr : This->tmp_buffer, written_bytes, wr_flags);
-+ This->pad += written_bytes;
-+ }
-
-- params.stream = This->pulse_stream;
-- params.written_frames = written_frames;
-- params.flags = flags;
-- pulse_call(release_render_buffer, ¶ms);
-- return params.result;
-+ if (!pa_stream_is_corked(This->stream)) {
-+ int success;
-+ pa_operation *o;
-+ o = pa_stream_trigger(This->stream, pulse_op_cb, &success);
-+ if (o) {
-+ while(pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-+ pthread_cond_wait(&pulse_cond, &pulse_lock);
-+ pa_operation_unref(o);
-+ }
-+ }
-+
-+ This->locked = 0;
-+ This->locked_ptr = NULL;
-+ TRACE("Released %u, pad %zu\n", written_frames, This->pad / pa_frame_size(&This->ss));
-+ assert(This->pad <= This->bufsize_bytes);
-+
-+ pthread_mutex_unlock(&pulse_lock);
-+ return S_OK;
- }
-
- static const IAudioRenderClientVtbl AudioRenderClient_Vtbl = {
-@@ -1246,13 +2548,13 @@ static HRESULT WINAPI AudioCaptureClient_QueryInterface(
- static ULONG WINAPI AudioCaptureClient_AddRef(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioCaptureClient_Release(IAudioCaptureClient *iface)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
-@@ -1260,63 +2562,98 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
- UINT64 *qpcpos)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- struct get_capture_buffer_params params;
-+ HRESULT hr;
-+ ACPacket *packet;
-
- TRACE("(%p)->(%p, %p, %p, %p, %p)\n", This, data, frames, flags,
- devpos, qpcpos);
-
- if (!data)
- return E_POINTER;
-+
- *data = NULL;
-+
- if (!frames || !flags)
- return E_POINTER;
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-
-- params.stream = This->pulse_stream;
-- params.data = data;
-- params.frames = frames;
-- params.flags = flags;
-- params.devpos = devpos;
-- params.qpcpos = qpcpos;
-- pulse_call(get_capture_buffer, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr) || This->locked) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return FAILED(hr) ? hr : AUDCLNT_E_OUT_OF_ORDER;
-+ }
-+
-+ ACImpl_GetCapturePad(This, NULL);
-+ if ((packet = This->locked_ptr)) {
-+ *frames = This->capture_period / pa_frame_size(&This->ss);
-+ *flags = 0;
-+ if (packet->discont)
-+ *flags |= AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY;
-+ if (devpos) {
-+ if (packet->discont)
-+ *devpos = (This->clock_written + This->capture_period) / pa_frame_size(&This->ss);
-+ else
-+ *devpos = This->clock_written / pa_frame_size(&This->ss);
-+ }
-+ if (qpcpos)
-+ *qpcpos = packet->qpcpos;
-+ *data = packet->data;
-+ }
-+ else
-+ *frames = 0;
-+ This->locked = *frames;
-+ pthread_mutex_unlock(&pulse_lock);
-+ return *frames ? S_OK : AUDCLNT_S_BUFFER_EMPTY;
- }
-
- static HRESULT WINAPI AudioCaptureClient_ReleaseBuffer(
- IAudioCaptureClient *iface, UINT32 done)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- struct release_capture_buffer_params params;
-
- TRACE("(%p)->(%u)\n", This, done);
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
--
-- params.stream = This->pulse_stream;
-- params.done = done;
-- pulse_call(release_capture_buffer, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ if (!This->locked && done) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return AUDCLNT_E_OUT_OF_ORDER;
-+ }
-+ if (done && This->locked != done) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return AUDCLNT_E_INVALID_SIZE;
-+ }
-+ if (done) {
-+ ACPacket *packet = This->locked_ptr;
-+ This->locked_ptr = NULL;
-+ This->pad -= This->capture_period;
-+ if (packet->discont)
-+ This->clock_written += 2 * This->capture_period;
-+ else
-+ This->clock_written += This->capture_period;
-+ list_add_tail(&This->packet_free_head, &packet->entry);
-+ }
-+ This->locked = 0;
-+ pthread_mutex_unlock(&pulse_lock);
-+ return S_OK;
- }
-
- static HRESULT WINAPI AudioCaptureClient_GetNextPacketSize(
- IAudioCaptureClient *iface, UINT32 *frames)
- {
- ACImpl *This = impl_from_IAudioCaptureClient(iface);
-- struct get_next_packet_size_params params;
-
- TRACE("(%p)->(%p)\n", This, frames);
--
- if (!frames)
- return E_POINTER;
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-
-- params.stream = This->pulse_stream;
-- params.frames = frames;
-- pulse_call(get_next_packet_size, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ ACImpl_GetCapturePad(This, NULL);
-+ if (This->locked_ptr)
-+ *frames = This->capture_period / pa_frame_size(&This->ss);
-+ else
-+ *frames = 0;
-+ pthread_mutex_unlock(&pulse_lock);
-+ return S_OK;
- }
-
- static const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl =
-@@ -1359,50 +2696,73 @@ static HRESULT WINAPI AudioClock_QueryInterface(IAudioClock *iface,
- static ULONG WINAPI AudioClock_AddRef(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock_Release(IAudioClock *iface)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock_GetFrequency(IAudioClock *iface, UINT64 *freq)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- struct get_frequency_params params;
-+ HRESULT hr;
-
- TRACE("(%p)->(%p)\n", This, freq);
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
--
-- params.stream = This->pulse_stream;
-- params.freq = freq;
-- pulse_call(get_frequency, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (SUCCEEDED(hr)) {
-+ *freq = This->ss.rate;
-+ if (This->share == AUDCLNT_SHAREMODE_SHARED)
-+ *freq *= pa_frame_size(&This->ss);
-+ }
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
- }
-
- static HRESULT WINAPI AudioClock_GetPosition(IAudioClock *iface, UINT64 *pos,
- UINT64 *qpctime)
- {
- ACImpl *This = impl_from_IAudioClock(iface);
-- struct get_position_params params;
-+ HRESULT hr;
-
- TRACE("(%p)->(%p, %p)\n", This, pos, qpctime);
-
- if (!pos)
- return E_POINTER;
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-
-- params.stream = This->pulse_stream;
-- params.device = FALSE;
-- params.pos = pos;
-- params.qpctime = qpctime;
-- pulse_call(get_position, ¶ms);
-- return params.result;
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr)) {
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
-+ }
-+
-+ *pos = This->clock_written;
-+
-+ if (This->share == AUDCLNT_SHAREMODE_EXCLUSIVE)
-+ *pos /= pa_frame_size(&This->ss);
-+
-+ /* Make time never go backwards */
-+ if (*pos < This->clock_lastpos)
-+ *pos = This->clock_lastpos;
-+ else
-+ This->clock_lastpos = *pos;
-+ pthread_mutex_unlock(&pulse_lock);
-+
-+ TRACE("%p Position: %u\n", This, (unsigned)*pos);
-+
-+ if (qpctime) {
-+ LARGE_INTEGER stamp, freq;
-+ QueryPerformanceCounter(&stamp);
-+ QueryPerformanceFrequency(&freq);
-+ *qpctime = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
-+ }
-+
-+ return S_OK;
- }
-
- static HRESULT WINAPI AudioClock_GetCharacteristics(IAudioClock *iface,
-@@ -1440,34 +2800,23 @@ static HRESULT WINAPI AudioClock2_QueryInterface(IAudioClock2 *iface,
- static ULONG WINAPI AudioClock2_AddRef(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioClock2_Release(IAudioClock2 *iface)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioClock2_GetDevicePosition(IAudioClock2 *iface,
- UINT64 *pos, UINT64 *qpctime)
- {
- ACImpl *This = impl_from_IAudioClock2(iface);
-- struct get_position_params params;
--
-- TRACE("(%p)->(%p, %p)\n", This, pos, qpctime);
--
-- if (!pos)
-- return E_POINTER;
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
--
-- params.stream = This->pulse_stream;
-- params.device = TRUE;
-- params.pos = pos;
-- params.qpctime = qpctime;
-- pulse_call(get_position, ¶ms);
-- return params.result;
-+ HRESULT hr = AudioClock_GetPosition(&This->IAudioClock_iface, pos, qpctime);
-+ if (SUCCEEDED(hr) && This->share == AUDCLNT_SHAREMODE_SHARED)
-+ *pos /= pa_frame_size(&This->ss);
-+ return hr;
- }
-
- static const IAudioClock2Vtbl AudioClock2_Vtbl =
-@@ -1507,13 +2856,13 @@ static HRESULT WINAPI AudioStreamVolume_QueryInterface(
- static ULONG WINAPI AudioStreamVolume_AddRef(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_AddRef(&This->IAudioClient3_iface);
-+ return IAudioClient2_AddRef(&This->IAudioClient2_iface);
- }
-
- static ULONG WINAPI AudioStreamVolume_Release(IAudioStreamVolume *iface)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-- return IAudioClient3_Release(&This->IAudioClient3_iface);
-+ return IAudioClient2_Release(&This->IAudioClient2_iface);
- }
-
- static HRESULT WINAPI AudioStreamVolume_GetChannelCount(
-@@ -1526,7 +2875,7 @@ static HRESULT WINAPI AudioStreamVolume_GetChannelCount(
- if (!out)
- return E_POINTER;
-
-- *out = This->channel_count;
-+ *out = This->ss.channels;
-
- return S_OK;
- }
-@@ -1540,6 +2889,7 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
- IAudioStreamVolume *iface, UINT32 count, const float *levels)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-+ HRESULT hr;
- int i;
-
- TRACE("(%p)->(%d, %p)\n", This, count, levels);
-@@ -1547,24 +2897,27 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
- if (!levels)
- return E_POINTER;
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-- if (count != This->channel_count)
-+ if (count != This->ss.channels)
- return E_INVALIDARG;
-
-- EnterCriticalSection(&session_cs);
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr))
-+ goto out;
-+
- for (i = 0; i < count; ++i)
- This->vol[i] = levels[i];
-
-- set_stream_volumes(This);
-- LeaveCriticalSection(&session_cs);
-- return S_OK;
-+out:
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
- }
-
- static HRESULT WINAPI AudioStreamVolume_GetAllVolumes(
- IAudioStreamVolume *iface, UINT32 count, float *levels)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-+ HRESULT hr;
- int i;
-
- TRACE("(%p)->(%d, %p)\n", This, count, levels);
-@@ -1572,59 +2925,63 @@ static HRESULT WINAPI AudioStreamVolume_GetAllVolumes(
- if (!levels)
- return E_POINTER;
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-- if (count != This->channel_count)
-+ if (count != This->ss.channels)
- return E_INVALIDARG;
-
-- EnterCriticalSection(&session_cs);
-+ pthread_mutex_lock(&pulse_lock);
-+ hr = pulse_stream_valid(This);
-+ if (FAILED(hr))
-+ goto out;
-+
- for (i = 0; i < count; ++i)
- levels[i] = This->vol[i];
-- LeaveCriticalSection(&session_cs);
-- return S_OK;
-+
-+out:
-+ pthread_mutex_unlock(&pulse_lock);
-+ return hr;
- }
-
- static HRESULT WINAPI AudioStreamVolume_SetChannelVolume(
- IAudioStreamVolume *iface, UINT32 index, float level)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-+ HRESULT hr;
-+ float volumes[PA_CHANNELS_MAX];
-
- TRACE("(%p)->(%d, %f)\n", This, index, level);
-
- if (level < 0.f || level > 1.f)
- return E_INVALIDARG;
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-- if (index >= This->channel_count)
-+ if (index >= This->ss.channels)
- return E_INVALIDARG;
-
-- EnterCriticalSection(&session_cs);
-- This->vol[index] = level;
-- set_stream_volumes(This);
-- LeaveCriticalSection(&session_cs);
-- return S_OK;
-+ hr = AudioStreamVolume_GetAllVolumes(iface, This->ss.channels, volumes);
-+ volumes[index] = level;
-+ if (SUCCEEDED(hr))
-+ hr = AudioStreamVolume_SetAllVolumes(iface, This->ss.channels, volumes);
-+ return hr;
- }
-
- static HRESULT WINAPI AudioStreamVolume_GetChannelVolume(
- IAudioStreamVolume *iface, UINT32 index, float *level)
- {
- ACImpl *This = impl_from_IAudioStreamVolume(iface);
-+ float volumes[PA_CHANNELS_MAX];
-+ HRESULT hr;
-
- TRACE("(%p)->(%d, %p)\n", This, index, level);
-
- if (!level)
- return E_POINTER;
-
-- if (!This->pulse_stream)
-- return AUDCLNT_E_NOT_INITIALIZED;
-- if (index >= This->channel_count)
-+ if (index >= This->ss.channels)
- return E_INVALIDARG;
-
-- EnterCriticalSection(&session_cs);
-- *level = This->vol[index];
-- LeaveCriticalSection(&session_cs);
-- return S_OK;
-+ hr = AudioStreamVolume_GetAllVolumes(iface, This->ss.channels, volumes);
-+ if (SUCCEEDED(hr))
-+ *level = volumes[index];
-+ return hr;
- }
-
- static const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl =
-@@ -1657,7 +3014,7 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client)
- ret->client = client;
- if (client) {
- ret->session = client->session;
-- AudioClient_AddRef(&client->IAudioClient3_iface);
-+ AudioClient_AddRef(&client->IAudioClient2_iface);
- }
-
- return ret;
-@@ -1703,7 +3060,7 @@ static ULONG WINAPI AudioSessionControl_Release(IAudioSessionControl2 *iface)
- if (!ref) {
- if (This->client) {
- This->client->session_wrapper = NULL;
-- AudioClient_Release(&This->client->IAudioClient3_iface);
-+ AudioClient_Release(&This->client->IAudioClient2_iface);
- }
- HeapFree(GetProcessHeap(), 0, This);
- }
-@@ -1721,20 +3078,13 @@ static HRESULT WINAPI AudioSessionControl_GetState(IAudioSessionControl2 *iface,
- if (!state)
- return NULL_PTR_ERR;
-
-- EnterCriticalSection(&session_cs);
-+ pthread_mutex_lock(&pulse_lock);
- if (list_empty(&This->session->clients)) {
- *state = AudioSessionStateExpired;
- goto out;
- }
- LIST_FOR_EACH_ENTRY(client, &This->session->clients, ACImpl, entry) {
-- struct is_started_params params;
--
-- if (!client->pulse_stream)
-- continue;
--
-- params.stream = client->pulse_stream;
-- pulse_call(is_started, ¶ms);
-- if (params.started) {
-+ if (client->started) {
- *state = AudioSessionStateActive;
- goto out;
- }
-@@ -1742,7 +3092,7 @@ static HRESULT WINAPI AudioSessionControl_GetState(IAudioSessionControl2 *iface,
- *state = AudioSessionStateInactive;
-
- out:
-- LeaveCriticalSection(&session_cs);
-+ pthread_mutex_unlock(&pulse_lock);
- return S_OK;
- }
-
-@@ -2106,7 +3456,6 @@ static HRESULT WINAPI SimpleAudioVolume_SetMasterVolume(
- {
- AudioSessionWrapper *This = impl_from_ISimpleAudioVolume(iface);
- AudioSession *session = This->session;
-- ACImpl *client;
-
- TRACE("(%p)->(%f, %s)\n", session, level, wine_dbgstr_guid(context));
-
-@@ -2118,11 +3467,9 @@ static HRESULT WINAPI SimpleAudioVolume_SetMasterVolume(
-
- TRACE("PulseAudio does not support session volume control\n");
-
-- EnterCriticalSection(&session_cs);
-+ pthread_mutex_lock(&pulse_lock);
- session->master_vol = level;
-- LIST_FOR_EACH_ENTRY(client, &This->session->clients, ACImpl, entry)
-- set_stream_volumes(client);
-- LeaveCriticalSection(&session_cs);
-+ pthread_mutex_unlock(&pulse_lock);
-
- return S_OK;
- }
-@@ -2148,18 +3495,13 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface,
- {
- AudioSessionWrapper *This = impl_from_ISimpleAudioVolume(iface);
- AudioSession *session = This->session;
-- ACImpl *client;
-
- TRACE("(%p)->(%u, %s)\n", session, mute, debugstr_guid(context));
-
- if (context)
- FIXME("Notifications not supported yet\n");
-
-- EnterCriticalSection(&session_cs);
- session->mute = mute;
-- LIST_FOR_EACH_ENTRY(client, &This->session->clients, ACImpl, entry)
-- set_stream_volumes(client);
-- LeaveCriticalSection(&session_cs);
-
- return S_OK;
- }
-@@ -2246,7 +3588,6 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume(
- {
- AudioSessionWrapper *This = impl_from_IChannelAudioVolume(iface);
- AudioSession *session = This->session;
-- ACImpl *client;
-
- TRACE("(%p)->(%d, %f, %s)\n", session, index, level,
- wine_dbgstr_guid(context));
-@@ -2262,11 +3603,9 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume(
-
- TRACE("PulseAudio does not support session volume control\n");
-
-- EnterCriticalSection(&session_cs);
-+ pthread_mutex_lock(&pulse_lock);
- session->channel_vols[index] = level;
-- LIST_FOR_EACH_ENTRY(client, &This->session->clients, ACImpl, entry)
-- set_stream_volumes(client);
-- LeaveCriticalSection(&session_cs);
-+ pthread_mutex_unlock(&pulse_lock);
-
- return S_OK;
- }
-@@ -2296,7 +3635,6 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes(
- {
- AudioSessionWrapper *This = impl_from_IChannelAudioVolume(iface);
- AudioSession *session = This->session;
-- ACImpl *client;
- int i;
-
- TRACE("(%p)->(%d, %p, %s)\n", session, count, levels,
-@@ -2313,12 +3651,10 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes(
-
- TRACE("PulseAudio does not support session volume control\n");
-
-- EnterCriticalSection(&session_cs);
-+ pthread_mutex_lock(&pulse_lock);
- for(i = 0; i < count; ++i)
- session->channel_vols[i] = levels[i];
-- LIST_FOR_EACH_ENTRY(client, &This->session->clients, ACImpl, entry)
-- set_stream_volumes(client);
-- LeaveCriticalSection(&session_cs);
-+ pthread_mutex_unlock(&pulse_lock);
- return S_OK;
- }
-
-@@ -2375,10 +3711,2001 @@ HRESULT WINAPI AUDDRV_GetPropValue(GUID *guid, const PROPERTYKEY *prop, PROPVARI
-
- if (IsEqualGUID(guid, &pulse_render_guid) && IsEqualPropertyKey(*prop, PKEY_AudioEndpoint_PhysicalSpeakers)) {
- out->vt = VT_UI4;
-- out->ulVal = pulse_config.speakers_mask;
-+ out->u.ulVal = g_phys_speakers_mask;
-
-- return out->ulVal ? S_OK : E_FAIL;
-+ return out->u.ulVal ? S_OK : E_FAIL;
- }
-
- return E_NOTIMPL;
- }
-+
-+
-+
-+/**********************************************************************
-+ * A-law and u-law sample manipulation functions
-+ * Multiply with the given volume (vol must be between 0...1 inclusive)
-+ *
-+ * These were taken from PulseAudio's sources but adjusted to directly
-+ * fit our usage (since we use floats directly) so they should be exact.
-+ */
-+static UINT8 mult_alaw_sample(UINT8 sample, float vol)
-+{
-+ static const float decode_to_13bits_float[1 << 8] =
-+ {
-+ -688.0f, -656.0f, -752.0f, -720.0f, -560.0f, -528.0f, -624.0f, -592.0f,
-+ -944.0f, -912.0f, -1008.0f, -976.0f, -816.0f, -784.0f, -880.0f, -848.0f,
-+ -344.0f, -328.0f, -376.0f, -360.0f, -280.0f, -264.0f, -312.0f, -296.0f,
-+ -472.0f, -456.0f, -504.0f, -488.0f, -408.0f, -392.0f, -440.0f, -424.0f,
-+ -2752.0f, -2624.0f, -3008.0f, -2880.0f, -2240.0f, -2112.0f, -2496.0f, -2368.0f,
-+ -3776.0f, -3648.0f, -4032.0f, -3904.0f, -3264.0f, -3136.0f, -3520.0f, -3392.0f,
-+ -1376.0f, -1312.0f, -1504.0f, -1440.0f, -1120.0f, -1056.0f, -1248.0f, -1184.0f,
-+ -1888.0f, -1824.0f, -2016.0f, -1952.0f, -1632.0f, -1568.0f, -1760.0f, -1696.0f,
-+ -43.0f, -41.0f, -47.0f, -45.0f, -35.0f, -33.0f, -39.0f, -37.0f,
-+ -59.0f, -57.0f, -63.0f, -61.0f, -51.0f, -49.0f, -55.0f, -53.0f,
-+ -11.0f, -9.0f, -15.0f, -13.0f, -3.0f, -1.0f, -7.0f, -5.0f,
-+ -27.0f, -25.0f, -31.0f, -29.0f, -19.0f, -17.0f, -23.0f, -21.0f,
-+ -172.0f, -164.0f, -188.0f, -180.0f, -140.0f, -132.0f, -156.0f, -148.0f,
-+ -236.0f, -228.0f, -252.0f, -244.0f, -204.0f, -196.0f, -220.0f, -212.0f,
-+ -86.0f, -82.0f, -94.0f, -90.0f, -70.0f, -66.0f, -78.0f, -74.0f,
-+ -118.0f, -114.0f, -126.0f, -122.0f, -102.0f, -98.0f, -110.0f, -106.0f,
-+ 688.0f, 656.0f, 752.0f, 720.0f, 560.0f, 528.0f, 624.0f, 592.0f,
-+ 944.0f, 912.0f, 1008.0f, 976.0f, 816.0f, 784.0f, 880.0f, 848.0f,
-+ 344.0f, 328.0f, 376.0f, 360.0f, 280.0f, 264.0f, 312.0f, 296.0f,
-+ 472.0f, 456.0f, 504.0f, 488.0f, 408.0f, 392.0f, 440.0f, 424.0f,
-+ 2752.0f, 2624.0f, 3008.0f, 2880.0f, 2240.0f, 2112.0f, 2496.0f, 2368.0f,
-+ 3776.0f, 3648.0f, 4032.0f, 3904.0f, 3264.0f, 3136.0f, 3520.0f, 3392.0f,
-+ 1376.0f, 1312.0f, 1504.0f, 1440.0f, 1120.0f, 1056.0f, 1248.0f, 1184.0f,
-+ 1888.0f, 1824.0f, 2016.0f, 1952.0f, 1632.0f, 1568.0f, 1760.0f, 1696.0f,
-+ 43.0f, 41.0f, 47.0f, 45.0f, 35.0f, 33.0f, 39.0f, 37.0f,
-+ 59.0f, 57.0f, 63.0f, 61.0f, 51.0f, 49.0f, 55.0f, 53.0f,
-+ 11.0f, 9.0f, 15.0f, 13.0f, 3.0f, 1.0f, 7.0f, 5.0f,
-+ 27.0f, 25.0f, 31.0f, 29.0f, 19.0f, 17.0f, 23.0f, 21.0f,
-+ 172.0f, 164.0f, 188.0f, 180.0f, 140.0f, 132.0f, 156.0f, 148.0f,
-+ 236.0f, 228.0f, 252.0f, 244.0f, 204.0f, 196.0f, 220.0f, 212.0f,
-+ 86.0f, 82.0f, 94.0f, 90.0f, 70.0f, 66.0f, 78.0f, 74.0f,
-+ 118.0f, 114.0f, 126.0f, 122.0f, 102.0f, 98.0f, 110.0f, 106.0f
-+ };
-+
-+ static const UINT8 encode[1 << 13] =
-+ {
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-+ 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-+ 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-+ 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-+ 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-+ 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-+ 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-+ 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-+ 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-+ 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-+ 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-+ 0x39, 0x39, 0x39, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-+ 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-+ 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-+ 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-+ 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-+ 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-+ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-+ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-+ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-+ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-+ 0x3f, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-+ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-+ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-+ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-+ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x32,
-+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
-+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x36, 0x36, 0x36, 0x36, 0x36,
-+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-+ 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-+ 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-+ 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-+ 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-+ 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-+ 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-+ 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-+ 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-+ 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-+ 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-+ 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-+ 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-+ 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-+ 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-+ 0x35, 0x35, 0x35, 0x35, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
-+ 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x68, 0x68, 0x68, 0x68, 0x68,
-+ 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
-+ 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d,
-+ 0x6d, 0x6d, 0x6d, 0x6d, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x63,
-+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
-+ 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x66, 0x66, 0x66,
-+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67,
-+ 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x65,
-+ 0x65, 0x65, 0x65, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x78, 0x78,
-+ 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
-+ 0x7f, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x72, 0x72, 0x72, 0x72,
-+ 0x73, 0x73, 0x73, 0x73, 0x70, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, 0x76,
-+ 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x74, 0x74, 0x74, 0x74, 0x75, 0x75,
-+ 0x75, 0x75, 0x4a, 0x4a, 0x4b, 0x4b, 0x48, 0x48, 0x49, 0x49, 0x4e, 0x4e, 0x4f,
-+ 0x4f, 0x4c, 0x4c, 0x4d, 0x4d, 0x42, 0x42, 0x43, 0x43, 0x40, 0x40, 0x41, 0x41,
-+ 0x46, 0x46, 0x47, 0x47, 0x44, 0x44, 0x45, 0x45, 0x5a, 0x5a, 0x5b, 0x5b, 0x58,
-+ 0x58, 0x59, 0x59, 0x5e, 0x5e, 0x5f, 0x5f, 0x5c, 0x5c, 0x5d, 0x5d, 0x52, 0x52,
-+ 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55,
-+ 0x55, 0xd5, 0xd5, 0xd4, 0xd4, 0xd7, 0xd7, 0xd6, 0xd6, 0xd1, 0xd1, 0xd0, 0xd0,
-+ 0xd3, 0xd3, 0xd2, 0xd2, 0xdd, 0xdd, 0xdc, 0xdc, 0xdf, 0xdf, 0xde, 0xde, 0xd9,
-+ 0xd9, 0xd8, 0xd8, 0xdb, 0xdb, 0xda, 0xda, 0xc5, 0xc5, 0xc4, 0xc4, 0xc7, 0xc7,
-+ 0xc6, 0xc6, 0xc1, 0xc1, 0xc0, 0xc0, 0xc3, 0xc3, 0xc2, 0xc2, 0xcd, 0xcd, 0xcc,
-+ 0xcc, 0xcf, 0xcf, 0xce, 0xce, 0xc9, 0xc9, 0xc8, 0xc8, 0xcb, 0xcb, 0xca, 0xca,
-+ 0xf5, 0xf5, 0xf5, 0xf5, 0xf4, 0xf4, 0xf4, 0xf4, 0xf7, 0xf7, 0xf7, 0xf7, 0xf6,
-+ 0xf6, 0xf6, 0xf6, 0xf1, 0xf1, 0xf1, 0xf1, 0xf0, 0xf0, 0xf0, 0xf0, 0xf3, 0xf3,
-+ 0xf3, 0xf3, 0xf2, 0xf2, 0xf2, 0xf2, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc,
-+ 0xfc, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xf9, 0xf9, 0xf9, 0xf9,
-+ 0xf8, 0xf8, 0xf8, 0xf8, 0xfb, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xfa, 0xe5,
-+ 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4,
-+ 0xe4, 0xe4, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1,
-+ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3,
-+ 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xed, 0xed,
-+ 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec,
-+ 0xec, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee,
-+ 0xee, 0xee, 0xee, 0xee, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8,
-+ 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
-+ 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5,
-+ 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-+ 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-+ 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-+ 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-+ 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4,
-+ 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-+ 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-+ 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-+ 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-+ 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb7, 0xb7, 0xb7, 0xb7,
-+ 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-+ 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-+ 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-+ 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-+ 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-+ 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-+ 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-+ 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-+ 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-+ 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-+ 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-+ 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-+ 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-+ 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-+ 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-+ 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-+ 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-+ 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-+ 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-+ 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-+ 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-+ 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-+ 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-+ 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-+ 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-+ 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-+ 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-+ 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-+ 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-+ 0xb2, 0xb2, 0xb2, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-+ 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-+ 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-+ 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-+ 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-+ 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-+ 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-+ 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-+ 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-+ 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-+ 0xbc, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-+ 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-+ 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-+ 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-+ 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-+ 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-+ 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-+ 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-+ 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-+ 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9,
-+ 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-+ 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-+ 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-+ 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-+ 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8,
-+ 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-+ 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-+ 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-+ 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-+ 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xbb, 0xbb, 0xbb,
-+ 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-+ 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-+ 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-+ 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-+ 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba,
-+ 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-+ 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-+ 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-+ 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-+ 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa
-+ };
-+
-+ return encode[(int)(vol * decode_to_13bits_float[sample]) + ARRAY_SIZE(encode) / 2];
-+}
-+
-+static UINT8 mult_ulaw_sample(UINT8 sample, float vol)
-+{
-+ static const float decode_to_14bits_float[1 << 8] =
-+ {
-+ -8031.0f, -7775.0f, -7519.0f, -7263.0f, -7007.0f, -6751.0f, -6495.0f, -6239.0f,
-+ -5983.0f, -5727.0f, -5471.0f, -5215.0f, -4959.0f, -4703.0f, -4447.0f, -4191.0f,
-+ -3999.0f, -3871.0f, -3743.0f, -3615.0f, -3487.0f, -3359.0f, -3231.0f, -3103.0f,
-+ -2975.0f, -2847.0f, -2719.0f, -2591.0f, -2463.0f, -2335.0f, -2207.0f, -2079.0f,
-+ -1983.0f, -1919.0f, -1855.0f, -1791.0f, -1727.0f, -1663.0f, -1599.0f, -1535.0f,
-+ -1471.0f, -1407.0f, -1343.0f, -1279.0f, -1215.0f, -1151.0f, -1087.0f, -1023.0f,
-+ -975.0f, -943.0f, -911.0f, -879.0f, -847.0f, -815.0f, -783.0f, -751.0f,
-+ -719.0f, -687.0f, -655.0f, -623.0f, -591.0f, -559.0f, -527.0f, -495.0f,
-+ -471.0f, -455.0f, -439.0f, -423.0f, -407.0f, -391.0f, -375.0f, -359.0f,
-+ -343.0f, -327.0f, -311.0f, -295.0f, -279.0f, -263.0f, -247.0f, -231.0f,
-+ -219.0f, -211.0f, -203.0f, -195.0f, -187.0f, -179.0f, -171.0f, -163.0f,
-+ -155.0f, -147.0f, -139.0f, -131.0f, -123.0f, -115.0f, -107.0f, -99.0f,
-+ -93.0f, -89.0f, -85.0f, -81.0f, -77.0f, -73.0f, -69.0f, -65.0f,
-+ -61.0f, -57.0f, -53.0f, -49.0f, -45.0f, -41.0f, -37.0f, -33.0f,
-+ -30.0f, -28.0f, -26.0f, -24.0f, -22.0f, -20.0f, -18.0f, -16.0f,
-+ -14.0f, -12.0f, -10.0f, -8.0f, -6.0f, -4.0f, -2.0f, 0.0f,
-+ 8031.0f, 7775.0f, 7519.0f, 7263.0f, 7007.0f, 6751.0f, 6495.0f, 6239.0f,
-+ 5983.0f, 5727.0f, 5471.0f, 5215.0f, 4959.0f, 4703.0f, 4447.0f, 4191.0f,
-+ 3999.0f, 3871.0f, 3743.0f, 3615.0f, 3487.0f, 3359.0f, 3231.0f, 3103.0f,
-+ 2975.0f, 2847.0f, 2719.0f, 2591.0f, 2463.0f, 2335.0f, 2207.0f, 2079.0f,
-+ 1983.0f, 1919.0f, 1855.0f, 1791.0f, 1727.0f, 1663.0f, 1599.0f, 1535.0f,
-+ 1471.0f, 1407.0f, 1343.0f, 1279.0f, 1215.0f, 1151.0f, 1087.0f, 1023.0f,
-+ 975.0f, 943.0f, 911.0f, 879.0f, 847.0f, 815.0f, 783.0f, 751.0f,
-+ 719.0f, 687.0f, 655.0f, 623.0f, 591.0f, 559.0f, 527.0f, 495.0f,
-+ 471.0f, 455.0f, 439.0f, 423.0f, 407.0f, 391.0f, 375.0f, 359.0f,
-+ 343.0f, 327.0f, 311.0f, 295.0f, 279.0f, 263.0f, 247.0f, 231.0f,
-+ 219.0f, 211.0f, 203.0f, 195.0f, 187.0f, 179.0f, 171.0f, 163.0f,
-+ 155.0f, 147.0f, 139.0f, 131.0f, 123.0f, 115.0f, 107.0f, 99.0f,
-+ 93.0f, 89.0f, 85.0f, 81.0f, 77.0f, 73.0f, 69.0f, 65.0f,
-+ 61.0f, 57.0f, 53.0f, 49.0f, 45.0f, 41.0f, 37.0f, 33.0f,
-+ 30.0f, 28.0f, 26.0f, 24.0f, 22.0f, 20.0f, 18.0f, 16.0f,
-+ 14.0f, 12.0f, 10.0f, 8.0f, 6.0f, 4.0f, 2.0f, 0.0f
-+ };
-+
-+ static const UINT8 encode[1 << 14] =
-+ {
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-+ 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-+ 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-+ 0x19, 0x19, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-+ 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-+ 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-+ 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-+ 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32,
-+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x34,
-+ 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-+ 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-+ 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-+ 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-+ 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36,
-+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-+ 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-+ 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-+ 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x38,
-+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-+ 0x38, 0x38, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-+ 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-+ 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-+ 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-+ 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-+ 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-+ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-+ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-+ 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-+ 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-+ 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3f,
-+ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-+ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-+ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x41, 0x41,
-+ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42,
-+ 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
-+ 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
-+ 0x43, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
-+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
-+ 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x46, 0x46,
-+ 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46,
-+ 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-+ 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-+ 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4a,
-+ 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4b,
-+ 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
-+ 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,
-+ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d,
-+ 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
-+ 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4f, 0x4f,
-+ 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
-+ 0x4f, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x51,
-+ 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x53,
-+ 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
-+ 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x56, 0x56,
-+ 0x56, 0x56, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-+ 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x59,
-+ 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b,
-+ 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
-+ 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, 0x5e,
-+ 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x60,
-+ 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x62, 0x63, 0x63,
-+ 0x63, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x66, 0x66, 0x66,
-+ 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69,
-+ 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d,
-+ 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x70,
-+ 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77,
-+ 0x77, 0x78, 0x78, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d,
-+ 0x7e, 0x7e, 0xff, 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa,
-+ 0xf9, 0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xf6, 0xf6, 0xf5, 0xf5, 0xf4, 0xf4, 0xf3,
-+ 0xf3, 0xf2, 0xf2, 0xf1, 0xf1, 0xf0, 0xf0, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee,
-+ 0xee, 0xee, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xeb, 0xeb, 0xeb,
-+ 0xeb, 0xea, 0xea, 0xea, 0xea, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8,
-+ 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4,
-+ 0xe4, 0xe4, 0xe4, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1,
-+ 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
-+ 0xdf, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd,
-+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb,
-+ 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda,
-+ 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8,
-+ 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
-+ 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
-+ 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3, 0xd3,
-+ 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
-+ 0xd2, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xd0,
-+ 0xd0, 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
-+ 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce,
-+ 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xcd, 0xcd, 0xcd,
-+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
-+ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
-+ 0xcc, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb,
-+ 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca,
-+ 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc9,
-+ 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc8,
-+ 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8,
-+ 0xc8, 0xc8, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7,
-+ 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-+ 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
-+ 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4,
-+ 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-+ 0xc4, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3,
-+ 0xc3, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
-+ 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
-+ 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0,
-+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
-+ 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-+ 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-+ 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-+ 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-+ 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbd,
-+ 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-+ 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-+ 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-+ 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-+ 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbb, 0xbb,
-+ 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-+ 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-+ 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-+ 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-+ 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xb9,
-+ 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-+ 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-+ 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-+ 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-+ 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb7, 0xb7, 0xb7, 0xb7,
-+ 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-+ 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-+ 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-+ 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-+ 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-+ 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-+ 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-+ 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-+ 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-+ 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-+ 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-+ 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-+ 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-+ 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-+ 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-+ 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-+ 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0,
-+ 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-+ 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-+ 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-+ 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-+ 0xae, 0xae, 0xae, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-+ 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0xac, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-+ 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-+ 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-+ 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-+ 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-+ 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-+ 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-+ 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-+ 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-+ 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-+ 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-+ 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-+ 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-+ 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-+ 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-+ 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-+ 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-+ 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-+ 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-+ 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-+ 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-+ 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80
-+ };
-+
-+ return encode[(int)(vol * decode_to_14bits_float[sample]) + ARRAY_SIZE(encode) / 2];
-+}
-diff --git a/dlls/winepulse.drv/mult.c b/dlls/winepulse.drv/mult.c
-deleted file mode 100644
-index 26b5e83c9cafad674bf80747bae1f5992538ee1c..0000000000000000000000000000000000000000
---- a/dlls/winepulse.drv/mult.c
-+++ /dev/null
-@@ -1,2015 +0,0 @@
--/*
-- * Copyright 2011-2012 Maarten Lankhorst
-- * Copyright 2010-2011 Maarten Lankhorst for CodeWeavers
-- * Copyright 2011 Andrew Eikum for CodeWeavers
-- *
-- * This library is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU Lesser General Public
-- * License as published by the Free Software Foundation; either
-- * version 2.1 of the License, or (at your option) any later version.
-- *
-- * This library is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- * Lesser General Public License for more details.
-- *
-- * You should have received a copy of the GNU Lesser General Public
-- * License along with this library; if not, write to the Free Software
-- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-- */
--
--#include
--
--#if 0
--#pragma makedep unix
--#endif
--
--
--/**********************************************************************
-- * A-law and u-law sample manipulation functions
-- * Multiply with the given volume (vol must be between 0...1 inclusive)
-- *
-- * These were taken from PulseAudio's sources but adjusted to directly
-- * fit our usage (since we use floats directly) so they should be exact.
-- */
--UINT8 mult_alaw_sample(UINT8 sample, float vol)
--{
-- static const float decode_to_13bits_float[1 << 8] =
-- {
-- -688.0f, -656.0f, -752.0f, -720.0f, -560.0f, -528.0f, -624.0f, -592.0f,
-- -944.0f, -912.0f, -1008.0f, -976.0f, -816.0f, -784.0f, -880.0f, -848.0f,
-- -344.0f, -328.0f, -376.0f, -360.0f, -280.0f, -264.0f, -312.0f, -296.0f,
-- -472.0f, -456.0f, -504.0f, -488.0f, -408.0f, -392.0f, -440.0f, -424.0f,
-- -2752.0f, -2624.0f, -3008.0f, -2880.0f, -2240.0f, -2112.0f, -2496.0f, -2368.0f,
-- -3776.0f, -3648.0f, -4032.0f, -3904.0f, -3264.0f, -3136.0f, -3520.0f, -3392.0f,
-- -1376.0f, -1312.0f, -1504.0f, -1440.0f, -1120.0f, -1056.0f, -1248.0f, -1184.0f,
-- -1888.0f, -1824.0f, -2016.0f, -1952.0f, -1632.0f, -1568.0f, -1760.0f, -1696.0f,
-- -43.0f, -41.0f, -47.0f, -45.0f, -35.0f, -33.0f, -39.0f, -37.0f,
-- -59.0f, -57.0f, -63.0f, -61.0f, -51.0f, -49.0f, -55.0f, -53.0f,
-- -11.0f, -9.0f, -15.0f, -13.0f, -3.0f, -1.0f, -7.0f, -5.0f,
-- -27.0f, -25.0f, -31.0f, -29.0f, -19.0f, -17.0f, -23.0f, -21.0f,
-- -172.0f, -164.0f, -188.0f, -180.0f, -140.0f, -132.0f, -156.0f, -148.0f,
-- -236.0f, -228.0f, -252.0f, -244.0f, -204.0f, -196.0f, -220.0f, -212.0f,
-- -86.0f, -82.0f, -94.0f, -90.0f, -70.0f, -66.0f, -78.0f, -74.0f,
-- -118.0f, -114.0f, -126.0f, -122.0f, -102.0f, -98.0f, -110.0f, -106.0f,
-- 688.0f, 656.0f, 752.0f, 720.0f, 560.0f, 528.0f, 624.0f, 592.0f,
-- 944.0f, 912.0f, 1008.0f, 976.0f, 816.0f, 784.0f, 880.0f, 848.0f,
-- 344.0f, 328.0f, 376.0f, 360.0f, 280.0f, 264.0f, 312.0f, 296.0f,
-- 472.0f, 456.0f, 504.0f, 488.0f, 408.0f, 392.0f, 440.0f, 424.0f,
-- 2752.0f, 2624.0f, 3008.0f, 2880.0f, 2240.0f, 2112.0f, 2496.0f, 2368.0f,
-- 3776.0f, 3648.0f, 4032.0f, 3904.0f, 3264.0f, 3136.0f, 3520.0f, 3392.0f,
-- 1376.0f, 1312.0f, 1504.0f, 1440.0f, 1120.0f, 1056.0f, 1248.0f, 1184.0f,
-- 1888.0f, 1824.0f, 2016.0f, 1952.0f, 1632.0f, 1568.0f, 1760.0f, 1696.0f,
-- 43.0f, 41.0f, 47.0f, 45.0f, 35.0f, 33.0f, 39.0f, 37.0f,
-- 59.0f, 57.0f, 63.0f, 61.0f, 51.0f, 49.0f, 55.0f, 53.0f,
-- 11.0f, 9.0f, 15.0f, 13.0f, 3.0f, 1.0f, 7.0f, 5.0f,
-- 27.0f, 25.0f, 31.0f, 29.0f, 19.0f, 17.0f, 23.0f, 21.0f,
-- 172.0f, 164.0f, 188.0f, 180.0f, 140.0f, 132.0f, 156.0f, 148.0f,
-- 236.0f, 228.0f, 252.0f, 244.0f, 204.0f, 196.0f, 220.0f, 212.0f,
-- 86.0f, 82.0f, 94.0f, 90.0f, 70.0f, 66.0f, 78.0f, 74.0f,
-- 118.0f, 114.0f, 126.0f, 122.0f, 102.0f, 98.0f, 110.0f, 106.0f
-- };
--
-- static const UINT8 encode[1 << 13] =
-- {
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-- 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-- 0x39, 0x39, 0x39, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-- 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-- 0x3f, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x32,
-- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33,
-- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, 0x30, 0x30,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
-- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-- 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-- 0x35, 0x35, 0x35, 0x35, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
-- 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x68, 0x68, 0x68, 0x68, 0x68,
-- 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x6e, 0x6e,
-- 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
-- 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d,
-- 0x6d, 0x6d, 0x6d, 0x6d, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x63,
-- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
-- 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x66, 0x66, 0x66,
-- 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67,
-- 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x65,
-- 0x65, 0x65, 0x65, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x78, 0x78,
-- 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
-- 0x7f, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x72, 0x72, 0x72, 0x72,
-- 0x73, 0x73, 0x73, 0x73, 0x70, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, 0x76,
-- 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x74, 0x74, 0x74, 0x74, 0x75, 0x75,
-- 0x75, 0x75, 0x4a, 0x4a, 0x4b, 0x4b, 0x48, 0x48, 0x49, 0x49, 0x4e, 0x4e, 0x4f,
-- 0x4f, 0x4c, 0x4c, 0x4d, 0x4d, 0x42, 0x42, 0x43, 0x43, 0x40, 0x40, 0x41, 0x41,
-- 0x46, 0x46, 0x47, 0x47, 0x44, 0x44, 0x45, 0x45, 0x5a, 0x5a, 0x5b, 0x5b, 0x58,
-- 0x58, 0x59, 0x59, 0x5e, 0x5e, 0x5f, 0x5f, 0x5c, 0x5c, 0x5d, 0x5d, 0x52, 0x52,
-- 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55,
-- 0x55, 0xd5, 0xd5, 0xd4, 0xd4, 0xd7, 0xd7, 0xd6, 0xd6, 0xd1, 0xd1, 0xd0, 0xd0,
-- 0xd3, 0xd3, 0xd2, 0xd2, 0xdd, 0xdd, 0xdc, 0xdc, 0xdf, 0xdf, 0xde, 0xde, 0xd9,
-- 0xd9, 0xd8, 0xd8, 0xdb, 0xdb, 0xda, 0xda, 0xc5, 0xc5, 0xc4, 0xc4, 0xc7, 0xc7,
-- 0xc6, 0xc6, 0xc1, 0xc1, 0xc0, 0xc0, 0xc3, 0xc3, 0xc2, 0xc2, 0xcd, 0xcd, 0xcc,
-- 0xcc, 0xcf, 0xcf, 0xce, 0xce, 0xc9, 0xc9, 0xc8, 0xc8, 0xcb, 0xcb, 0xca, 0xca,
-- 0xf5, 0xf5, 0xf5, 0xf5, 0xf4, 0xf4, 0xf4, 0xf4, 0xf7, 0xf7, 0xf7, 0xf7, 0xf6,
-- 0xf6, 0xf6, 0xf6, 0xf1, 0xf1, 0xf1, 0xf1, 0xf0, 0xf0, 0xf0, 0xf0, 0xf3, 0xf3,
-- 0xf3, 0xf3, 0xf2, 0xf2, 0xf2, 0xf2, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc,
-- 0xfc, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xf9, 0xf9, 0xf9, 0xf9,
-- 0xf8, 0xf8, 0xf8, 0xf8, 0xfb, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xfa, 0xe5,
-- 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4,
-- 0xe4, 0xe4, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6,
-- 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1,
-- 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3,
-- 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xed, 0xed,
-- 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec,
-- 0xec, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee,
-- 0xee, 0xee, 0xee, 0xee, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8,
-- 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
-- 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5,
-- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4,
-- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb7, 0xb7, 0xb7, 0xb7,
-- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-- 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-- 0xb2, 0xb2, 0xb2, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-- 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-- 0xbc, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9,
-- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8,
-- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xbb, 0xbb, 0xbb,
-- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba,
-- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa
-- };
--
-- return encode[(int)(vol * decode_to_13bits_float[sample]) + ARRAY_SIZE(encode) / 2];
--}
--
--UINT8 mult_ulaw_sample(UINT8 sample, float vol)
--{
-- static const float decode_to_14bits_float[1 << 8] =
-- {
-- -8031.0f, -7775.0f, -7519.0f, -7263.0f, -7007.0f, -6751.0f, -6495.0f, -6239.0f,
-- -5983.0f, -5727.0f, -5471.0f, -5215.0f, -4959.0f, -4703.0f, -4447.0f, -4191.0f,
-- -3999.0f, -3871.0f, -3743.0f, -3615.0f, -3487.0f, -3359.0f, -3231.0f, -3103.0f,
-- -2975.0f, -2847.0f, -2719.0f, -2591.0f, -2463.0f, -2335.0f, -2207.0f, -2079.0f,
-- -1983.0f, -1919.0f, -1855.0f, -1791.0f, -1727.0f, -1663.0f, -1599.0f, -1535.0f,
-- -1471.0f, -1407.0f, -1343.0f, -1279.0f, -1215.0f, -1151.0f, -1087.0f, -1023.0f,
-- -975.0f, -943.0f, -911.0f, -879.0f, -847.0f, -815.0f, -783.0f, -751.0f,
-- -719.0f, -687.0f, -655.0f, -623.0f, -591.0f, -559.0f, -527.0f, -495.0f,
-- -471.0f, -455.0f, -439.0f, -423.0f, -407.0f, -391.0f, -375.0f, -359.0f,
-- -343.0f, -327.0f, -311.0f, -295.0f, -279.0f, -263.0f, -247.0f, -231.0f,
-- -219.0f, -211.0f, -203.0f, -195.0f, -187.0f, -179.0f, -171.0f, -163.0f,
-- -155.0f, -147.0f, -139.0f, -131.0f, -123.0f, -115.0f, -107.0f, -99.0f,
-- -93.0f, -89.0f, -85.0f, -81.0f, -77.0f, -73.0f, -69.0f, -65.0f,
-- -61.0f, -57.0f, -53.0f, -49.0f, -45.0f, -41.0f, -37.0f, -33.0f,
-- -30.0f, -28.0f, -26.0f, -24.0f, -22.0f, -20.0f, -18.0f, -16.0f,
-- -14.0f, -12.0f, -10.0f, -8.0f, -6.0f, -4.0f, -2.0f, 0.0f,
-- 8031.0f, 7775.0f, 7519.0f, 7263.0f, 7007.0f, 6751.0f, 6495.0f, 6239.0f,
-- 5983.0f, 5727.0f, 5471.0f, 5215.0f, 4959.0f, 4703.0f, 4447.0f, 4191.0f,
-- 3999.0f, 3871.0f, 3743.0f, 3615.0f, 3487.0f, 3359.0f, 3231.0f, 3103.0f,
-- 2975.0f, 2847.0f, 2719.0f, 2591.0f, 2463.0f, 2335.0f, 2207.0f, 2079.0f,
-- 1983.0f, 1919.0f, 1855.0f, 1791.0f, 1727.0f, 1663.0f, 1599.0f, 1535.0f,
-- 1471.0f, 1407.0f, 1343.0f, 1279.0f, 1215.0f, 1151.0f, 1087.0f, 1023.0f,
-- 975.0f, 943.0f, 911.0f, 879.0f, 847.0f, 815.0f, 783.0f, 751.0f,
-- 719.0f, 687.0f, 655.0f, 623.0f, 591.0f, 559.0f, 527.0f, 495.0f,
-- 471.0f, 455.0f, 439.0f, 423.0f, 407.0f, 391.0f, 375.0f, 359.0f,
-- 343.0f, 327.0f, 311.0f, 295.0f, 279.0f, 263.0f, 247.0f, 231.0f,
-- 219.0f, 211.0f, 203.0f, 195.0f, 187.0f, 179.0f, 171.0f, 163.0f,
-- 155.0f, 147.0f, 139.0f, 131.0f, 123.0f, 115.0f, 107.0f, 99.0f,
-- 93.0f, 89.0f, 85.0f, 81.0f, 77.0f, 73.0f, 69.0f, 65.0f,
-- 61.0f, 57.0f, 53.0f, 49.0f, 45.0f, 41.0f, 37.0f, 33.0f,
-- 30.0f, 28.0f, 26.0f, 24.0f, 22.0f, 20.0f, 18.0f, 16.0f,
-- 14.0f, 12.0f, 10.0f, 8.0f, 6.0f, 4.0f, 2.0f, 0.0f
-- };
--
-- static const UINT8 encode[1 << 14] =
-- {
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-- 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-- 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-- 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
-- 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
-- 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-- 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
-- 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
-- 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
-- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
-- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
-- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
-- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-- 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
-- 0x19, 0x19, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
-- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
-- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
-- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
-- 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
-- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
-- 0x2b, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
-- 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32,
-- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-- 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x34,
-- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
-- 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
-- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x38,
-- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
-- 0x38, 0x38, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
-- 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
-- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
-- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
-- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3f,
-- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x41, 0x41,
-- 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42,
-- 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
-- 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
-- 0x43, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
-- 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
-- 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x46, 0x46,
-- 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46,
-- 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-- 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
-- 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4a,
-- 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4b,
-- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
-- 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,
-- 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d,
-- 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
-- 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4f, 0x4f,
-- 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
-- 0x4f, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x51,
-- 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x53,
-- 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
-- 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x56, 0x56,
-- 0x56, 0x56, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
-- 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x59,
-- 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b,
-- 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
-- 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, 0x5e,
-- 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x60,
-- 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x62, 0x63, 0x63,
-- 0x63, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x66, 0x66, 0x66,
-- 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69,
-- 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d,
-- 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x70,
-- 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77,
-- 0x77, 0x78, 0x78, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d,
-- 0x7e, 0x7e, 0xff, 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa,
-- 0xf9, 0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xf6, 0xf6, 0xf5, 0xf5, 0xf4, 0xf4, 0xf3,
-- 0xf3, 0xf2, 0xf2, 0xf1, 0xf1, 0xf0, 0xf0, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee,
-- 0xee, 0xee, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xeb, 0xeb, 0xeb,
-- 0xeb, 0xea, 0xea, 0xea, 0xea, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8,
-- 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4,
-- 0xe4, 0xe4, 0xe4, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1,
-- 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
-- 0xdf, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd,
-- 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb,
-- 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda,
-- 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8,
-- 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7,
-- 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
-- 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3, 0xd3,
-- 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
-- 0xd2, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xd0,
-- 0xd0, 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
-- 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce,
-- 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xcd, 0xcd, 0xcd,
-- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
-- 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
-- 0xcc, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb,
-- 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca,
-- 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc9,
-- 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc8,
-- 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8,
-- 0xc8, 0xc8, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7,
-- 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
-- 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4,
-- 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-- 0xc4, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3,
-- 0xc3, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
-- 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
-- 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0,
-- 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
-- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
-- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
-- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbd,
-- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
-- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
-- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbb, 0xbb,
-- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
-- 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
-- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xb9,
-- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
-- 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
-- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb7, 0xb7, 0xb7, 0xb7,
-- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
-- 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
-- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
-- 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
-- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
-- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
-- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
-- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0,
-- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
-- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
-- 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
-- 0xae, 0xae, 0xae, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
-- 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-- 0xac, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
-- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
-- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
-- 0xa2, 0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
-- 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-- 0xa0, 0xa0, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
-- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
-- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
-- 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-- 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
-- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
-- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
-- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
-- 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
-- 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
-- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
-- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
-- 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
-- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
-- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
-- 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
-- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-- 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-- 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-- 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-- 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-- 0x80, 0x80, 0x80, 0x80
-- };
--
-- return encode[(int)(vol * decode_to_14bits_float[sample]) + ARRAY_SIZE(encode) / 2];
--}
-diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c
-deleted file mode 100644
-index 55579ecda80bc557c00b2adba783d7d4b001f52e..0000000000000000000000000000000000000000
---- a/dlls/winepulse.drv/pulse.c
-+++ /dev/null
-@@ -1,1984 +0,0 @@
--/*
-- * Copyright 2011-2012 Maarten Lankhorst
-- * Copyright 2010-2011 Maarten Lankhorst for CodeWeavers
-- * Copyright 2011 Andrew Eikum for CodeWeavers
-- *
-- * This library is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU Lesser General Public
-- * License as published by the Free Software Foundation; either
-- * version 2.1 of the License, or (at your option) any later version.
-- *
-- * This library is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- * Lesser General Public License for more details.
-- *
-- * You should have received a copy of the GNU Lesser General Public
-- * License along with this library; if not, write to the Free Software
-- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-- */
--
--#if 0
--#pragma makedep unix
--#endif
--
--#define _NTSYSTEM_
--
--#include
--#include
--#include
--#include
--
--#include
--
--#include "ntstatus.h"
--#define WIN32_NO_STATUS
--#include "winternl.h"
--
--#include "mmdeviceapi.h"
--#include "initguid.h"
--#include "audioclient.h"
--
--#include "unixlib.h"
--
--#include "wine/debug.h"
--
--WINE_DEFAULT_DEBUG_CHANNEL(pulse);
--
--struct pulse_stream
--{
-- EDataFlow dataflow;
--
-- pa_stream *stream;
-- pa_sample_spec ss;
-- pa_channel_map map;
-- pa_buffer_attr attr;
--
-- DWORD flags;
-- AUDCLNT_SHAREMODE share;
-- HANDLE event;
-- float vol[PA_CHANNELS_MAX];
-- BOOL mute;
--
-- INT32 locked;
-- BOOL started;
-- SIZE_T bufsize_frames, alloc_size, real_bufsize_bytes, period_bytes;
-- SIZE_T peek_ofs, read_offs_bytes, lcl_offs_bytes, pa_offs_bytes;
-- SIZE_T tmp_buffer_bytes, held_bytes, peek_len, peek_buffer_len, pa_held_bytes;
-- BYTE *local_buffer, *tmp_buffer, *peek_buffer;
-- void *locked_ptr;
-- BOOL please_quit, just_started, just_underran;
-- pa_usec_t last_time, mmdev_period_usec;
--
-- INT64 clock_lastpos, clock_written;
--
-- struct list packet_free_head;
-- struct list packet_filled_head;
--};
--
--typedef struct _ACPacket
--{
-- struct list entry;
-- UINT64 qpcpos;
-- BYTE *data;
-- UINT32 discont;
--} ACPacket;
--
--static pa_context *pulse_ctx;
--static pa_mainloop *pulse_ml;
--
--/* Mixer format + period times */
--static WAVEFORMATEXTENSIBLE pulse_fmt[2];
--static REFERENCE_TIME pulse_min_period[2], pulse_def_period[2];
--
--static UINT g_phys_speakers_mask = 0;
--
--static const REFERENCE_TIME MinimumPeriod = 30000;
--static const REFERENCE_TIME DefaultPeriod = 100000;
--
--static pthread_mutex_t pulse_mutex;
--static pthread_cond_t pulse_cond = PTHREAD_COND_INITIALIZER;
--
--UINT8 mult_alaw_sample(UINT8, float);
--UINT8 mult_ulaw_sample(UINT8, float);
--
--static void pulse_lock(void)
--{
-- pthread_mutex_lock(&pulse_mutex);
--}
--
--static void pulse_unlock(void)
--{
-- pthread_mutex_unlock(&pulse_mutex);
--}
--
--static int pulse_cond_wait(void)
--{
-- return pthread_cond_wait(&pulse_cond, &pulse_mutex);
--}
--
--static void pulse_broadcast(void)
--{
-- pthread_cond_broadcast(&pulse_cond);
--}
--
--static void dump_attr(const pa_buffer_attr *attr)
--{
-- TRACE("maxlength: %u\n", attr->maxlength);
-- TRACE("minreq: %u\n", attr->minreq);
-- TRACE("fragsize: %u\n", attr->fragsize);
-- TRACE("tlength: %u\n", attr->tlength);
-- TRACE("prebuf: %u\n", attr->prebuf);
--}
--
--/* copied from kernelbase */
--static int muldiv(int a, int b, int c)
--{
-- LONGLONG ret;
--
-- if (!c) return -1;
--
-- /* We want to deal with a positive divisor to simplify the logic. */
-- if (c < 0)
-- {
-- a = -a;
-- c = -c;
-- }
--
-- /* If the result is positive, we "add" to round. else, we subtract to round. */
-- if ((a < 0 && b < 0) || (a >= 0 && b >= 0))
-- ret = (((LONGLONG)a * b) + (c / 2)) / c;
-- else
-- ret = (((LONGLONG)a * b) - (c / 2)) / c;
--
-- if (ret > 2147483647 || ret < -2147483647) return -1;
-- return ret;
--}
--
--/* Following pulseaudio design here, mainloop has the lock taken whenever
-- * it is handling something for pulse, and the lock is required whenever
-- * doing any pa_* call that can affect the state in any way
-- *
-- * pa_cond_wait is used when waiting on results, because the mainloop needs
-- * the same lock taken to affect the state
-- *
-- * This is basically the same as the pa_threaded_mainloop implementation,
-- * but that cannot be used because it uses pthread_create directly
-- *
-- * pa_threaded_mainloop_(un)lock -> pthread_mutex_(un)lock
-- * pa_threaded_mainloop_signal -> pthread_cond_broadcast
-- * pa_threaded_mainloop_wait -> pthread_cond_wait
-- */
--static int pulse_poll_func(struct pollfd *ufds, unsigned long nfds, int timeout, void *userdata)
--{
-- int r;
-- pulse_unlock();
-- r = poll(ufds, nfds, timeout);
-- pulse_lock();
-- return r;
--}
--
--static NTSTATUS pulse_main_loop(void *args)
--{
-- struct main_loop_params *params = args;
-- int ret;
-- pulse_lock();
-- pulse_ml = pa_mainloop_new();
-- pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL);
-- NtSetEvent(params->event, NULL);
-- pa_mainloop_run(pulse_ml, &ret);
-- pa_mainloop_free(pulse_ml);
-- pulse_unlock();
-- return STATUS_SUCCESS;
--}
--
--static void pulse_contextcallback(pa_context *c, void *userdata)
--{
-- switch (pa_context_get_state(c)) {
-- default:
-- FIXME("Unhandled state: %i\n", pa_context_get_state(c));
-- return;
--
-- case PA_CONTEXT_CONNECTING:
-- case PA_CONTEXT_UNCONNECTED:
-- case PA_CONTEXT_AUTHORIZING:
-- case PA_CONTEXT_SETTING_NAME:
-- case PA_CONTEXT_TERMINATED:
-- TRACE("State change to %i\n", pa_context_get_state(c));
-- return;
--
-- case PA_CONTEXT_READY:
-- TRACE("Ready\n");
-- break;
--
-- case PA_CONTEXT_FAILED:
-- WARN("Context failed: %s\n", pa_strerror(pa_context_errno(c)));
-- break;
-- }
-- pulse_broadcast();
--}
--
--static void pulse_stream_state(pa_stream *s, void *user)
--{
-- pa_stream_state_t state = pa_stream_get_state(s);
-- TRACE("Stream state changed to %i\n", state);
-- pulse_broadcast();
--}
--
--static void pulse_attr_update(pa_stream *s, void *user) {
-- const pa_buffer_attr *attr = pa_stream_get_buffer_attr(s);
-- TRACE("New attributes or device moved:\n");
-- dump_attr(attr);
--}
--
--static void pulse_underflow_callback(pa_stream *s, void *userdata)
--{
-- struct pulse_stream *stream = userdata;
-- WARN("%p: Underflow\n", userdata);
-- stream->just_underran = TRUE;
-- /* re-sync */
-- stream->pa_offs_bytes = stream->lcl_offs_bytes;
-- stream->pa_held_bytes = stream->held_bytes;
--}
--
--static void pulse_started_callback(pa_stream *s, void *userdata)
--{
-- TRACE("%p: (Re)started playing\n", userdata);
--}
--
--static void pulse_op_cb(pa_stream *s, int success, void *user)
--{
-- TRACE("Success: %i\n", success);
-- *(int*)user = success;
-- pulse_broadcast();
--}
--
--static void silence_buffer(pa_sample_format_t format, BYTE *buffer, UINT32 bytes)
--{
-- memset(buffer, format == PA_SAMPLE_U8 ? 0x80 : 0, bytes);
--}
--
--static BOOL pulse_stream_valid(struct pulse_stream *stream)
--{
-- return pa_stream_get_state(stream->stream) == PA_STREAM_READY;
--}
--
--static HRESULT pulse_connect(const char *name)
--{
-- if (pulse_ctx && PA_CONTEXT_IS_GOOD(pa_context_get_state(pulse_ctx)))
-- return S_OK;
-- if (pulse_ctx)
-- pa_context_unref(pulse_ctx);
--
-- pulse_ctx = pa_context_new(pa_mainloop_get_api(pulse_ml), name);
-- if (!pulse_ctx) {
-- ERR("Failed to create context\n");
-- return E_FAIL;
-- }
--
-- pa_context_set_state_callback(pulse_ctx, pulse_contextcallback, NULL);
--
-- TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(pulse_ctx), PA_API_VERSION);
-- if (pa_context_connect(pulse_ctx, NULL, 0, NULL) < 0)
-- goto fail;
--
-- /* Wait for connection */
-- while (pulse_cond_wait()) {
-- pa_context_state_t state = pa_context_get_state(pulse_ctx);
--
-- if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED)
-- goto fail;
--
-- if (state == PA_CONTEXT_READY)
-- break;
-- }
--
-- TRACE("Connected to server %s with protocol version: %i.\n",
-- pa_context_get_server(pulse_ctx),
-- pa_context_get_server_protocol_version(pulse_ctx));
-- return S_OK;
--
--fail:
-- pa_context_unref(pulse_ctx);
-- pulse_ctx = NULL;
-- return E_FAIL;
--}
--
--static DWORD pulse_channel_map_to_channel_mask(const pa_channel_map *map)
--{
-- int i;
-- DWORD mask = 0;
--
-- for (i = 0; i < map->channels; ++i) {
-- switch (map->map[i]) {
-- default: FIXME("Unhandled channel %s\n", pa_channel_position_to_string(map->map[i])); break;
-- case PA_CHANNEL_POSITION_FRONT_LEFT: mask |= SPEAKER_FRONT_LEFT; break;
-- case PA_CHANNEL_POSITION_MONO:
-- case PA_CHANNEL_POSITION_FRONT_CENTER: mask |= SPEAKER_FRONT_CENTER; break;
-- case PA_CHANNEL_POSITION_FRONT_RIGHT: mask |= SPEAKER_FRONT_RIGHT; break;
-- case PA_CHANNEL_POSITION_REAR_LEFT: mask |= SPEAKER_BACK_LEFT; break;
-- case PA_CHANNEL_POSITION_REAR_CENTER: mask |= SPEAKER_BACK_CENTER; break;
-- case PA_CHANNEL_POSITION_REAR_RIGHT: mask |= SPEAKER_BACK_RIGHT; break;
-- case PA_CHANNEL_POSITION_LFE: mask |= SPEAKER_LOW_FREQUENCY; break;
-- case PA_CHANNEL_POSITION_SIDE_LEFT: mask |= SPEAKER_SIDE_LEFT; break;
-- case PA_CHANNEL_POSITION_SIDE_RIGHT: mask |= SPEAKER_SIDE_RIGHT; break;
-- case PA_CHANNEL_POSITION_TOP_CENTER: mask |= SPEAKER_TOP_CENTER; break;
-- case PA_CHANNEL_POSITION_TOP_FRONT_LEFT: mask |= SPEAKER_TOP_FRONT_LEFT; break;
-- case PA_CHANNEL_POSITION_TOP_FRONT_CENTER: mask |= SPEAKER_TOP_FRONT_CENTER; break;
-- case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT: mask |= SPEAKER_TOP_FRONT_RIGHT; break;
-- case PA_CHANNEL_POSITION_TOP_REAR_LEFT: mask |= SPEAKER_TOP_BACK_LEFT; break;
-- case PA_CHANNEL_POSITION_TOP_REAR_CENTER: mask |= SPEAKER_TOP_BACK_CENTER; break;
-- case PA_CHANNEL_POSITION_TOP_REAR_RIGHT: mask |= SPEAKER_TOP_BACK_RIGHT; break;
-- case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: mask |= SPEAKER_FRONT_LEFT_OF_CENTER; break;
-- case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: mask |= SPEAKER_FRONT_RIGHT_OF_CENTER; break;
-- }
-- }
--
-- return mask;
--}
--
--/* For default PulseAudio render device, OR together all of the
-- * PKEY_AudioEndpoint_PhysicalSpeakers values of the sinks. */
--static void pulse_phys_speakers_cb(pa_context *c, const pa_sink_info *i, int eol, void *userdata)
--{
-- if (i)
-- g_phys_speakers_mask |= pulse_channel_map_to_channel_mask(&i->channel_map);
--}
--
--/* For most hardware on Windows, users must choose a configuration with an even
-- * number of channels (stereo, quad, 5.1, 7.1). Users can then disable
-- * channels, but those channels are still reported to applications from
-- * GetMixFormat! Some applications behave badly if given an odd number of
-- * channels (e.g. 2.1). Here, we find the nearest configuration that Windows
-- * would report for a given channel layout. */
--static void convert_channel_map(const pa_channel_map *pa_map, WAVEFORMATEXTENSIBLE *fmt)
--{
-- DWORD pa_mask = pulse_channel_map_to_channel_mask(pa_map);
--
-- TRACE("got mask for PA: 0x%x\n", pa_mask);
--
-- if (pa_map->channels == 1)
-- {
-- fmt->Format.nChannels = 1;
-- fmt->dwChannelMask = pa_mask;
-- return;
-- }
--
-- /* compare against known configurations and find smallest configuration
-- * which is a superset of the given speakers */
--
-- if (pa_map->channels <= 2 &&
-- (pa_mask & ~KSAUDIO_SPEAKER_STEREO) == 0)
-- {
-- fmt->Format.nChannels = 2;
-- fmt->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
-- return;
-- }
--
-- if (pa_map->channels <= 4 &&
-- (pa_mask & ~KSAUDIO_SPEAKER_QUAD) == 0)
-- {
-- fmt->Format.nChannels = 4;
-- fmt->dwChannelMask = KSAUDIO_SPEAKER_QUAD;
-- return;
-- }
--
-- if (pa_map->channels <= 4 &&
-- (pa_mask & ~KSAUDIO_SPEAKER_SURROUND) == 0)
-- {
-- fmt->Format.nChannels = 4;
-- fmt->dwChannelMask = KSAUDIO_SPEAKER_SURROUND;
-- return;
-- }
--
-- if (pa_map->channels <= 6 &&
-- (pa_mask & ~KSAUDIO_SPEAKER_5POINT1) == 0)
-- {
-- fmt->Format.nChannels = 6;
-- fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
-- return;
-- }
--
-- if (pa_map->channels <= 6 &&
-- (pa_mask & ~KSAUDIO_SPEAKER_5POINT1_SURROUND) == 0)
-- {
-- fmt->Format.nChannels = 6;
-- fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND;
-- return;
-- }
--
-- if (pa_map->channels <= 8 &&
-- (pa_mask & ~KSAUDIO_SPEAKER_7POINT1) == 0)
-- {
-- fmt->Format.nChannels = 8;
-- fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1;
-- return;
-- }
--
-- if (pa_map->channels <= 8 &&
-- (pa_mask & ~KSAUDIO_SPEAKER_7POINT1_SURROUND) == 0)
-- {
-- fmt->Format.nChannels = 8;
-- fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
-- return;
-- }
--
-- /* oddball format, report truthfully */
-- fmt->Format.nChannels = pa_map->channels;
-- fmt->dwChannelMask = pa_mask;
--}
--
--static void pulse_probe_settings(int render, WAVEFORMATEXTENSIBLE *fmt) {
-- WAVEFORMATEX *wfx = &fmt->Format;
-- pa_stream *stream;
-- pa_channel_map map;
-- pa_sample_spec ss;
-- pa_buffer_attr attr;
-- int ret;
-- unsigned int length = 0;
--
-- pa_channel_map_init_auto(&map, 2, PA_CHANNEL_MAP_ALSA);
-- ss.rate = 48000;
-- ss.format = PA_SAMPLE_FLOAT32LE;
-- ss.channels = map.channels;
--
-- attr.maxlength = -1;
-- attr.tlength = -1;
-- attr.minreq = attr.fragsize = pa_frame_size(&ss);
-- attr.prebuf = 0;
--
-- stream = pa_stream_new(pulse_ctx, "format test stream", &ss, &map);
-- if (stream)
-- pa_stream_set_state_callback(stream, pulse_stream_state, NULL);
-- if (!stream)
-- ret = -1;
-- else if (render)
-- ret = pa_stream_connect_playback(stream, NULL, &attr,
-- PA_STREAM_START_CORKED|PA_STREAM_FIX_RATE|PA_STREAM_FIX_CHANNELS|PA_STREAM_EARLY_REQUESTS, NULL, NULL);
-- else
-- ret = pa_stream_connect_record(stream, NULL, &attr, PA_STREAM_START_CORKED|PA_STREAM_FIX_RATE|PA_STREAM_FIX_CHANNELS|PA_STREAM_EARLY_REQUESTS);
-- if (ret >= 0) {
-- while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
-- pa_stream_get_state(stream) == PA_STREAM_CREATING)
-- {}
-- if (pa_stream_get_state(stream) == PA_STREAM_READY) {
-- ss = *pa_stream_get_sample_spec(stream);
-- map = *pa_stream_get_channel_map(stream);
-- if (render)
-- length = pa_stream_get_buffer_attr(stream)->minreq;
-- else
-- length = pa_stream_get_buffer_attr(stream)->fragsize;
-- pa_stream_disconnect(stream);
-- while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
-- pa_stream_get_state(stream) == PA_STREAM_READY)
-- {}
-- }
-- }
--
-- if (stream)
-- pa_stream_unref(stream);
--
-- if (length)
-- pulse_def_period[!render] = pulse_min_period[!render] = pa_bytes_to_usec(10 * length, &ss);
--
-- if (pulse_min_period[!render] < MinimumPeriod)
-- pulse_min_period[!render] = MinimumPeriod;
--
-- if (pulse_def_period[!render] < DefaultPeriod)
-- pulse_def_period[!render] = DefaultPeriod;
--
-- wfx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
-- wfx->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
--
-- convert_channel_map(&map, fmt);
--
-- wfx->wBitsPerSample = 8 * pa_sample_size_of_format(ss.format);
-- wfx->nSamplesPerSec = ss.rate;
-- wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8;
-- wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign;
-- if (ss.format != PA_SAMPLE_S24_32LE)
-- fmt->Samples.wValidBitsPerSample = wfx->wBitsPerSample;
-- else
-- fmt->Samples.wValidBitsPerSample = 24;
-- if (ss.format == PA_SAMPLE_FLOAT32LE)
-- fmt->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
-- else
-- fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
--}
--
--/* some poorly-behaved applications call audio functions during DllMain, so we
-- * have to do as much as possible without creating a new thread. this function
-- * sets up a synchronous connection to verify the server is running and query
-- * static data. */
--static NTSTATUS pulse_test_connect(void *args)
--{
-- struct test_connect_params *params = args;
-- struct pulse_config *config = params->config;
-- pa_operation *o;
-- int ret;
--
-- pulse_lock();
-- pulse_ml = pa_mainloop_new();
--
-- pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL);
--
-- pulse_ctx = pa_context_new(pa_mainloop_get_api(pulse_ml), params->name);
-- if (!pulse_ctx) {
-- ERR("Failed to create context\n");
-- pa_mainloop_free(pulse_ml);
-- pulse_ml = NULL;
-- pulse_unlock();
-- params->result = E_FAIL;
-- return STATUS_SUCCESS;
-- }
--
-- pa_context_set_state_callback(pulse_ctx, pulse_contextcallback, NULL);
--
-- TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(pulse_ctx), PA_API_VERSION);
-- if (pa_context_connect(pulse_ctx, NULL, 0, NULL) < 0)
-- goto fail;
--
-- /* Wait for connection */
-- while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0) {
-- pa_context_state_t state = pa_context_get_state(pulse_ctx);
--
-- if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED)
-- goto fail;
--
-- if (state == PA_CONTEXT_READY)
-- break;
-- }
--
-- if (pa_context_get_state(pulse_ctx) != PA_CONTEXT_READY)
-- goto fail;
--
-- TRACE("Test-connected to server %s with protocol version: %i.\n",
-- pa_context_get_server(pulse_ctx),
-- pa_context_get_server_protocol_version(pulse_ctx));
--
-- pulse_probe_settings(1, &pulse_fmt[0]);
-- pulse_probe_settings(0, &pulse_fmt[1]);
--
-- g_phys_speakers_mask = 0;
-- o = pa_context_get_sink_info_list(pulse_ctx, &pulse_phys_speakers_cb, NULL);
-- if (o) {
-- while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
-- pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-- {}
-- pa_operation_unref(o);
-- }
--
-- pa_context_unref(pulse_ctx);
-- pulse_ctx = NULL;
-- pa_mainloop_free(pulse_ml);
-- pulse_ml = NULL;
--
-- config->speakers_mask = g_phys_speakers_mask;
-- config->modes[0].format = pulse_fmt[0];
-- config->modes[0].def_period = pulse_def_period[0];
-- config->modes[0].min_period = pulse_min_period[0];
-- config->modes[1].format = pulse_fmt[1];
-- config->modes[1].def_period = pulse_def_period[1];
-- config->modes[1].min_period = pulse_min_period[1];
--
-- pulse_unlock();
--
-- params->result = S_OK;
-- return STATUS_SUCCESS;
--
--fail:
-- pa_context_unref(pulse_ctx);
-- pulse_ctx = NULL;
-- pa_mainloop_free(pulse_ml);
-- pulse_ml = NULL;
-- pulse_unlock();
-- params->result = E_FAIL;
-- return STATUS_SUCCESS;
--}
--
--static DWORD get_channel_mask(unsigned int channels)
--{
-- switch(channels) {
-- case 0:
-- return 0;
-- case 1:
-- return KSAUDIO_SPEAKER_MONO;
-- case 2:
-- return KSAUDIO_SPEAKER_STEREO;
-- case 3:
-- return KSAUDIO_SPEAKER_STEREO | SPEAKER_LOW_FREQUENCY;
-- case 4:
-- return KSAUDIO_SPEAKER_QUAD; /* not _SURROUND */
-- case 5:
-- return KSAUDIO_SPEAKER_QUAD | SPEAKER_LOW_FREQUENCY;
-- case 6:
-- return KSAUDIO_SPEAKER_5POINT1; /* not 5POINT1_SURROUND */
-- case 7:
-- return KSAUDIO_SPEAKER_5POINT1 | SPEAKER_BACK_CENTER;
-- case 8:
-- return KSAUDIO_SPEAKER_7POINT1_SURROUND; /* Vista deprecates 7POINT1 */
-- }
-- FIXME("Unknown speaker configuration: %u\n", channels);
-- return 0;
--}
--
--static const enum pa_channel_position pulse_pos_from_wfx[] = {
-- PA_CHANNEL_POSITION_FRONT_LEFT,
-- PA_CHANNEL_POSITION_FRONT_RIGHT,
-- PA_CHANNEL_POSITION_FRONT_CENTER,
-- PA_CHANNEL_POSITION_LFE,
-- PA_CHANNEL_POSITION_REAR_LEFT,
-- PA_CHANNEL_POSITION_REAR_RIGHT,
-- PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
-- PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
-- PA_CHANNEL_POSITION_REAR_CENTER,
-- PA_CHANNEL_POSITION_SIDE_LEFT,
-- PA_CHANNEL_POSITION_SIDE_RIGHT,
-- PA_CHANNEL_POSITION_TOP_CENTER,
-- PA_CHANNEL_POSITION_TOP_FRONT_LEFT,
-- PA_CHANNEL_POSITION_TOP_FRONT_CENTER,
-- PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,
-- PA_CHANNEL_POSITION_TOP_REAR_LEFT,
-- PA_CHANNEL_POSITION_TOP_REAR_CENTER,
-- PA_CHANNEL_POSITION_TOP_REAR_RIGHT
--};
--
--static HRESULT pulse_spec_from_waveformat(struct pulse_stream *stream, const WAVEFORMATEX *fmt)
--{
-- pa_channel_map_init(&stream->map);
-- stream->ss.rate = fmt->nSamplesPerSec;
-- stream->ss.format = PA_SAMPLE_INVALID;
--
-- switch(fmt->wFormatTag) {
-- case WAVE_FORMAT_IEEE_FLOAT:
-- if (!fmt->nChannels || fmt->nChannels > 2 || fmt->wBitsPerSample != 32)
-- break;
-- stream->ss.format = PA_SAMPLE_FLOAT32LE;
-- pa_channel_map_init_auto(&stream->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
-- break;
-- case WAVE_FORMAT_PCM:
-- if (!fmt->nChannels || fmt->nChannels > 2)
-- break;
-- if (fmt->wBitsPerSample == 8)
-- stream->ss.format = PA_SAMPLE_U8;
-- else if (fmt->wBitsPerSample == 16)
-- stream->ss.format = PA_SAMPLE_S16LE;
-- else
-- return AUDCLNT_E_UNSUPPORTED_FORMAT;
-- pa_channel_map_init_auto(&stream->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
-- break;
-- case WAVE_FORMAT_EXTENSIBLE: {
-- WAVEFORMATEXTENSIBLE *wfe = (WAVEFORMATEXTENSIBLE*)fmt;
-- DWORD mask = wfe->dwChannelMask;
-- DWORD i = 0, j;
-- if (fmt->cbSize != (sizeof(*wfe) - sizeof(*fmt)) && fmt->cbSize != sizeof(*wfe))
-- break;
-- if (IsEqualGUID(&wfe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) &&
-- (!wfe->Samples.wValidBitsPerSample || wfe->Samples.wValidBitsPerSample == 32) &&
-- fmt->wBitsPerSample == 32)
-- stream->ss.format = PA_SAMPLE_FLOAT32LE;
-- else if (IsEqualGUID(&wfe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) {
-- DWORD valid = wfe->Samples.wValidBitsPerSample;
-- if (!valid)
-- valid = fmt->wBitsPerSample;
-- if (!valid || valid > fmt->wBitsPerSample)
-- break;
-- switch (fmt->wBitsPerSample) {
-- case 8:
-- if (valid == 8)
-- stream->ss.format = PA_SAMPLE_U8;
-- break;
-- case 16:
-- if (valid == 16)
-- stream->ss.format = PA_SAMPLE_S16LE;
-- break;
-- case 24:
-- if (valid == 24)
-- stream->ss.format = PA_SAMPLE_S24LE;
-- break;
-- case 32:
-- if (valid == 24)
-- stream->ss.format = PA_SAMPLE_S24_32LE;
-- else if (valid == 32)
-- stream->ss.format = PA_SAMPLE_S32LE;
-- break;
-- default:
-- return AUDCLNT_E_UNSUPPORTED_FORMAT;
-- }
-- }
-- stream->map.channels = fmt->nChannels;
-- if (!mask || (mask & (SPEAKER_ALL|SPEAKER_RESERVED)))
-- mask = get_channel_mask(fmt->nChannels);
-- for (j = 0; j < ARRAY_SIZE(pulse_pos_from_wfx) && i < fmt->nChannels; ++j) {
-- if (mask & (1 << j))
-- stream->map.map[i++] = pulse_pos_from_wfx[j];
-- }
--
-- /* Special case for mono since pulse appears to map it differently */
-- if (mask == SPEAKER_FRONT_CENTER)
-- stream->map.map[0] = PA_CHANNEL_POSITION_MONO;
--
-- if (i < fmt->nChannels || (mask & SPEAKER_RESERVED)) {
-- stream->map.channels = 0;
-- ERR("Invalid channel mask: %i/%i and %x(%x)\n", i, fmt->nChannels, mask, wfe->dwChannelMask);
-- break;
-- }
-- break;
-- }
-- case WAVE_FORMAT_ALAW:
-- case WAVE_FORMAT_MULAW:
-- if (fmt->wBitsPerSample != 8) {
-- FIXME("Unsupported bpp %u for LAW\n", fmt->wBitsPerSample);
-- return AUDCLNT_E_UNSUPPORTED_FORMAT;
-- }
-- if (fmt->nChannels != 1 && fmt->nChannels != 2) {
-- FIXME("Unsupported channels %u for LAW\n", fmt->nChannels);
-- return AUDCLNT_E_UNSUPPORTED_FORMAT;
-- }
-- stream->ss.format = fmt->wFormatTag == WAVE_FORMAT_MULAW ? PA_SAMPLE_ULAW : PA_SAMPLE_ALAW;
-- pa_channel_map_init_auto(&stream->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
-- break;
-- default:
-- WARN("Unhandled tag %x\n", fmt->wFormatTag);
-- return AUDCLNT_E_UNSUPPORTED_FORMAT;
-- }
-- stream->ss.channels = stream->map.channels;
-- if (!pa_channel_map_valid(&stream->map) || stream->ss.format == PA_SAMPLE_INVALID) {
-- ERR("Invalid format! Channel spec valid: %i, format: %i\n",
-- pa_channel_map_valid(&stream->map), stream->ss.format);
-- return AUDCLNT_E_UNSUPPORTED_FORMAT;
-- }
-- return S_OK;
--}
--
--static HRESULT pulse_stream_connect(struct pulse_stream *stream, UINT32 period_bytes)
--{
-- int ret;
-- char buffer[64];
-- static LONG number;
-- pa_buffer_attr attr;
--
-- ret = InterlockedIncrement(&number);
-- sprintf(buffer, "audio stream #%i", ret);
-- stream->stream = pa_stream_new(pulse_ctx, buffer, &stream->ss, &stream->map);
--
-- if (!stream->stream) {
-- WARN("pa_stream_new returned error %i\n", pa_context_errno(pulse_ctx));
-- return AUDCLNT_E_ENDPOINT_CREATE_FAILED;
-- }
--
-- pa_stream_set_state_callback(stream->stream, pulse_stream_state, stream);
-- pa_stream_set_buffer_attr_callback(stream->stream, pulse_attr_update, stream);
-- pa_stream_set_moved_callback(stream->stream, pulse_attr_update, stream);
--
-- /* PulseAudio will fill in correct values */
-- attr.minreq = attr.fragsize = period_bytes;
-- attr.tlength = period_bytes * 3;
-- attr.maxlength = stream->bufsize_frames * pa_frame_size(&stream->ss);
-- attr.prebuf = pa_frame_size(&stream->ss);
-- dump_attr(&attr);
-- if (stream->dataflow == eRender)
-- ret = pa_stream_connect_playback(stream->stream, NULL, &attr,
-- PA_STREAM_START_CORKED|PA_STREAM_START_UNMUTED|PA_STREAM_ADJUST_LATENCY, NULL, NULL);
-- else
-- ret = pa_stream_connect_record(stream->stream, NULL, &attr,
-- PA_STREAM_START_CORKED|PA_STREAM_START_UNMUTED|PA_STREAM_ADJUST_LATENCY);
-- if (ret < 0) {
-- WARN("Returns %i\n", ret);
-- return AUDCLNT_E_ENDPOINT_CREATE_FAILED;
-- }
-- while (pa_stream_get_state(stream->stream) == PA_STREAM_CREATING)
-- pulse_cond_wait();
-- if (pa_stream_get_state(stream->stream) != PA_STREAM_READY)
-- return AUDCLNT_E_ENDPOINT_CREATE_FAILED;
--
-- if (stream->dataflow == eRender) {
-- pa_stream_set_underflow_callback(stream->stream, pulse_underflow_callback, stream);
-- pa_stream_set_started_callback(stream->stream, pulse_started_callback, stream);
-- }
-- return S_OK;
--}
--
--static NTSTATUS pulse_create_stream(void *args)
--{
-- struct create_stream_params *params = args;
-- REFERENCE_TIME period, duration = params->duration;
-- struct pulse_stream *stream;
-- unsigned int i, bufsize_bytes;
-- HRESULT hr;
--
-- pulse_lock();
--
-- if (FAILED(params->result = pulse_connect(params->name)))
-- {
-- pulse_unlock();
-- return STATUS_SUCCESS;
-- }
--
-- if (!(stream = calloc(1, sizeof(*stream))))
-- {
-- pulse_unlock();
-- params->result = E_OUTOFMEMORY;
-- return STATUS_SUCCESS;
-- }
--
-- stream->dataflow = params->dataflow;
-- for (i = 0; i < ARRAY_SIZE(stream->vol); ++i)
-- stream->vol[i] = 1.f;
--
-- hr = pulse_spec_from_waveformat(stream, params->fmt);
-- TRACE("Obtaining format returns %08x\n", hr);
--
-- if (FAILED(hr))
-- goto exit;
--
-- period = pulse_def_period[stream->dataflow == eCapture];
-- if (duration < 3 * period)
-- duration = 3 * period;
--
-- stream->period_bytes = pa_frame_size(&stream->ss) * muldiv(period, stream->ss.rate, 10000000);
--
-- stream->bufsize_frames = ceil((duration / 10000000.) * params->fmt->nSamplesPerSec);
-- bufsize_bytes = stream->bufsize_frames * pa_frame_size(&stream->ss);
-- stream->mmdev_period_usec = period / 10;
--
-- stream->share = params->mode;
-- stream->flags = params->flags;
-- hr = pulse_stream_connect(stream, stream->period_bytes);
-- if (SUCCEEDED(hr)) {
-- UINT32 unalign;
-- const pa_buffer_attr *attr = pa_stream_get_buffer_attr(stream->stream);
-- stream->attr = *attr;
-- /* Update frames according to new size */
-- dump_attr(attr);
-- if (stream->dataflow == eRender) {
-- stream->alloc_size = stream->real_bufsize_bytes =
-- stream->bufsize_frames * 2 * pa_frame_size(&stream->ss);
-- if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer,
-- 0, &stream->real_bufsize_bytes, MEM_COMMIT, PAGE_READWRITE))
-- hr = E_OUTOFMEMORY;
-- } else {
-- UINT32 i, capture_packets;
--
-- if ((unalign = bufsize_bytes % stream->period_bytes))
-- bufsize_bytes += stream->period_bytes - unalign;
-- stream->bufsize_frames = bufsize_bytes / pa_frame_size(&stream->ss);
-- stream->real_bufsize_bytes = bufsize_bytes;
--
-- capture_packets = stream->real_bufsize_bytes / stream->period_bytes;
--
-- stream->alloc_size = stream->real_bufsize_bytes + capture_packets * sizeof(ACPacket);
-- if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer,
-- 0, &stream->alloc_size, MEM_COMMIT, PAGE_READWRITE))
-- hr = E_OUTOFMEMORY;
-- else {
-- ACPacket *cur_packet = (ACPacket*)((char*)stream->local_buffer + stream->real_bufsize_bytes);
-- BYTE *data = stream->local_buffer;
-- silence_buffer(stream->ss.format, stream->local_buffer, stream->real_bufsize_bytes);
-- list_init(&stream->packet_free_head);
-- list_init(&stream->packet_filled_head);
-- for (i = 0; i < capture_packets; ++i, ++cur_packet) {
-- list_add_tail(&stream->packet_free_head, &cur_packet->entry);
-- cur_packet->data = data;
-- data += stream->period_bytes;
-- }
-- }
-- }
-- }
--
-- *params->channel_count = stream->ss.channels;
-- *params->stream = stream;
--
--exit:
-- if (FAILED(params->result = hr)) {
-- free(stream->local_buffer);
-- if (stream->stream) {
-- pa_stream_disconnect(stream->stream);
-- pa_stream_unref(stream->stream);
-- free(stream);
-- }
-- }
--
-- pulse_unlock();
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_release_stream(void *args)
--{
-- struct release_stream_params *params = args;
-- struct pulse_stream *stream = params->stream;
--
-- if(params->timer) {
-- stream->please_quit = TRUE;
-- NtWaitForSingleObject(params->timer, FALSE, NULL);
-- NtClose(params->timer);
-- }
--
-- pulse_lock();
-- if (PA_STREAM_IS_GOOD(pa_stream_get_state(stream->stream))) {
-- pa_stream_disconnect(stream->stream);
-- while (PA_STREAM_IS_GOOD(pa_stream_get_state(stream->stream)))
-- pulse_cond_wait();
-- }
-- pa_stream_unref(stream->stream);
-- pulse_unlock();
--
-- if (stream->tmp_buffer)
-- NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer,
-- &stream->tmp_buffer_bytes, MEM_RELEASE);
-- if (stream->local_buffer)
-- NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer,
-- &stream->alloc_size, MEM_RELEASE);
-- free(stream->peek_buffer);
-- free(stream);
-- return STATUS_SUCCESS;
--}
--
--static int write_buffer(const struct pulse_stream *stream, BYTE *buffer, UINT32 bytes)
--{
-- const float *vol = stream->vol;
-- UINT32 i, channels, mute = 0;
-- BOOL adjust = FALSE;
-- BYTE *end;
--
-- if (!bytes) return 0;
--
-- /* Adjust the buffer based on the volume for each channel */
-- channels = stream->ss.channels;
-- for (i = 0; i < channels; i++)
-- {
-- adjust |= vol[i] != 1.0f;
-- if (vol[i] == 0.0f)
-- mute++;
-- }
-- if (mute == channels)
-- {
-- silence_buffer(stream->ss.format, buffer, bytes);
-- goto write;
-- }
-- if (!adjust) goto write;
--
-- end = buffer + bytes;
-- switch (stream->ss.format)
-- {
--#ifndef WORDS_BIGENDIAN
--#define PROCESS_BUFFER(type) do \
--{ \
-- type *p = (type*)buffer; \
-- do \
-- { \
-- for (i = 0; i < channels; i++) \
-- p[i] = p[i] * vol[i]; \
-- p += i; \
-- } while ((BYTE*)p != end); \
--} while (0)
-- case PA_SAMPLE_S16LE:
-- PROCESS_BUFFER(INT16);
-- break;
-- case PA_SAMPLE_S32LE:
-- PROCESS_BUFFER(INT32);
-- break;
-- case PA_SAMPLE_FLOAT32LE:
-- PROCESS_BUFFER(float);
-- break;
--#undef PROCESS_BUFFER
-- case PA_SAMPLE_S24_32LE:
-- {
-- UINT32 *p = (UINT32*)buffer;
-- do
-- {
-- for (i = 0; i < channels; i++)
-- {
-- p[i] = (INT32)((INT32)(p[i] << 8) * vol[i]);
-- p[i] >>= 8;
-- }
-- p += i;
-- } while ((BYTE*)p != end);
-- break;
-- }
-- case PA_SAMPLE_S24LE:
-- {
-- /* do it 12 bytes at a time until it is no longer possible */
-- UINT32 *q = (UINT32*)buffer;
-- BYTE *p;
--
-- i = 0;
-- while (end - (BYTE*)q >= 12)
-- {
-- UINT32 v[4], k;
-- v[0] = q[0] << 8;
-- v[1] = q[1] << 16 | (q[0] >> 16 & ~0xff);
-- v[2] = q[2] << 24 | (q[1] >> 8 & ~0xff);
-- v[3] = q[2] & ~0xff;
-- for (k = 0; k < 4; k++)
-- {
-- v[k] = (INT32)((INT32)v[k] * vol[i]);
-- if (++i == channels) i = 0;
-- }
-- *q++ = v[0] >> 8 | (v[1] & ~0xff) << 16;
-- *q++ = v[1] >> 16 | (v[2] & ~0xff) << 8;
-- *q++ = v[2] >> 24 | (v[3] & ~0xff);
-- }
-- p = (BYTE*)q;
-- while (p != end)
-- {
-- UINT32 v = (INT32)((INT32)(p[0] << 8 | p[1] << 16 | p[2] << 24) * vol[i]);
-- *p++ = v >> 8 & 0xff;
-- *p++ = v >> 16 & 0xff;
-- *p++ = v >> 24;
-- if (++i == channels) i = 0;
-- }
-- break;
-- }
--#endif
-- case PA_SAMPLE_U8:
-- {
-- UINT8 *p = (UINT8*)buffer;
-- do
-- {
-- for (i = 0; i < channels; i++)
-- p[i] = (int)((p[i] - 128) * vol[i]) + 128;
-- p += i;
-- } while ((BYTE*)p != end);
-- break;
-- }
-- case PA_SAMPLE_ALAW:
-- {
-- UINT8 *p = (UINT8*)buffer;
-- do
-- {
-- for (i = 0; i < channels; i++)
-- p[i] = mult_alaw_sample(p[i], vol[i]);
-- p += i;
-- } while ((BYTE*)p != end);
-- break;
-- }
-- case PA_SAMPLE_ULAW:
-- {
-- UINT8 *p = (UINT8*)buffer;
-- do
-- {
-- for (i = 0; i < channels; i++)
-- p[i] = mult_ulaw_sample(p[i], vol[i]);
-- p += i;
-- } while ((BYTE*)p != end);
-- break;
-- }
-- default:
-- TRACE("Unhandled format %i, not adjusting volume.\n", stream->ss.format);
-- break;
-- }
--
--write:
-- return pa_stream_write(stream->stream, buffer, bytes, NULL, 0, PA_SEEK_RELATIVE);
--}
--
--static void pulse_write(struct pulse_stream *stream)
--{
-- /* write as much data to PA as we can */
-- UINT32 to_write;
-- BYTE *buf = stream->local_buffer + stream->pa_offs_bytes;
-- UINT32 bytes = pa_stream_writable_size(stream->stream);
--
-- if (stream->just_underran)
-- {
-- /* prebuffer with silence if needed */
-- if(stream->pa_held_bytes < bytes){
-- to_write = bytes - stream->pa_held_bytes;
-- TRACE("prebuffering %u frames of silence\n",
-- (int)(to_write / pa_frame_size(&stream->ss)));
-- buf = calloc(1, to_write);
-- pa_stream_write(stream->stream, buf, to_write, NULL, 0, PA_SEEK_RELATIVE);
-- free(buf);
-- }
--
-- stream->just_underran = FALSE;
-- }
--
-- buf = stream->local_buffer + stream->pa_offs_bytes;
-- TRACE("held: %lu, avail: %u\n", stream->pa_held_bytes, bytes);
-- bytes = min(stream->pa_held_bytes, bytes);
--
-- if (stream->pa_offs_bytes + bytes > stream->real_bufsize_bytes)
-- {
-- to_write = stream->real_bufsize_bytes - stream->pa_offs_bytes;
-- TRACE("writing small chunk of %u bytes\n", to_write);
-- write_buffer(stream, buf, to_write);
-- stream->pa_held_bytes -= to_write;
-- to_write = bytes - to_write;
-- stream->pa_offs_bytes = 0;
-- buf = stream->local_buffer;
-- }
-- else
-- to_write = bytes;
--
-- TRACE("writing main chunk of %u bytes\n", to_write);
-- write_buffer(stream, buf, to_write);
-- stream->pa_offs_bytes += to_write;
-- stream->pa_offs_bytes %= stream->real_bufsize_bytes;
-- stream->pa_held_bytes -= to_write;
--}
--
--static void pulse_read(struct pulse_stream *stream)
--{
-- size_t bytes = pa_stream_readable_size(stream->stream);
--
-- TRACE("Readable total: %zu, fragsize: %u\n", bytes, pa_stream_get_buffer_attr(stream->stream)->fragsize);
--
-- bytes += stream->peek_len - stream->peek_ofs;
--
-- while (bytes >= stream->period_bytes)
-- {
-- BYTE *dst = NULL, *src;
-- size_t src_len, copy, rem = stream->period_bytes;
--
-- if (stream->started)
-- {
-- LARGE_INTEGER stamp, freq;
-- ACPacket *p, *next;
--
-- if (!(p = (ACPacket*)list_head(&stream->packet_free_head)))
-- {
-- p = (ACPacket*)list_head(&stream->packet_filled_head);
-- if (!p) return;
-- if (!p->discont) {
-- next = (ACPacket*)p->entry.next;
-- next->discont = 1;
-- } else
-- p = (ACPacket*)list_tail(&stream->packet_filled_head);
-- }
-- else
-- {
-- stream->held_bytes += stream->period_bytes;
-- }
-- NtQueryPerformanceCounter(&stamp, &freq);
-- p->qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
-- p->discont = 0;
-- list_remove(&p->entry);
-- list_add_tail(&stream->packet_filled_head, &p->entry);
--
-- dst = p->data;
-- }
--
-- while (rem)
-- {
-- if (stream->peek_len)
-- {
-- copy = min(rem, stream->peek_len - stream->peek_ofs);
--
-- if (dst)
-- {
-- memcpy(dst, stream->peek_buffer + stream->peek_ofs, copy);
-- dst += copy;
-- }
--
-- rem -= copy;
-- stream->peek_ofs += copy;
-- if(stream->peek_len == stream->peek_ofs)
-- stream->peek_len = stream->peek_ofs = 0;
--
-- }
-- else if (pa_stream_peek(stream->stream, (const void**)&src, &src_len) == 0 && src_len)
-- {
-- copy = min(rem, src_len);
--
-- if (dst) {
-- if(src)
-- memcpy(dst, src, copy);
-- else
-- silence_buffer(stream->ss.format, dst, copy);
--
-- dst += copy;
-- }
--
-- rem -= copy;
--
-- if (copy < src_len)
-- {
-- if (src_len > stream->peek_buffer_len)
-- {
-- free(stream->peek_buffer);
-- stream->peek_buffer = malloc(src_len);
-- stream->peek_buffer_len = src_len;
-- }
--
-- if(src)
-- memcpy(stream->peek_buffer, src + copy, src_len - copy);
-- else
-- silence_buffer(stream->ss.format, stream->peek_buffer, src_len - copy);
--
-- stream->peek_len = src_len - copy;
-- stream->peek_ofs = 0;
-- }
--
-- pa_stream_drop(stream->stream);
-- }
-- }
--
-- bytes -= stream->period_bytes;
-- }
--}
--
--static NTSTATUS pulse_timer_loop(void *args)
--{
-- struct timer_loop_params *params = args;
-- struct pulse_stream *stream = params->stream;
-- LARGE_INTEGER delay;
-- UINT32 adv_bytes;
-- int success;
-- pa_operation *o;
--
-- pulse_lock();
-- delay.QuadPart = -stream->mmdev_period_usec * 10;
-- pa_stream_get_time(stream->stream, &stream->last_time);
-- pulse_unlock();
--
-- while (!stream->please_quit)
-- {
-- pa_usec_t now, adv_usec = 0;
-- int err;
--
-- NtDelayExecution(FALSE, &delay);
--
-- pulse_lock();
--
-- delay.QuadPart = -stream->mmdev_period_usec * 10;
--
-- o = pa_stream_update_timing_info(stream->stream, pulse_op_cb, &success);
-- if (o)
-- {
-- while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-- pulse_cond_wait();
-- pa_operation_unref(o);
-- }
-- err = pa_stream_get_time(stream->stream, &now);
-- if (err == 0)
-- {
-- TRACE("got now: %s, last time: %s\n", wine_dbgstr_longlong(now), wine_dbgstr_longlong(stream->last_time));
-- if (stream->started && (stream->dataflow == eCapture || stream->held_bytes))
-- {
-- if(stream->just_underran)
-- {
-- stream->last_time = now;
-- stream->just_started = TRUE;
-- }
--
-- if (stream->just_started)
-- {
-- /* let it play out a period to absorb some latency and get accurate timing */
-- pa_usec_t diff = now - stream->last_time;
--
-- if (diff > stream->mmdev_period_usec)
-- {
-- stream->just_started = FALSE;
-- stream->last_time = now;
-- }
-- }
-- else
-- {
-- INT32 adjust = stream->last_time + stream->mmdev_period_usec - now;
--
-- adv_usec = now - stream->last_time;
--
-- if(adjust > ((INT32)(stream->mmdev_period_usec / 2)))
-- adjust = stream->mmdev_period_usec / 2;
-- else if(adjust < -((INT32)(stream->mmdev_period_usec / 2)))
-- adjust = -1 * stream->mmdev_period_usec / 2;
--
-- delay.QuadPart = -(stream->mmdev_period_usec + adjust) * 10;
--
-- stream->last_time += stream->mmdev_period_usec;
-- }
--
-- if (stream->dataflow == eRender)
-- {
-- pulse_write(stream);
--
-- /* regardless of what PA does, advance one period */
-- adv_bytes = min(stream->period_bytes, stream->held_bytes);
-- stream->lcl_offs_bytes += adv_bytes;
-- stream->lcl_offs_bytes %= stream->real_bufsize_bytes;
-- stream->held_bytes -= adv_bytes;
-- }
-- else if(stream->dataflow == eCapture)
-- {
-- pulse_read(stream);
-- }
-- }
-- else
-- {
-- stream->last_time = now;
-- delay.QuadPart = -stream->mmdev_period_usec * 10;
-- }
-- }
--
-- if (stream->event)
-- NtSetEvent(stream->event, NULL);
--
-- TRACE("%p after update, adv usec: %d, held: %u, delay usec: %u\n",
-- stream, (int)adv_usec,
-- (int)(stream->held_bytes/ pa_frame_size(&stream->ss)),
-- (unsigned int)(-delay.QuadPart / 10));
--
-- pulse_unlock();
-- }
--
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_start(void *args)
--{
-- struct start_params *params = args;
-- struct pulse_stream *stream = params->stream;
-- int success;
-- pa_operation *o;
--
-- params->result = S_OK;
-- pulse_lock();
-- if (!pulse_stream_valid(stream))
-- {
-- pulse_unlock();
-- params->result = S_OK;
-- return STATUS_SUCCESS;
-- }
--
-- if ((stream->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) && !stream->event)
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_EVENTHANDLE_NOT_SET;
-- return STATUS_SUCCESS;
-- }
--
-- if (stream->started)
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_NOT_STOPPED;
-- return STATUS_SUCCESS;
-- }
--
-- pulse_write(stream);
--
-- if (pa_stream_is_corked(stream->stream))
-- {
-- o = pa_stream_cork(stream->stream, 0, pulse_op_cb, &success);
-- if (o)
-- {
-- while(pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-- pulse_cond_wait();
-- pa_operation_unref(o);
-- }
-- else
-- success = 0;
-- if (!success)
-- params->result = E_FAIL;
-- }
--
-- if (SUCCEEDED(params->result))
-- {
-- stream->started = TRUE;
-- stream->just_started = TRUE;
-- }
-- pulse_unlock();
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_stop(void *args)
--{
-- struct stop_params *params = args;
-- struct pulse_stream *stream = params->stream;
-- pa_operation *o;
-- int success;
--
-- pulse_lock();
-- if (!pulse_stream_valid(stream))
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_DEVICE_INVALIDATED;
-- return STATUS_SUCCESS;
-- }
--
-- if (!stream->started)
-- {
-- pulse_unlock();
-- params->result = S_FALSE;
-- return STATUS_SUCCESS;
-- }
--
-- params->result = S_OK;
-- if (stream->dataflow == eRender)
-- {
-- o = pa_stream_cork(stream->stream, 1, pulse_op_cb, &success);
-- if (o)
-- {
-- while(pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-- pulse_cond_wait();
-- pa_operation_unref(o);
-- }
-- else
-- success = 0;
-- if (!success)
-- params->result = E_FAIL;
-- }
-- if (SUCCEEDED(params->result))
-- stream->started = FALSE;
-- pulse_unlock();
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_reset(void *args)
--{
-- struct reset_params *params = args;
-- struct pulse_stream *stream = params->stream;
--
-- pulse_lock();
-- if (!pulse_stream_valid(stream))
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_DEVICE_INVALIDATED;
-- return STATUS_SUCCESS;
-- }
--
-- if (stream->started)
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_NOT_STOPPED;
-- return STATUS_SUCCESS;
-- }
--
-- if (stream->locked)
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_BUFFER_OPERATION_PENDING;
-- return STATUS_SUCCESS;
-- }
--
-- if (stream->dataflow == eRender)
-- {
-- /* If there is still data in the render buffer it needs to be removed from the server */
-- int success = 0;
-- if (stream->held_bytes)
-- {
-- pa_operation *o = pa_stream_flush(stream->stream, pulse_op_cb, &success);
-- if (o)
-- {
-- while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
-- pulse_cond_wait();
-- pa_operation_unref(o);
-- }
-- }
-- if (success || !stream->held_bytes)
-- {
-- stream->clock_lastpos = stream->clock_written = 0;
-- stream->pa_offs_bytes = stream->lcl_offs_bytes = 0;
-- stream->held_bytes = stream->pa_held_bytes = 0;
-- }
-- }
-- else
-- {
-- ACPacket *p;
-- stream->clock_written += stream->held_bytes;
-- stream->held_bytes = 0;
--
-- if ((p = stream->locked_ptr))
-- {
-- stream->locked_ptr = NULL;
-- list_add_tail(&stream->packet_free_head, &p->entry);
-- }
-- list_move_tail(&stream->packet_free_head, &stream->packet_filled_head);
-- }
-- pulse_unlock();
-- params->result = S_OK;
-- return STATUS_SUCCESS;
--}
--
--static BOOL alloc_tmp_buffer(struct pulse_stream *stream, SIZE_T bytes)
--{
-- if (stream->tmp_buffer_bytes >= bytes)
-- return TRUE;
--
-- if (stream->tmp_buffer)
-- {
-- NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer,
-- &stream->tmp_buffer_bytes, MEM_RELEASE);
-- stream->tmp_buffer = NULL;
-- stream->tmp_buffer_bytes = 0;
-- }
-- if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer,
-- 0, &bytes, MEM_COMMIT, PAGE_READWRITE))
-- return FALSE;
--
-- stream->tmp_buffer_bytes = bytes;
-- return TRUE;
--}
--
--static UINT32 pulse_render_padding(struct pulse_stream *stream)
--{
-- return stream->held_bytes / pa_frame_size(&stream->ss);
--}
--
--static UINT32 pulse_capture_padding(struct pulse_stream *stream)
--{
-- ACPacket *packet = stream->locked_ptr;
-- if (!packet && !list_empty(&stream->packet_filled_head))
-- {
-- packet = (ACPacket*)list_head(&stream->packet_filled_head);
-- stream->locked_ptr = packet;
-- list_remove(&packet->entry);
-- }
-- return stream->held_bytes / pa_frame_size(&stream->ss);
--}
--
--static NTSTATUS pulse_get_render_buffer(void *args)
--{
-- struct get_render_buffer_params *params = args;
-- struct pulse_stream *stream = params->stream;
-- size_t bytes;
-- UINT32 wri_offs_bytes;
--
-- pulse_lock();
-- if (!pulse_stream_valid(stream))
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_DEVICE_INVALIDATED;
-- return STATUS_SUCCESS;
-- }
--
-- if (stream->locked)
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_OUT_OF_ORDER;
-- return STATUS_SUCCESS;
-- }
--
-- if (!params->frames)
-- {
-- pulse_unlock();
-- *params->data = NULL;
-- params->result = S_OK;
-- return STATUS_SUCCESS;
-- }
--
-- if (stream->held_bytes / pa_frame_size(&stream->ss) + params->frames > stream->bufsize_frames)
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_BUFFER_TOO_LARGE;
-- return STATUS_SUCCESS;
-- }
--
-- bytes = params->frames * pa_frame_size(&stream->ss);
-- wri_offs_bytes = (stream->lcl_offs_bytes + stream->held_bytes) % stream->real_bufsize_bytes;
-- if (wri_offs_bytes + bytes > stream->real_bufsize_bytes)
-- {
-- if (!alloc_tmp_buffer(stream, bytes))
-- {
-- pulse_unlock();
-- params->result = E_OUTOFMEMORY;
-- return STATUS_SUCCESS;
-- }
-- *params->data = stream->tmp_buffer;
-- stream->locked = -bytes;
-- }
-- else
-- {
-- *params->data = stream->local_buffer + wri_offs_bytes;
-- stream->locked = bytes;
-- }
--
-- silence_buffer(stream->ss.format, *params->data, bytes);
--
-- pulse_unlock();
-- params->result = S_OK;
-- return STATUS_SUCCESS;
--}
--
--static void pulse_wrap_buffer(struct pulse_stream *stream, BYTE *buffer, UINT32 written_bytes)
--{
-- UINT32 wri_offs_bytes = (stream->lcl_offs_bytes + stream->held_bytes) % stream->real_bufsize_bytes;
-- UINT32 chunk_bytes = stream->real_bufsize_bytes - wri_offs_bytes;
--
-- if (written_bytes <= chunk_bytes)
-- {
-- memcpy(stream->local_buffer + wri_offs_bytes, buffer, written_bytes);
-- }
-- else
-- {
-- memcpy(stream->local_buffer + wri_offs_bytes, buffer, chunk_bytes);
-- memcpy(stream->local_buffer, buffer + chunk_bytes, written_bytes - chunk_bytes);
-- }
--}
--
--static NTSTATUS pulse_release_render_buffer(void *args)
--{
-- struct release_render_buffer_params *params = args;
-- struct pulse_stream *stream = params->stream;
-- UINT32 written_bytes;
-- BYTE *buffer;
--
-- pulse_lock();
-- if (!stream->locked || !params->written_frames)
-- {
-- stream->locked = 0;
-- pulse_unlock();
-- params->result = params->written_frames ? AUDCLNT_E_OUT_OF_ORDER : S_OK;
-- return STATUS_SUCCESS;
-- }
--
-- if (params->written_frames * pa_frame_size(&stream->ss) >
-- (stream->locked >= 0 ? stream->locked : -stream->locked))
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_INVALID_SIZE;
-- return STATUS_SUCCESS;
-- }
--
-- if (stream->locked >= 0)
-- buffer = stream->local_buffer + (stream->lcl_offs_bytes + stream->held_bytes) % stream->real_bufsize_bytes;
-- else
-- buffer = stream->tmp_buffer;
--
-- written_bytes = params->written_frames * pa_frame_size(&stream->ss);
-- if (params->flags & AUDCLNT_BUFFERFLAGS_SILENT)
-- silence_buffer(stream->ss.format, buffer, written_bytes);
--
-- if (stream->locked < 0)
-- pulse_wrap_buffer(stream, buffer, written_bytes);
--
-- stream->held_bytes += written_bytes;
-- stream->pa_held_bytes += written_bytes;
-- if (stream->pa_held_bytes > stream->real_bufsize_bytes)
-- {
-- stream->pa_offs_bytes += stream->pa_held_bytes - stream->real_bufsize_bytes;
-- stream->pa_offs_bytes %= stream->real_bufsize_bytes;
-- stream->pa_held_bytes = stream->real_bufsize_bytes;
-- }
-- stream->clock_written += written_bytes;
-- stream->locked = 0;
--
-- TRACE("Released %u, held %lu\n", params->written_frames, stream->held_bytes / pa_frame_size(&stream->ss));
--
-- pulse_unlock();
-- params->result = S_OK;
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_get_capture_buffer(void *args)
--{
-- struct get_capture_buffer_params *params = args;
-- struct pulse_stream *stream = params->stream;
-- ACPacket *packet;
--
-- pulse_lock();
-- if (!pulse_stream_valid(stream))
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_DEVICE_INVALIDATED;
-- return STATUS_SUCCESS;
-- }
-- if (stream->locked)
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_OUT_OF_ORDER;
-- return STATUS_SUCCESS;
-- }
--
-- pulse_capture_padding(stream);
-- if ((packet = stream->locked_ptr))
-- {
-- *params->frames = stream->period_bytes / pa_frame_size(&stream->ss);
-- *params->flags = 0;
-- if (packet->discont)
-- *params->flags |= AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY;
-- if (params->devpos)
-- {
-- if (packet->discont)
-- *params->devpos = (stream->clock_written + stream->period_bytes) / pa_frame_size(&stream->ss);
-- else
-- *params->devpos = stream->clock_written / pa_frame_size(&stream->ss);
-- }
-- if (params->qpcpos)
-- *params->qpcpos = packet->qpcpos;
-- *params->data = packet->data;
-- }
-- else
-- *params->frames = 0;
-- stream->locked = *params->frames;
-- pulse_unlock();
-- params->result = *params->frames ? S_OK : AUDCLNT_S_BUFFER_EMPTY;
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_release_capture_buffer(void *args)
--{
-- struct release_capture_buffer_params *params = args;
-- struct pulse_stream *stream = params->stream;
--
-- pulse_lock();
-- if (!stream->locked && params->done)
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_OUT_OF_ORDER;
-- return STATUS_SUCCESS;
-- }
-- if (params->done && stream->locked != params->done)
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_INVALID_SIZE;
-- return STATUS_SUCCESS;
-- }
-- if (params->done)
-- {
-- ACPacket *packet = stream->locked_ptr;
-- stream->locked_ptr = NULL;
-- stream->held_bytes -= stream->period_bytes;
-- if (packet->discont)
-- stream->clock_written += 2 * stream->period_bytes;
-- else
-- stream->clock_written += stream->period_bytes;
-- list_add_tail(&stream->packet_free_head, &packet->entry);
-- }
-- stream->locked = 0;
-- pulse_unlock();
-- params->result = S_OK;
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_get_buffer_size(void *args)
--{
-- struct get_buffer_size_params *params = args;
--
-- params->result = S_OK;
--
-- pulse_lock();
-- if (!pulse_stream_valid(params->stream))
-- params->result = AUDCLNT_E_DEVICE_INVALIDATED;
-- else
-- *params->size = params->stream->bufsize_frames;
-- pulse_unlock();
--
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_get_latency(void *args)
--{
-- struct get_latency_params *params = args;
-- struct pulse_stream *stream = params->stream;
-- const pa_buffer_attr *attr;
-- REFERENCE_TIME lat;
--
-- pulse_lock();
-- if (!pulse_stream_valid(stream)) {
-- pulse_unlock();
-- params->result = AUDCLNT_E_DEVICE_INVALIDATED;
-- return STATUS_SUCCESS;
-- }
-- attr = pa_stream_get_buffer_attr(stream->stream);
-- if (stream->dataflow == eRender)
-- lat = attr->minreq / pa_frame_size(&stream->ss);
-- else
-- lat = attr->fragsize / pa_frame_size(&stream->ss);
-- *params->latency = (lat * 10000000) / stream->ss.rate + pulse_def_period[0];
-- pulse_unlock();
-- TRACE("Latency: %u ms\n", (DWORD)(*params->latency / 10000));
-- params->result = S_OK;
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_get_current_padding(void *args)
--{
-- struct get_current_padding_params *params = args;
-- struct pulse_stream *stream = params->stream;
--
-- pulse_lock();
-- if (!pulse_stream_valid(stream))
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_DEVICE_INVALIDATED;
-- return STATUS_SUCCESS;
-- }
--
-- if (stream->dataflow == eRender)
-- *params->padding = pulse_render_padding(stream);
-- else
-- *params->padding = pulse_capture_padding(stream);
-- pulse_unlock();
--
-- TRACE("%p Pad: %u ms (%u)\n", stream, muldiv(*params->padding, 1000, stream->ss.rate),
-- *params->padding);
-- params->result = S_OK;
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_get_next_packet_size(void *args)
--{
-- struct get_next_packet_size_params *params = args;
-- struct pulse_stream *stream = params->stream;
--
-- pulse_lock();
-- pulse_capture_padding(stream);
-- if (stream->locked_ptr)
-- *params->frames = stream->period_bytes / pa_frame_size(&stream->ss);
-- else
-- *params->frames = 0;
-- pulse_unlock();
-- params->result = S_OK;
--
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_get_frequency(void *args)
--{
-- struct get_frequency_params *params = args;
-- struct pulse_stream *stream = params->stream;
--
-- pulse_lock();
-- if (!pulse_stream_valid(stream))
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_DEVICE_INVALIDATED;
-- return STATUS_SUCCESS;
-- }
--
-- *params->freq = stream->ss.rate;
-- if (stream->share == AUDCLNT_SHAREMODE_SHARED)
-- *params->freq *= pa_frame_size(&stream->ss);
-- pulse_unlock();
-- params->result = S_OK;
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_get_position(void *args)
--{
-- struct get_position_params *params = args;
-- struct pulse_stream *stream = params->stream;
--
-- pulse_lock();
-- if (!pulse_stream_valid(stream))
-- {
-- pulse_unlock();
-- params->result = AUDCLNT_E_DEVICE_INVALIDATED;
-- return STATUS_SUCCESS;
-- }
--
-- *params->pos = stream->clock_written - stream->held_bytes;
--
-- if (stream->share == AUDCLNT_SHAREMODE_EXCLUSIVE || params->device)
-- *params->pos /= pa_frame_size(&stream->ss);
--
-- /* Make time never go backwards */
-- if (*params->pos < stream->clock_lastpos)
-- *params->pos = stream->clock_lastpos;
-- else
-- stream->clock_lastpos = *params->pos;
-- pulse_unlock();
--
-- TRACE("%p Position: %u\n", stream, (unsigned)*params->pos);
--
-- if (params->qpctime)
-- {
-- LARGE_INTEGER stamp, freq;
-- NtQueryPerformanceCounter(&stamp, &freq);
-- *params->qpctime = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
-- }
--
-- params->result = S_OK;
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_set_volumes(void *args)
--{
-- struct set_volumes_params *params = args;
-- struct pulse_stream *stream = params->stream;
-- unsigned int i;
--
-- for (i = 0; i < stream->ss.channels; i++)
-- stream->vol[i] = params->volumes[i] * params->master_volume * params->session_volumes[i];
--
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_set_event_handle(void *args)
--{
-- struct set_event_handle_params *params = args;
-- struct pulse_stream *stream = params->stream;
-- HRESULT hr = S_OK;
--
-- pulse_lock();
-- if (!pulse_stream_valid(stream))
-- hr = AUDCLNT_E_DEVICE_INVALIDATED;
-- else if (!(stream->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK))
-- hr = AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED;
-- else if (stream->event)
-- hr = HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
-- else
-- stream->event = params->event;
-- pulse_unlock();
--
-- params->result = hr;
-- return STATUS_SUCCESS;
--}
--
--static NTSTATUS pulse_is_started(void *args)
--{
-- struct is_started_params *params = args;
-- struct pulse_stream *stream = params->stream;
--
-- pulse_lock();
-- params->started = pulse_stream_valid(stream) && stream->started;
-- pulse_unlock();
--
-- return STATUS_SUCCESS;
--}
--
--static const unixlib_entry_t unix_funcs[] =
--{
-- pulse_main_loop,
-- pulse_create_stream,
-- pulse_release_stream,
-- pulse_start,
-- pulse_stop,
-- pulse_reset,
-- pulse_timer_loop,
-- pulse_get_render_buffer,
-- pulse_release_render_buffer,
-- pulse_get_capture_buffer,
-- pulse_release_capture_buffer,
-- pulse_get_buffer_size,
-- pulse_get_latency,
-- pulse_get_current_padding,
-- pulse_get_next_packet_size,
-- pulse_get_frequency,
-- pulse_get_position,
-- pulse_set_volumes,
-- pulse_set_event_handle,
-- pulse_test_connect,
-- pulse_is_started,
--};
--
--NTSTATUS CDECL __wine_init_unix_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
--{
-- pthread_mutexattr_t attr;
--
-- switch (reason)
-- {
-- case DLL_PROCESS_ATTACH:
-- pthread_mutexattr_init(&attr);
-- pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
--
-- if (pthread_mutex_init(&pulse_mutex, &attr) != 0)
-- pthread_mutex_init(&pulse_mutex, NULL);
--
-- *(UINT64 *)ptr_out = (UINT_PTR)&unix_funcs;
-- break;
-- case DLL_PROCESS_DETACH:
-- if (pulse_ctx)
-- {
-- pa_context_disconnect(pulse_ctx);
-- pa_context_unref(pulse_ctx);
-- }
-- if (pulse_ml)
-- pa_mainloop_quit(pulse_ml, 0);
--
-- }
--
-- return STATUS_SUCCESS;
--}
-diff --git a/dlls/winepulse.drv/unixlib.h b/dlls/winepulse.drv/unixlib.h
-deleted file mode 100644
-index 9e7af57b716e8d3edc4793ead64b35d4993a4a94..0000000000000000000000000000000000000000
---- a/dlls/winepulse.drv/unixlib.h
-+++ /dev/null
-@@ -1,211 +0,0 @@
--/*
-- * Copyright 2021 Jacek Caban for CodeWeavers
-- *
-- * This library is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU Lesser General Public
-- * License as published by the Free Software Foundation; either
-- * version 2.1 of the License, or (at your option) any later version.
-- *
-- * This library is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- * Lesser General Public License for more details.
-- *
-- * You should have received a copy of the GNU Lesser General Public
-- * License along with this library; if not, write to the Free Software
-- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-- */
--
--#include "wine/list.h"
--
--struct pulse_stream;
--
--struct pulse_config
--{
-- struct
-- {
-- WAVEFORMATEXTENSIBLE format;
-- REFERENCE_TIME def_period;
-- REFERENCE_TIME min_period;
-- } modes[2];
-- unsigned int speakers_mask;
--};
--
--struct main_loop_params
--{
-- HANDLE event;
--};
--
--struct create_stream_params
--{
-- const char *name;
-- EDataFlow dataflow;
-- AUDCLNT_SHAREMODE mode;
-- DWORD flags;
-- REFERENCE_TIME duration;
-- const WAVEFORMATEX *fmt;
-- HRESULT result;
-- UINT32 *channel_count;
-- struct pulse_stream **stream;
--};
--
--struct release_stream_params
--{
-- struct pulse_stream *stream;
-- HANDLE timer;
-- HRESULT result;
--};
--
--struct start_params
--{
-- struct pulse_stream *stream;
-- HRESULT result;
--};
--
--struct stop_params
--{
-- struct pulse_stream *stream;
-- HRESULT result;
--};
--
--struct reset_params
--{
-- struct pulse_stream *stream;
-- HRESULT result;
--};
--
--struct timer_loop_params
--{
-- struct pulse_stream *stream;
--};
--
--struct get_render_buffer_params
--{
-- struct pulse_stream *stream;
-- UINT32 frames;
-- HRESULT result;
-- BYTE **data;
--};
--
--struct release_render_buffer_params
--{
-- struct pulse_stream *stream;
-- UINT32 written_frames;
-- DWORD flags;
-- HRESULT result;
--};
--
--struct get_capture_buffer_params
--{
-- struct pulse_stream *stream;
-- HRESULT result;
-- BYTE **data;
-- UINT32 *frames;
-- DWORD *flags;
-- UINT64 *devpos;
-- UINT64 *qpcpos;
--};
--
--struct release_capture_buffer_params
--{
-- struct pulse_stream *stream;
-- BOOL done;
-- HRESULT result;
--};
--
--struct get_buffer_size_params
--{
-- struct pulse_stream *stream;
-- HRESULT result;
-- UINT32 *size;
--};
--
--struct get_latency_params
--{
-- struct pulse_stream *stream;
-- HRESULT result;
-- REFERENCE_TIME *latency;
--};
--
--struct get_current_padding_params
--{
-- struct pulse_stream *stream;
-- HRESULT result;
-- UINT32 *padding;
--};
--
--struct get_next_packet_size_params
--{
-- struct pulse_stream *stream;
-- HRESULT result;
-- UINT32 *frames;
--};
--
--struct get_frequency_params
--{
-- struct pulse_stream *stream;
-- HRESULT result;
-- UINT64 *freq;
--};
--
--struct get_position_params
--{
-- struct pulse_stream *stream;
-- BOOL device;
-- HRESULT result;
-- UINT64 *pos;
-- UINT64 *qpctime;
--};
--
--struct set_volumes_params
--{
-- struct pulse_stream *stream;
-- float master_volume;
-- const float *volumes;
-- const float *session_volumes;
--};
--
--struct set_event_handle_params
--{
-- struct pulse_stream *stream;
-- HANDLE event;
-- HRESULT result;
--};
--
--struct test_connect_params
--{
-- const char *name;
-- HRESULT result;
-- struct pulse_config *config;
--};
--
--struct is_started_params
--{
-- struct pulse_stream *stream;
-- BOOL started;
--};
--
--enum unix_funcs
--{
-- main_loop,
-- create_stream,
-- release_stream,
-- start,
-- stop,
-- reset,
-- timer_loop,
-- get_render_buffer,
-- release_render_buffer,
-- get_capture_buffer,
-- release_capture_buffer,
-- get_buffer_size,
-- get_latency,
-- get_current_padding,
-- get_next_packet_size,
-- get_frequency,
-- get_position,
-- set_volumes,
-- set_event_handle,
-- test_connect,
-- is_started,
--};
-diff --git a/include/audioclient.idl b/include/audioclient.idl
-index 754ae58f78c9a014c5990250fa739c711902c819..c69a4116789190bc5ed025dc32176dd8b2081c07 100644
---- a/include/audioclient.idl
-+++ b/include/audioclient.idl
-@@ -128,14 +128,6 @@ typedef struct _AudioClientProperties
- AUDCLNT_STREAMOPTIONS Options;
- } AudioClientProperties;
-
--typedef struct _Win8AudioClientProperties
--{
-- UINT32 cbSize;
-- BOOL bIsOffload;
-- AUDIO_STREAM_CATEGORY eCategory;
-- /* Options field added in Win 8.1 */
--} Win8AudioClientProperties;
--
- [
- local,
- pointer_default(unique),
---
-2.32.0
-
diff --git a/packages/wine-osu/patches/0002-5.14-Latency-Fix.patch b/packages/wine-osu/patches/0002-5.14-Latency-Fix.patch
deleted file mode 100644
index 518538f..0000000
--- a/packages/wine-osu/patches/0002-5.14-Latency-Fix.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 4a2c23db4eddd827ac81513af43bc92475ad7d3a Mon Sep 17 00:00:00 2001
-From: Sebastian 'gonX' Jensen
-Date: Sun, 20 Jun 2021 17:02:15 +0200
-Subject: [PATCH 2/4] 5.14 Latency Fix
-
----
- dlls/winepulse.drv/mmdevdrv.c | 22 ++++++++++++++--------
- 1 file changed, 14 insertions(+), 8 deletions(-)
-
-diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c
-index 07407089ac5af65eb13d6e00b6d0969a61ec5589..3ed47e38c830987e4bcc2e9f5c59c7773fe686f1 100644
---- a/dlls/winepulse.drv/mmdevdrv.c
-+++ b/dlls/winepulse.drv/mmdevdrv.c
-@@ -68,9 +68,6 @@ enum DriverPriority {
- Priority_Preferred
- };
-
--static const REFERENCE_TIME MinimumPeriod = 30000;
--static const REFERENCE_TIME DefaultPeriod = 100000;
--
- static pa_context *pulse_ctx;
- static pa_mainloop *pulse_ml;
-
-@@ -510,11 +507,12 @@ static void pulse_probe_settings(int render, WAVEFORMATEXTENSIBLE *fmt) {
- if (length)
- pulse_def_period[!render] = pulse_min_period[!render] = pa_bytes_to_usec(10 * length, &ss);
-
-- if (pulse_min_period[!render] < MinimumPeriod)
-- pulse_min_period[!render] = MinimumPeriod;
--
-- if (pulse_def_period[!render] < DefaultPeriod)
-- pulse_def_period[!render] = DefaultPeriod;
-+ const char* penv = getenv("STAGING_AUDIO_PERIOD");
-+ if (penv) {
-+ int val = atoi(penv);
-+ pulse_def_period[!render] = pulse_min_period[!render] = val;
-+ printf("Staging audio period set to %d.\n", val);
-+ }
-
- wfx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
- wfx->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
-@@ -1640,6 +1638,14 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient2 *iface,
- if (duration <= 2 * period)
- period /= 2;
- }
-+
-+ const char* denv = getenv("STAGING_AUDIO_DURATION");
-+ if (denv) {
-+ int val = atoi(denv);
-+ duration = val;
-+ printf("Staging audio duration set to %d.\n", val);
-+ }
-+
- period_bytes = pa_frame_size(&This->ss) * MulDiv(period, This->ss.rate, 10000000);
-
- if (duration < 20000000)
---
-2.32.0
-
diff --git a/packages/wine-osu/patches/0003-secur32-Fix-crash-from-invalid-context-in-Initialize.patch b/packages/wine-osu/patches/0003-secur32-Fix-crash-from-invalid-context-in-Initialize.patch
deleted file mode 100644
index 7800d50..0000000
--- a/packages/wine-osu/patches/0003-secur32-Fix-crash-from-invalid-context-in-Initialize.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From e17fb0bda3c042beec05b918e2d171211742e01c Mon Sep 17 00:00:00 2001
-From: Torge Matthies
-Date: Fri, 12 Feb 2021 13:58:35 +0100
-Subject: [PATCH 3/4] secur32: Fix crash from invalid context in
- InitializeSecurityContextW.
-
-Signed-off-by: Torge Matthies
----
- dlls/secur32/schannel.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c
-index 9c7e98b32a4c55588a78ac6c3811b89db9e09db7..b2baefbc8caaf370c9c0ec31b7daf4cc9bb7fbb8 100644
---- a/dlls/secur32/schannel.c
-+++ b/dlls/secur32/schannel.c
-@@ -983,6 +983,7 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
- unsigned char *ptr;
-
- ctx = schan_get_object(phContext->dwLower, SCHAN_HANDLE_CTX);
-+ if (!ctx) return SEC_E_INVALID_HANDLE;
- if (pInput)
- {
- idx = schan_find_sec_buffer_idx(pInput, 0, SECBUFFER_TOKEN);
---
-2.32.0
-
diff --git a/packages/wine-osu/patches/0004-kernelbase-Cache-last-used-locale-sortguid-mapping.patch b/packages/wine-osu/patches/0004-kernelbase-Cache-last-used-locale-sortguid-mapping.patch
deleted file mode 100644
index 22cd561..0000000
--- a/packages/wine-osu/patches/0004-kernelbase-Cache-last-used-locale-sortguid-mapping.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From b1ac42097f6f6e038a2e1fac773bc31e829fb891 Mon Sep 17 00:00:00 2001
-From: Torge Matthies
-Date: Mon, 5 Apr 2021 05:48:28 +0200
-Subject: [PATCH 4/4] kernelbase: Cache last used locale->sortguid mapping.
-
-get_language_sort reads from the registry, which is not particularly fast.
-Staging's implementation of CompareStringEx calls this function, and if
-CompareStringEx is used in a loop over many elements, it will slow down the
-application by a lot (> 30 seconds vs a few hundred ms in osu!, depends
-on the CPU and the number of installed beatmaps).
-
-Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50923
-Signed-off-by: Torge Matthies
----
- dlls/kernelbase/locale.c | 42 +++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 41 insertions(+), 1 deletion(-)
-
-diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
-index 89b3577505348a001577ba3549b8af2d1e6cb456..db97383f2858455f8c329f326d4b3f9f3ec606cb 100644
---- a/dlls/kernelbase/locale.c
-+++ b/dlls/kernelbase/locale.c
-@@ -619,6 +619,21 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
- };
- static CRITICAL_SECTION locale_section = { &critsect_debug, -1, 0, 0, 0, 0 };
-
-+static struct
-+{
-+ WCHAR locale[LOCALE_NAME_MAX_LENGTH]; /* The locale name */
-+ const struct sortguid *guid; /* The cached associated GUID */
-+} sortguid_cache;
-+
-+static CRITICAL_SECTION sortguid_cache_section;
-+static CRITICAL_SECTION_DEBUG sortguid_cache_section_debug =
-+{
-+ 0, 0, &sortguid_cache_section,
-+ { &sortguid_cache_section_debug.ProcessLocksList, &sortguid_cache_section_debug.ProcessLocksList },
-+ 0, 0, { (DWORD_PTR)(__FILE__ ": sortguid_cache_section") }
-+};
-+static CRITICAL_SECTION sortguid_cache_section = { &sortguid_cache_section_debug, -1, 0, 0, 0, 0 };
-+
-
- static void init_sortkeys( DWORD *ptr )
- {
-@@ -656,7 +671,7 @@ static const struct sortguid *find_sortguid( const GUID *guid )
- }
-
-
--static const struct sortguid *get_language_sort( const WCHAR *locale )
-+static const struct sortguid *get_language_sort_uncached( const WCHAR *locale )
- {
- WCHAR *p, *end, buffer[LOCALE_NAME_MAX_LENGTH], guidstr[39];
- const struct sortguid *ret;
-@@ -699,6 +714,31 @@ done:
- }
-
-
-+static const struct sortguid *get_language_sort( const WCHAR *locale )
-+{
-+ const struct sortguid *ret = NULL;
-+
-+ if (!locale) return get_language_sort_uncached( locale );
-+
-+ RtlEnterCriticalSection( &sortguid_cache_section );
-+
-+ if (sortguid_cache.guid && !wcsncmp( sortguid_cache.locale, locale, LOCALE_NAME_MAX_LENGTH ))
-+ {
-+ ret = sortguid_cache.guid;
-+ goto done;
-+ }
-+
-+ ret = get_language_sort_uncached( locale );
-+
-+ lstrcpynW( sortguid_cache.locale, locale, LOCALE_NAME_MAX_LENGTH );
-+ sortguid_cache.guid = ret;
-+
-+done:
-+ RtlLeaveCriticalSection( &sortguid_cache_section );
-+ return ret;
-+}
-+
-+
- static LCID locale_to_lcid( WCHAR *win_name )
- {
- WCHAR *p;
---
-2.32.0
-
diff --git a/res/README.md b/res/README.md
deleted file mode 100644
index 28d2424..0000000
--- a/res/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-### Wallpaper
-Edited from https://www.deviantart.com/mrezamulia/art/Hifumi-wallpaper-731342039
diff --git a/res/authorized_keys b/res/authorized_keys
new file mode 100644
index 0000000..9e9178d
--- /dev/null
+++ b/res/authorized_keys
@@ -0,0 +1,2 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPru5eTBvHJ4ZmrrzPRHCGM09wQP/ZHSaKYalDuBVO15 rin@blossom
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ5l9t8dc6mPsKKYqZlPKvhOdyqz+DS5UOcvHuh3uVGt @strawberry
diff --git a/res/config-minimal.lua b/res/config-minimal.lua
new file mode 100644
index 0000000..c2d3f06
--- /dev/null
+++ b/res/config-minimal.lua
@@ -0,0 +1,55 @@
+-- Keybindings
+local map = vim.keymap.set
+map('n', '', 'h', { noremap = true })
+map('n', '', 'j', { noremap = true })
+map('n', '', 'k', { noremap = true })
+map('n', '', 'l', { noremap = true })
+map('n', '', ':q', { noremap = true })
+map('n', '', ':Files', { noremap = true })
+
+-- Autocommands
+vim.cmd('au BufEnter * set noro')
+vim.cmd('au CursorHold * lua vim.diagnostic.open_float(0, { scope = "line", focusable = false })')
+
+-- Settings
+vim.opt.mouse = ""
+vim.opt.relativenumber = true
+vim.opt.number = true
+vim.opt.cursorline = true
+vim.opt.signcolumn = "yes:3"
+vim.opt.title = true
+vim.opt.termguicolors = true
+vim.opt.updatetime = 0
+vim.opt.clipboard:prepend('unnamedplus')
+
+local runtimedir = os.getenv('XDG_RUNTIME_DIR')
+vim.opt.directory:prepend(runtimedir..'/vim/swap//')
+vim.opt.undodir:prepend(runtimedir..'/vim/undo//')
+vim.opt.swapfile = true
+vim.opt.undofile = true
+
+vim.opt.hlsearch = true
+vim.opt.ignorecase = true
+vim.opt.smartcase = true
+vim.opt.incsearch = true
+
+vim.opt.tabstop = 8
+vim.opt.softtabstop = 0
+vim.opt.expandtab = true
+vim.opt.shiftwidth = 4
+vim.opt.smarttab = true
+
+vim.g.signify_priority = 5
+vim.g.signify_sign_show_count = 0
+vim.g.signify_sign_add = '┃'
+vim.g.signify_sign_delete = vim.g.signify_sign_add
+vim.g.signify_sign_delete_first_line = '┏━'
+vim.g.signify_sign_change = vim.g.signify_sign_add
+vim.g.signify_sign_change_delete = vim.g.signify_sign_delete
+
+-- Plugins
+require('nvim-treesitter').setup {
+ highlight = { enable = true },
+ indent = { enable = false }
+}
+require('lualine').setup { }
diff --git a/res/config.lua b/res/config.lua
new file mode 100644
index 0000000..c0b5dad
--- /dev/null
+++ b/res/config.lua
@@ -0,0 +1,340 @@
+-- Keybindings
+local map = vim.keymap.set
+map('n', '', 'h', { remap = false })
+map('n', '', 'j', { remap = false })
+map('n', '', 'k', { remap = false })
+map('n', '', 'l', { remap = false })
+map('n', '', ':q', { remap = false })
+map('n', '', ':Files', { remap = false })
+map('n', '', 'gcc', { remap = true, silent = true })
+map('v', '', 'gc', { remap = true, silent = true })
+
+-- Autocommands
+vim.cmd('au BufEnter * set noro')
+vim.cmd('au CursorHold * lua vim.diagnostic.open_float(0, { scope = "line", focusable = false })')
+
+-- Settings
+vim.opt.mouse = ""
+vim.opt.relativenumber = true
+vim.opt.number = true
+vim.opt.cursorline = true
+vim.opt.signcolumn = "yes:3"
+vim.opt.title = true
+vim.opt.termguicolors = true
+vim.opt.updatetime = 0
+vim.opt.clipboard:prepend('unnamedplus')
+
+local runtimedir = os.getenv('XDG_RUNTIME_DIR')
+vim.opt.directory:prepend(runtimedir..'/vim/swap//')
+vim.opt.undodir:prepend(runtimedir..'/vim/undo//')
+vim.opt.swapfile = true
+vim.opt.undofile = true
+
+vim.opt.hlsearch = true
+vim.opt.ignorecase = true
+vim.opt.smartcase = true
+vim.opt.incsearch = true
+
+vim.opt.tabstop = 8
+vim.opt.softtabstop = 0
+vim.opt.expandtab = true
+vim.opt.shiftwidth = 4
+vim.opt.smarttab = true
+
+vim.g.signify_priority = 5
+vim.g.signify_sign_show_count = 0
+vim.g.signify_sign_add = '┃'
+vim.g.signify_sign_delete = vim.g.signify_sign_add
+vim.g.signify_sign_delete_first_line = '┏━'
+vim.g.signify_sign_change = vim.g.signify_sign_add
+vim.g.signify_sign_change_delete = vim.g.signify_sign_delete
+
+-- VimTeX
+vim.g.vimtex_view_method = "zathura"
+vim.g.vimtex_quickfix_open_on_warning = 0
+
+-- Theming
+vim.api.nvim_command("syntax enable")
+local colors = require("catppuccin.palettes").get_palette "{{CATPPUCCIN_FLAVOUR}}"
+vim.cmd("highlight SignifySignAdd guifg="..colors.green)
+vim.cmd("highlight SignifySignChange guifg="..colors.peach)
+vim.cmd("highlight SignifySignDelete guifg="..colors.red)
+vim.cmd("highlight SignifySignDeleteFirstLine guifg="..colors.red)
+vim.cmd("highlight SignifySignChangeDelete guifg="..colors.red)
+
+-- Set this specific highlight group in rust
+-- Shown when using #[cfg] directives, entire chunks of disabled code has squiggly lines and I don't want
+-- to see it
+vim.cmd("au FileType rust highlight DiagnosticUnderlineHint ctermfg=14 gui=italic guifg="..colors.overlay2)
+
+-- Plugins
+require('autoclose').setup {}
+local function autosavecond(buf)
+ if vim.tbl_contains({"astro", "tex"}, vim.fn.getbufvar(buf, "&filetype")) then
+ return true
+ end
+ return false
+end
+require('auto-save').setup {
+ trigger_events = {
+ defer_save = { "InsertLeave", "TextChanged", "TextChangedI" },
+ },
+ debounce_delay = 250,
+ condition = autosavecond,
+}
+require('nvim-ts-autotag').setup {}
+require('nvim-highlight-colors').setup {
+ render = "virtual",
+}
+require('nvim-treesitter').setup {
+ highlight = { enable = true },
+ indent = { enable = false }
+}
+require('lualine').setup {
+ options = {
+ theme = 'catppuccin'
+ },
+ sections = {
+ lualine_c = {
+ {
+ "filename",
+ path = 1,
+ }
+ }
+ }
+}
+
+-- Block comments indent workaround
+-- many thanks to @kristijanhusak
+-- https://github.com/nvim-treesitter/nvim-treesitter/issues/1167#issuecomment-920824125
+function _G.javascript_indent()
+ local line = vim.fn.getline(vim.v.lnum)
+ local prev_line = vim.fn.getline(vim.v.lnum - 1)
+ if line:match('^%s*[%*/]%s*') then
+ if prev_line:match('^%s*%*%s*') then
+ return vim.fn.indent(vim.v.lnum - 1)
+ end
+ if prev_line:match('^%s*/%*%*%s*$') then
+ return vim.fn.indent(vim.v.lnum - 1) + 1
+ end
+ end
+
+ return vim.fn['GetJavascriptIndent']()
+end
+
+vim.cmd('au FileType javascript setlocal indentexpr=v:lua.javascript_indent()')
+
+-- LSP
+vim.api.nvim_create_autocmd("LspAttach", {
+ callback = function(args)
+ local client = vim.lsp.get_client_by_id(args.data.client_id)
+ if not client then
+ return
+ end
+
+ local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(args.buf, ...) end
+ local function buf_set_option(...) vim.api.nvim_buf_set_option(args.buf, ...) end
+
+ local opts = { noremap = true, silent = true }
+
+ buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', opts)
+ buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', opts)
+ buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()', opts)
+ buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts)
+ buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', opts)
+ buf_set_keymap('n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts)
+ buf_set_keymap('n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts)
+ buf_set_keymap('n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts)
+ buf_set_keymap('n', 'D', 'lua vim.lsp.buf.type_definition()', opts)
+ buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()', opts)
+ buf_set_keymap('n', 'ca', 'lua vim.lsp.buf.code_action()', opts)
+ buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts)
+ buf_set_keymap('n', 'e', 'lua vim.diagnostic.open_float(0, { scope = "line" })', opts)
+ buf_set_keymap('n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', opts)
+ buf_set_keymap('n', ']d', 'lua vim.lsp.diagnostic.goto_next()', opts)
+ buf_set_keymap('n', 'q', 'lua vim.lsp.diagnostic.set_loclist()', opts)
+ buf_set_keymap('n', 'f', 'lua vim.lsp.buf.formatting()', opts)
+ end
+})
+
+vim.diagnostic.config({
+ focusable = false,
+ virtual_text = false,
+ underline = true,
+ signs = true,
+ update_in_insert = true
+})
+
+capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities)
+
+local servers = { 'astro', 'clangd', 'cssls', 'html', 'tailwindcss', 'texlab', 'ts_ls', 'yamlls' }
+for _, lsp in ipairs(servers) do
+ vim.lsp.config(lsp, {
+ capabilities = capabilities,
+ flags = { debounce_text_changes = 150 }
+ })
+ vim.lsp.enable(lsp)
+end
+
+-- nvim-cmp
+local luasnip = require('luasnip')
+local cmp = require('cmp')
+cmp.setup {
+ snippet = {
+ expand = function(args)
+ luasnip.lsp_expand(args.body)
+ end
+ },
+ mapping = {
+ [''] = cmp.mapping.select_next_item(),
+ [''] = cmp.mapping.select_prev_item(),
+ [''] = cmp.mapping.scroll_docs(-4),
+ [''] = cmp.mapping.scroll_docs(4),
+ [''] = cmp.mapping.complete(),
+ [''] = cmp.mapping.close(),
+ [''] = cmp.mapping.confirm {
+ behavior = cmp.ConfirmBehavior.Replace,
+ select = true,
+ },
+ [''] = function(fallback)
+ if cmp.visible() then
+ cmp.select_next_item()
+ elseif luasnip.expand_or_jumpable() then
+ vim.fn.feedkeys(vim.api.nvim_replace_termcodes('luasnip-expand-or-jump', true, true, true), '')
+ else
+ fallback()
+ end
+ end,
+ [''] = function(fallback)
+ if cmp.visible() then
+ cmp.select_prev_item()
+ elseif luasnip.jumpable(-1) then
+ vim.fn.feedkeys(vim.api.nvim_replace_termcodes('luasnip-jump-prev', true, true, true), '')
+ else
+ fallback()
+ end
+ end
+ },
+ sources = {
+ { name = 'nvim_lsp' },
+ { name = 'luasnip' }
+ }
+}
+
+-- LSP/Omnisharp
+local pid = vim.fn.getpid()
+vim.lsp.config("omnisharp", {
+ capabilities = capabilities,
+ on_attach = on_attach,
+ flags = { debounce_text_changes = 150 },
+ cmd = { "{{OMNISHARP_PATH}}", "--languageserver", "--hostPID", tostring(pid) }
+})
+vim.lsp.enable("omnisharp")
+
+-- LSP/rust_analyzer
+vim.lsp.config("rust_analyzer", {
+ capabilities = capabilities,
+ on_attach = on_attach,
+ flags = { debounce_text_changes = 150 },
+ settings = {
+ ["rust-analyzer"] = {
+ imports = {
+ granularity = {
+ enforce = true,
+ group = "module"
+ }
+ },
+ diagnostics = {
+ disabled = { "incorrect-ident-case" }
+ }
+ }
+ }
+})
+vim.lsp.enable("rust_analyzer")
+
+-- LSP/Diagnostics
+vim.lsp.config("diagnosticls", {
+ capabilities = capabilities,
+ on_attach = on_attach,
+ flags = { debounce_text_changes = 150 },
+ filetypes = { 'javascript', 'javascriptreact', 'typescript', 'typescriptreact', 'vue' },
+ init_options = {
+ linters = {
+ eslint = {
+ command = 'eslint_d',
+ rootPatterns = { '.git' },
+ debounce = 100,
+ args = { '--stdin', '--stdin-filename', '%filepath', '--format', 'json' },
+ sourceName = 'eslint',
+ parseJson = {
+ errorsRoot = '[0].messages',
+ line = 'line',
+ column = 'column',
+ endLine = 'endLine',
+ endColumn = 'endColumn',
+ message = '[eslint] ${message} [${ruleId}]',
+ security = 'severity'
+ },
+ securities = {
+ [2] = 'error',
+ [1] = 'warning'
+ }
+ }
+ },
+ filetypes = {
+ javascript = 'eslint',
+ javascriptreact = 'eslint',
+ typescript = 'eslint',
+ typescriptreact = 'eslint',
+ vue = 'eslint'
+ }
+ }
+})
+vim.lsp.enable("diagnosticls")
+
+-- LSP/nixd
+vim.lsp.config("nixd", {
+ cmd = { "nixd" },
+ filetypes = { "nix" },
+ root_markers = { "flake.nix", ".git" },
+ settings = {
+ nixd = {
+ nixpkgs = {
+ expr = "import { }",
+ },
+ formatting = {
+ command = { "nixfmt" },
+ },
+ options = {
+ nixos = {
+ expr = '(builtins.getFlake (toString ./.)).nixosConfigurations.{{HOSTNAME}}.options',
+ },
+ home_manager = {
+ expr = '(builtins.getFlake (builtins.toString ./.)).nixosConfigurations."{{USERNAME}}@{{HOSTNAME}}".options.home-manager.users.type.getSubOptions []',
+ },
+ },
+ },
+ },
+})
+vim.lsp.enable("nixd")
+
+-- LSP/Signatures
+require("lsp_signature").setup {
+ hint_enable = false,
+ handler_opts = { border = "none" },
+ fix_pos = true
+}
+
+-- LSP/fzf
+require("fzf_lsp").setup()
+
+-- LSP/flutter
+require("flutter-tools").setup {
+ debugger = {
+ enabled = true
+ },
+ lsp = {
+ on_attach = on_attach,
+ cmd = { "{{DART_PATH}}", "language-server", "--protocol=lsp" }
+ }
+}
diff --git a/res/direnvrc b/res/direnvrc
new file mode 100644
index 0000000..8839ab5
--- /dev/null
+++ b/res/direnvrc
@@ -0,0 +1,9 @@
+: ${XDG_CACHE_HOME:=$HOME/.cache}
+declare -A direnv_layout_dirs
+direnv_layout_dir() {
+ echo "${direnv_layout_dirs[$PWD]:=$(
+ echo -n "$XDG_CACHE_HOME"/direnv/layouts/
+ echo -n "$(echo -n "$PWD" | shasum | cut -d ' ' -f 1)"
+ echo -n "-$(basename $PWD)"
+ )}"
+}
diff --git a/res/eww/eww.scss b/res/eww/eww.scss
new file mode 100644
index 0000000..763e6fd
--- /dev/null
+++ b/res/eww/eww.scss
@@ -0,0 +1,91 @@
+$background: EWW_BACKGROUND;
+$accent: EWW_ACCENT;
+$foreground: EWW_TEXT;
+
+* {
+ all: unset;
+}
+
+window {
+ background: transparent;
+}
+
+.bar {
+ margin: 5px 20px 5px 20px;
+}
+
+.widget {
+ background: $background;
+ color: $foreground;
+ font-family: "Noto Sans";
+ font-weight: 600;
+ font-size: 15px;
+ padding: 5px 15px;
+ border-radius: 50px;
+ box-shadow: rgba($foreground, .7) 0px 0px 2px;
+}
+
+.title {
+ margin: 0 5px;
+}
+
+.pill {
+ margin-right: 5px;
+ padding: 5px 10px;
+}
+
+.extended {
+ padding: 5px 15px;
+}
+
+.time {
+ .base {
+ font-weight: 700;
+ }
+ .extension {
+ font-weight: 500;
+ color: rgba($foreground, .7);
+ }
+}
+
+.workspaces {
+ padding: 5px 10px;
+ font-size: 22px;
+
+ button {
+ padding: 0px 2px;
+ }
+
+ .empty, .occupied {
+ color: $accent;
+ }
+}
+
+.widget.line-workspaces {
+ color: transparent;
+ padding: 0;
+ border-radius: 0;
+ font-size: 0;
+
+ button {
+ padding: 0 13px;
+ }
+
+ .empty {
+ background-color: $background;
+ }
+
+ .occupied {
+ background-color: $accent;
+ }
+
+ .focused {
+ background-color: $foreground;
+ }
+}
+
+.pill-icon {
+ color: $accent;
+ font-family: Material Symbols Outlined;
+ font-size: 18px;
+}
diff --git a/res/eww/eww.yuck b/res/eww/eww.yuck
new file mode 100644
index 0000000..d72a2cc
--- /dev/null
+++ b/res/eww/eww.yuck
@@ -0,0 +1,165 @@
+(defwindow mainbar :monitor 0
+
+ :geometry (geometry :x "0%"
+ :y "0%"
+ :width "100%"
+ :height "30px"
+ :anchor "top center")
+ :stacking "fg"
+ :exclusive false
+ :focusable false
+ (bar))
+
+(defwindow mainbar-ext :monitor 1
+ :geometry (geometry :x "0%"
+ :y "0%"
+ :width "100%"
+ :height "30px"
+ :anchor "top center")
+ :stacking "fg"
+ :exclusive false
+ :focusable false
+ (bar))
+
+(defvar bat-enabled _BAT_ENABLED_)
+(defvar bt-enabled _BT_ENABLED_)
+(defvar wifi-enabled _WIFI_ENABLED_)
+
+(defvar bat-extended true)
+(defvar bluetooth-extended false)
+(defvar network-extended false)
+(defvar time-extended false)
+
+(defpoll ptime :interval "1s"
+ `date +%H:%M`)
+(defpoll petimea :interval "1s" :run-while time-extended
+ `date "+%A, %d %B %Y "`)
+(defpoll petimeb :interval "1s" :run-while time-extended
+ `date "+:%S"`)
+(defpoll pbat_cap :interval "5s" :run-while bat-enabled
+ `cat /sys/class/power_supply/_BAT_PATH_/capacity`)
+(defpoll pbat_status :interval "1s" :run-while bat-enabled
+ `cat /sys/class/power_supply/_BAT_PATH_/status`)
+(defpoll wifi_ssid :interval "1s" :run-while wifi-enabled
+ `iwctl station wlan0 show | grep "Connected network" | awk '{print $3}'`)
+(defpoll wifi_strength :interval "1s" :run-while wifi-enabled
+ `iw dev wlan0 link | awk '/signal/ {gsub("-",""); print $2}'`)
+(defpoll bluetooth_device :interval "1s" :run-while bt-enabled
+ `bluetoothctl devices Connected | grep Device | cut -d" " -f3-`)
+(defpoll bluetooth_device_count :interval "1s" :run-while bt-enabled
+ `bluetoothctl devices Connected | wc -l`)
+
+(deflisten ltitle :initial "" "./scripts/title.sh")
+(deflisten lworkspaces :initial "[]" "./scripts/workspaces.sh")
+(deflisten lcurrent_workspace :initial "1" "./scripts/active-workspace.sh")
+
+(defwidget bar []
+ (eventbox :onscroll "./scripts/scroll.sh {}"
+ (centerbox :orientation "h"
+ :class "bar"
+ (workspaces)
+ (title)
+ (right_bar))))
+
+(defwidget workspaces []
+ (box :class "widget workspaces"
+ :halign "start"
+ :valign "center"
+ :vexpand true
+ :hexpand true
+ (for workspace in lworkspaces
+ (eventbox :cursor "hand"
+ (button :class "${workspace.id == lcurrent_workspace ? "focused" : (workspace.windows > 0 ? "occupied" : "empty")}"
+ :onclick "hyprctl dispatch workspace ${workspace.id}"
+ "${workspace.id == lcurrent_workspace ? "" : (workspace.windows > 0 ? "" : "")}")))))
+
+(defwidget title []
+ (literal :content ltitle))
+
+(defwidget time_extension [text]
+ (revealer :transition "slideleft"
+ :reveal time-extended
+ :duration 150
+ (label :text text
+ :class "extension")))
+
+(defwidget right_bar []
+ (box :orientation "horizontal"
+ :space-evenly false
+ :halign "end"
+ (box :visible {bt-enabled} (bluetooth))
+ (box :visible {wifi-enabled} (network))
+ (box :visible {bat-enabled} (battery))
+ (time)))
+
+(defwidget bluetooth []
+ (button :onclick `eww update bluetooth-extended=${bluetooth-extended ? "false" : "true"}`
+ (box :orientation "horizontal"
+ :class {"widget pill" + ((bluetooth-extended && bluetooth_device != "") ? " extended" : "")}
+ :spacing {(bluetooth-extended && bluetooth_device != "") ? 5 : 0}
+ :space-evenly false
+ (label :text { bluetooth_device == "" ? "" : ""}
+ :class "base pill-icon")
+ (revealer :transition "slideleft"
+ :reveal {bluetooth-extended && bluetooth_device != ""}
+ :duration 150
+ (label :text { bluetooth_device_count == "1" ? bluetooth_device : (bluetooth_device_count + " devices") }
+ :class "base")))))
+
+(defwidget network []
+ (button :onclick `eww update network-extended=${network-extended ? "false" : "true"}`
+ (box :orientation "horizontal"
+ :class {"widget pill" + ((network-extended && wifi_ssid != "") ? " extended" : "")}
+ :spacing {(network-extended && wifi_ssid != "") ? 5 : 0}
+ :space-evenly false
+ (label :text {
+ (wifi_ssid == "") ? ""
+ : (wifi_strength == "") ? ""
+ : (wifi_strength < 75) ? ""
+ : (wifi_strength < 65) ? ""
+ : (wifi_strength < 60) ? ""
+ : (wifi_strength < 50) ? ""
+ : ""}
+ :class "base pill-icon")
+ (revealer :transition "slideleft"
+ :reveal {network-extended && wifi_ssid != ""}
+ :duration 150
+ (label :text wifi_ssid
+ :class "base")))))
+
+(defwidget battery []
+ (button :onclick `eww update bat-extended=${bat-extended ? "false" : "true"}`
+ (box :orientation "horizontal"
+ :class {"widget pill" + (bat-extended ? " extended" : "")}
+ :spacing {bat-extended ? 3 : 0}
+ :space-evenly false
+ (label :text {
+ (pbat_status == "Charging" || pbat_status == "Full") ?
+ ( (pbat_cap < 20) ? ""
+ : (pbat_cap < 50) ? ""
+ : (pbat_cap < 100) ? ""
+ : "" )
+ : (pbat_cap < 10) ? ""
+ : (pbat_cap < 20) ? ""
+ : (pbat_cap < 50) ? ""
+ : (pbat_cap < 80) ? ""
+ : ""}
+ :class "base pill-icon")
+ (revealer :transition "slideleft"
+ :reveal bat-extended
+ :duration 150
+ (label :text {pbat_cap + "%"}
+ :class "base")))))
+
+
+(defwidget time []
+ (button :onclick `eww update time-extended=${time-extended ? "false" : "true"}`
+ (box :orientation "horizontal"
+ :space-evenly false
+ :hexpand true
+ :class "widget time"
+ (time_extension :text petimea)
+ (label :text ptime
+ :class "base")
+ (time_extension :text petimeb))))
+
diff --git a/res/eww/scripts/active-workspace.sh b/res/eww/scripts/active-workspace.sh
new file mode 100755
index 0000000..d4e6b87
--- /dev/null
+++ b/res/eww/scripts/active-workspace.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env sh
+
+hyprctl monitors -j | jq '.[] | select(.focused) | .activeWorkspace.id'
+
+socat -u UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - |
+ stdbuf -o0 awk -F '>>|,' -e '/^workspace>>/ {print $2}' -e '/^focusedmon>>/ {print $3}'
diff --git a/res/eww/scripts/title.sh b/res/eww/scripts/title.sh
new file mode 100755
index 0000000..108e0a5
--- /dev/null
+++ b/res/eww/scripts/title.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env sh
+
+out () {
+ if [ -z "$1" ] || [ "$1" == "null" ]; then
+ echo ""
+ else
+ echo "(box :class \"widget title\" :halign \"center\" :valign \"center\" :vexpand true :hexpand true (label :text \"$1\"))"
+ fi
+}
+
+init=$(hyprctl activewindow -j | jq --raw-output .title)
+trunc=$(echo $init | cut -c-60)
+out "$trunc"
+
+socat -u UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | stdbuf -o0 awk -F '>>|,' '/^activewindow>>/{print $3}' | while read -r line ; do
+ trunc=$(echo $line | cut -c-60)
+ out "$trunc"
+done
diff --git a/res/eww/scripts/workspaces.sh b/res/eww/scripts/workspaces.sh
new file mode 100755
index 0000000..963dbe8
--- /dev/null
+++ b/res/eww/scripts/workspaces.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env sh
+
+spaces (){
+ WORKSPACE_WINDOWS=$(hyprctl workspaces -j | jq 'map({key: .id | tostring, value: .windows}) | from_entries')
+ seq 1 10 | jq --argjson windows "${WORKSPACE_WINDOWS}" --slurp -Mc 'map(tostring) | map({id: ., windows: ($windows[.]//0)})'
+}
+
+spaces
+socat -u UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | while read -r line; do
+ spaces
+done
diff --git a/res/theme.rasi b/res/theme.rasi
new file mode 100644
index 0000000..b7fd398
--- /dev/null
+++ b/res/theme.rasi
@@ -0,0 +1,89 @@
+// Stolen from https://github.com/DanisDGK thanks uwu
+
+configuration {
+ modi: "drun,run";
+ terminal: "kitty";
+ display-drun: "";
+ drun-display-format: "{name}";
+ sidebar-mode: false;
+ show-icons: true;
+}
+
+@theme "/dev/null"
+
+* {
+ bg: CAT_BACKGROUND;
+ fg: CAT_TEXT;
+ button: CAT_ACCENT;
+
+ background-color: @bg;
+ text-color: @fg;
+}
+
+window {
+ transparency: "real";
+ width: 40%;
+ border-radius: 20px;
+}
+
+prompt { enabled: false; }
+
+entry {
+ placeholder: "Search";
+ placeholder-color: CAT_PLACEHOLDER;
+ transparency: "real";
+ expand: true;
+ font: "Noto Sans 32";
+ padding: 1.5%;
+ border-radius: 8px;
+ background-color: transparent;
+}
+
+inputbar {
+ children: [ prompt, entry ];
+ expand: false;
+ border-radius: 0px 0 8px 8px;
+ padding: 30px 30px 15px 30px;
+}
+
+listview {
+ columns: 1;
+ lines: 4;
+ cycle: false;
+ dynamic: true;
+ layout: vertical;
+ padding: 30px 30px 15px 30px;
+}
+
+mainbox { children: [ inputbar, listview ]; }
+
+element {
+ orientation: horizontal;
+ padding: 1.5% 0% 1.5% 0%;
+ border-radius: 8px;
+}
+
+element-text {
+ expand: true;
+ vertical-align: 0.5;
+ horizontal-align: 0.97;
+ margin: 0% 3% 0.5% 3%;
+ background-color: inherit;
+ text-color: inherit;
+ font: "Noto Sans Medium 12";
+}
+
+element-icon {
+ vertical-align: 0.5;
+ horizonal-align: 0.03;
+ margin: 0.5% 3% 0.5% 3%;
+ background-color: inherit;
+ text-color: inherit;
+ size: 54;
+}
+
+element selected {
+ background-color: @button;
+ border-radius: 8px;
+ text-color: @bg;
+}
diff --git a/res/wallpaper.png b/res/wallpaper.png
index ea95619..fce7b00 100644
Binary files a/res/wallpaper.png and b/res/wallpaper.png differ
diff --git a/users/rin/scripts/osu b/scripts/osu
similarity index 100%
rename from users/rin/scripts/osu
rename to scripts/osu
diff --git a/scripts/tmptsync.sh b/scripts/tmptsync.sh
new file mode 100755
index 0000000..9d5aca7
--- /dev/null
+++ b/scripts/tmptsync.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Super simple script that saves clock to file and reads from it later
+# Something like fake-hwclock from debian
+# CC0-1.0
+
+CMD="${1:-save}"
+
+if [ ! -v FILE ]; then
+ echo 'missing $FILE'
+ exit 64
+fi
+
+case $CMD in
+ save)
+ date -u '+%Y-%m-%d %H:%M:%S' > $FILE
+ ;;
+ load)
+ if [ ! -e $FILE ]; then
+ echo "attempted to load from nonexistent file"
+ exit 65
+ fi
+ NEW=$(cat $FILE)
+ date -u -s "$NEW"
+ ;;
+ *)
+ echo "unknown subcommand"
+ exit 66
+ ;;
+esac
diff --git a/secrets.gcrypt/shared.json b/secrets.gcrypt/shared.json
new file mode 100644
index 0000000..21378e7
Binary files /dev/null and b/secrets.gcrypt/shared.json differ
diff --git a/secrets.nix b/secrets.nix
new file mode 100644
index 0000000..b1f55e5
--- /dev/null
+++ b/secrets.nix
@@ -0,0 +1,25 @@
+let
+ alyssum = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAp00i2DTwMk9i2WBEwpNTDA51TQJEqzpyCka6znmRzR";
+ anemone = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEPFifSAybe97xDP/cq6AAjy7Fm0go0dtQ9ICK6JRUgc";
+ blossom = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA5wfPCcpkNR3ubr7cBV0UwVCDo/sMmV0aI/JOJTIxQj";
+ dandelion = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFUk99ku7+eiIO7Q9sIPlPx3GiUljLv7W404W/zwrtzI";
+ hazel = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ6mi50ecrrMIn5C4QUyCjPHfSElz0mhevvFCznUzIrK";
+
+ rin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPru5eTBvHJ4ZmrrzPRHCGM09wQP/ZHSaKYalDuBVO15";
+in {
+ "secrets/passwd.age".publicKeys = [ alyssum anemone blossom rin ];
+ "secrets/passwd_smbcilly.age".publicKeys = [ alyssum rin ];
+ "secrets/passwd_smbkujira.age".publicKeys = [ alyssum rin ];
+ "secrets/wpa_conf.age".publicKeys = [ alyssum blossom rin ];
+
+ "secrets/acme_dns.age".publicKeys = [ alyssum dandelion hazel rin ];
+ "secrets/navidrome_env.age".publicKeys = [ alyssum dandelion rin ];
+ "secrets/slskd_env.age".publicKeys = [ anemone dandelion rin ];
+ "secrets/tailscale_auth.age".publicKeys = [ alyssum anemone blossom dandelion rin ];
+ "secrets/warden_admin.age".publicKeys = [ rin ];
+ "secrets/wg_anemone.age".publicKeys = [ anemone rin ];
+ "secrets/wg_dandelion.age".publicKeys = [ dandelion rin ];
+ "secrets/wg_hazel.age".publicKeys = [ hazel rin ];
+ "secrets/wg_hyacinth.age".publicKeys = [ blossom rin ];
+ "secrets/wg_caramel.age".publicKeys = [ rin ];
+}
diff --git a/secrets/acme_dns.age b/secrets/acme_dns.age
new file mode 100644
index 0000000..c440de6
--- /dev/null
+++ b/secrets/acme_dns.age
@@ -0,0 +1,11 @@
+age-encryption.org/v1
+-> ssh-ed25519 kOMSPw vqjZO82kILUQaoD9EwOgnmXKD9IyscgtzP65BVKkGhs
+07f0vL5fSq+EVdJ4n3L/q0tGsh0SVLCueTzbrMQC2ok
+-> ssh-ed25519 bRFqeQ qZAsyhdIY/fg7weEBYfB/WwFBrr/fDRrjt0J/m+57W4
+FOWjbk7efoVdL9WxjWvaZ/0mJrQ4yj0fN/Fa3zztz84
+-> ssh-ed25519 ZAcXHw UHpAQ4nKoGGaZWXVj4UM6uBanOgDpBvG6XdoBvhz6y8
+xF1orqajQxp2QzU/e1sq8lMxz4AQ2Vr5a3wEU55QqyE
+-> ssh-ed25519 U9FXlg n/LPuRDZ7N0VbZYLNr86hH/yRuqd2zFC7Nnpooz8d0o
+aZig/wjd5vitGaJwQ89w2M7fj8fAiqTpdDOmLae74sM
+--- mXuALIh6k4n0cErsTFnwKemo/r2jFG7mGSTz2M8zXF8
+Zr2. ~MPXŹ1)p9R9ScLzhQO0H7Lj5
\l97ܫn>
diff --git a/secrets/navidrome_env.age b/secrets/navidrome_env.age
new file mode 100644
index 0000000..7df364f
--- /dev/null
+++ b/secrets/navidrome_env.age
@@ -0,0 +1,9 @@
+age-encryption.org/v1
+-> ssh-ed25519 kOMSPw s/uDjoILzZ4meH5Thqdly/pPe2bTO7sKHPIsn7B/Ays
+Pg3ePdLimArZbzBJJkole/d6UjUafNayktjKqt9gqv4
+-> ssh-ed25519 bRFqeQ /yrku11wKk2gf24aPjSBZ1KBZXLOlSTOgvW13gjzC3M
+xTCWHdq5Vr02v9xDoEZqCcGLIdjZT9s29Gldoz27ow0
+-> ssh-ed25519 U9FXlg HhSqF8DRz/vW42Sf34fqGMIgj9Zpc5MeYNhqqsz7fBk
+4IzAURq50rY160/qAzo49cmhV7/skh7PGM8h9qI9WGE
+--- aSO1slFKfkECL6Gro84fMiDZ0QLLNbOrfiNegNK7ksc
+i'rЌl"j^S"_UPCxs1Mwʍ;#{a}+=eԑ$#szKiJD?>F8kZ(;)[b+o@#2L,חL<\U#>13p\IQ)@p,C5v8M%NA r7ɀnt'Ѕֲ5+bj)RaC
\ No newline at end of file
diff --git a/secrets/passwd.age b/secrets/passwd.age
new file mode 100644
index 0000000..05ad906
--- /dev/null
+++ b/secrets/passwd.age
@@ -0,0 +1,11 @@
+age-encryption.org/v1
+-> ssh-ed25519 kOMSPw rWkX3HSRLDrGS1MJhIttcTrDpUkpKuvgzzj8VGYwo00
+ei4Smot7TzHG267tZOTHZGP/r708VyXsth6JkutoD0M
+-> ssh-ed25519 ohyStA i3Os44jBRhjApBM+LB2OBtN5Va5B4Rn9ns1T5ZgHsjw
+chQ66k2O/5vKQ/H3UK/SpyAVyMijeFzPamZrUuA2gFE
+-> ssh-ed25519 CUCjXQ bcoF9UqyTLIkv8voU3MqN8Z3ewXbIkDwdTD0MAbNiwA
+clZLUvkiT8kXITUh3n1khtUKRhzSEfql1+LaTpGyXtE
+-> ssh-ed25519 U9FXlg ICIR8S4zMAdXicH72HzJeeQfffjNThvSDkGc9fkRKQQ
+lr3xEi63dR+sywvIrbOTWkYyd9jTX619LHvZU9H9+Bw
+--- P7jilfDiKJ6O6vXk5s3FimCLHRQoVatVwoEjzoYncdg
+$as[ԡ`|7nYYU6#8FlW'H;O)OMB1b_iSpgu-yhVB ssh-ed25519 kOMSPw CQaXT9/nw3NGD2/H/ctSQGXIoacgjfKQ24wkpEieLSQ
+i4xEXgWGQ7xgQyaDQQIeDuiCLjA6Le23qSnv8C1cbcI
+-> ssh-ed25519 U9FXlg GL4dCSCku/FA6ipb9XI1AxO4lhm2r/1lRAeqaGrB32o
++pPgqwnoPi3wJLobTimVMj0rng+XRapRG6jTYFXSsDM
+--- eVgn3ON19pqq+L832bqlbkHUQXdaTI+LfSL4bYfEdew
+*l\W!J7E/"f@%\[j8fӶ
\ No newline at end of file
diff --git a/secrets/passwd_smbkujira.age b/secrets/passwd_smbkujira.age
new file mode 100644
index 0000000..71b6bb8
--- /dev/null
+++ b/secrets/passwd_smbkujira.age
@@ -0,0 +1,7 @@
+age-encryption.org/v1
+-> ssh-ed25519 kOMSPw Kn+LPMoyOrVwI/nrGgnxgVA3D+tVY9Tccg/Yx/jL+E8
+IfWiSBh7KgNvgcHlcDzfdcB9nxm1zy12Ae7AGm39fdE
+-> ssh-ed25519 U9FXlg 6eIIGEIYDo02FBsgBnwbuOeR8t4xB6jSmLfIL73UCDg
+QOc0ddunQQcVEVD20DKKpn3wZWUSveFJSUTBnv+xnNk
+--- MjN2i0FNzbUpBGUDNgWGXrRsYl2gtsQX+JlzZV/fYdw
+T <R#dĆ̎lLkN8c_N)T
\ No newline at end of file
diff --git a/secrets/slskd_env.age b/secrets/slskd_env.age
new file mode 100644
index 0000000..eded5d0
--- /dev/null
+++ b/secrets/slskd_env.age
@@ -0,0 +1,9 @@
+age-encryption.org/v1
+-> ssh-ed25519 ohyStA 3Do7MsCBX9ZgP6pIekvkRisFgF74jq2cKxrjUi2NlhM
+EdfLIUk40isfNBY4CKA0JjHc2RaCM/LJmvQJuue+aYs
+-> ssh-ed25519 bRFqeQ XcjdLy6CEELgdN133BkgTG0cUffU6N9nsapB3c9Swyc
++ILEkir7XMK/xLNrTs2R+pBoucIN7fVEBRZSZwBo7Fs
+-> ssh-ed25519 U9FXlg bqpdUcMN/bk7WlIruWmhj0hpFL/CliDHto/P/KaMdxk
+z6wKPbT1OAW7sDjeziwdqs6mf9Rk37xsU9pw4wYMOF4
+--- wNvTtQPOTxetOpazjBXo4fR3wPL7CVQq4R30gOj/qQw
+&P+Sy=}~1C^.?zLHR`akER(4R!*l!A~@VG<2-K8HPu2jS#WДl>@a .MƞHg[$Wˌ["%N, rGNmf9Fk&~OWZ70t?eOfAz,hq/Z&Fy5ɾBQw/"JS섘5f}%BPĮ,rF`NmnCÎrJaf i?0pzaV[yjX4B>R,tyOIW!(n#ܒj>589d0mi%tCR˄^IrM")֙S&.)lzӨq:rbrE@JǺsMd?Sk
\ No newline at end of file
diff --git a/secrets/tailscale_auth.age b/secrets/tailscale_auth.age
new file mode 100644
index 0000000..be7af43
--- /dev/null
+++ b/secrets/tailscale_auth.age
@@ -0,0 +1,13 @@
+age-encryption.org/v1
+-> ssh-ed25519 kOMSPw judP6VmZDGErkHfUpCp3xTgJtWVmGv3/tZw3WGyhfhM
+10jxPIR6Qaf/iWLzbWOrFq9XBsm8OC3mcMrxEt+BYQ8
+-> ssh-ed25519 ohyStA Xc6TjSJYtJkK1VEauNJKn+RcTdwdkyJ0Sr+tbAJ8rGc
+vzQt4zMdktY5tNvfu9HsKBgJb52uM7x8bhF+WXwpWZ8
+-> ssh-ed25519 CUCjXQ r8WxaXpWtaBdMJ2ubaAwJ4ipSz/UtnMs0x3+eI8p0VU
+CdicUH7AE4E4XVHDAeYzQdsYMYA0sCLlt2P4eR24vvs
+-> ssh-ed25519 bRFqeQ E9sknPioO9leKqs8bFJDLrAMuRAJf0ZRyGMvy7O5wVA
+KX93oSqGHimM/PaeaoHq1aYVXGG1YsVMO2ihZaM8xVE
+-> ssh-ed25519 U9FXlg u7yG7cLylPUgu/Is4xx0BXVhX31vUtgStV5CYa8Cowg
+xAuGYZpMPVQpZYASXrMuqNE9wqqEG3kMLUNjLzPmL4g
+--- EoeqIMnX5tR3J51Cz2QEyjsgD/7h468bqjRmt3mOEjY
+xHQ)k)ĉB~ە֖Zv?%lQx
OwZIsۄf4Dǔ*Otݳ0.m[q_[v
\ No newline at end of file
diff --git a/secrets/warden_admin.age b/secrets/warden_admin.age
new file mode 100644
index 0000000..1c56924
Binary files /dev/null and b/secrets/warden_admin.age differ
diff --git a/secrets/wg_anemone.age b/secrets/wg_anemone.age
new file mode 100644
index 0000000..3ed5b37
Binary files /dev/null and b/secrets/wg_anemone.age differ
diff --git a/secrets/wg_caramel.age b/secrets/wg_caramel.age
new file mode 100644
index 0000000..a85d63f
--- /dev/null
+++ b/secrets/wg_caramel.age
@@ -0,0 +1,6 @@
+age-encryption.org/v1
+-> ssh-ed25519 U9FXlg VpFnvpTVZFSkKRpEgcmuT/WDLIP1ZySFLq2lRvrjq20
+7zQoSoIs1URmAYn2AdjvDTIY8GDYROcSxFq1bcl24Og
+--- iaQQUE1/Xj1vxto3d+Llyl6XGrSff5MGPxdCHW9EI40
+Ʀ`t \
+bpeHX3!$3]X32t~V.=>$xBKJAL:DD}5
\ No newline at end of file
diff --git a/secrets/wg_dandelion.age b/secrets/wg_dandelion.age
new file mode 100644
index 0000000..0229699
--- /dev/null
+++ b/secrets/wg_dandelion.age
@@ -0,0 +1,7 @@
+age-encryption.org/v1
+-> ssh-ed25519 bRFqeQ swv/p+w9+aytIkQ/6Yk1jouA+0M3rJabuiOz2rlpyAs
+wt+wnM1EEKAyDNefr9K4+DtZvHcOzz9Y1EBRFkA5Nv4
+-> ssh-ed25519 U9FXlg xxV/8JoorO4YWPbwSG7p306Pb2+aT10u9eNR69PhZAA
+rjOOuapa/h1tMYbdOc3Y/fPPzkNcYiamSk6rS/tbhtE
+--- UKvt/4aAyYHOk5bhAP55yxPhkxTE94/xEqIqpGF3yiE
+5;_EDB ssh-ed25519 ZAcXHw eEKOjQqzqL9npB+C/wUahKJg58fedM6oxPKuKlMHpRo
+obx/pnoSM0uXYR7EC/yHYVs8gM/W74zoMijdWRpnYv8
+-> ssh-ed25519 U9FXlg o8QW/BHBKLHhahpcHf5ZrYIbCzilWVZvXr1nEChAqFM
+fgmtkUzJs2Oeq85JVl0HrHwBg/gjDQfzT5J+9Wyk8Kw
+--- yXs0fQOQfJ1NyPAPSr+1nm5/hVds5dhxW4WZagtMna0
+;ǓוZI=Z[cϏ7&.HFkJUDNi_NTȊ"l_Go)fs9&
\ No newline at end of file
diff --git a/secrets/wg_hyacinth.age b/secrets/wg_hyacinth.age
new file mode 100644
index 0000000..082940f
--- /dev/null
+++ b/secrets/wg_hyacinth.age
@@ -0,0 +1,7 @@
+age-encryption.org/v1
+-> ssh-ed25519 CUCjXQ ptHKlNvz+AmnB/Wt9XBBNyfOGeoPG5TbyrXv5993PDQ
+P0C17K+Kz8ocn0vzLf02aaYnxvRM/yjfRLMsBaJhsok
+-> ssh-ed25519 U9FXlg /M8ryJjXAdlWhvNHbQgKUxe/UtL7HqEs9RqNDQBW3SM
+p2d9OnOkU2Hx7+Kn+Z66qElFvczd3F4zVm5KXbOzYWY
+--- PVd8mrRk/t6qv/U32/AZk9YssRU1yn3CLPeyaEPBXi0
+:Dx[cyyۙc4ɥ/އ^.=ȯoGVQdXf^@TRegn9UT
\ No newline at end of file
diff --git a/secrets/wpa_conf.age b/secrets/wpa_conf.age
new file mode 100644
index 0000000..555b594
--- /dev/null
+++ b/secrets/wpa_conf.age
@@ -0,0 +1,9 @@
+age-encryption.org/v1
+-> ssh-ed25519 kOMSPw WjWYVdPA5nC91K7UTi5lsbmljg1nVKCGkx1xtWWmR3A
+ZqwrUa6UMKMs7VPPlL7Q7mevVS8PKb/CBmPjt9l+stE
+-> ssh-ed25519 CUCjXQ 6NWpq4HWsktCO86TO8QvPA13gu5QVo6MDh8pNGYItn4
+LBqgl0q5VF/246BNc1+Mp4nKgpFdsbM6B/H/dL2e3lE
+-> ssh-ed25519 U9FXlg yWJhHQPrrE/OvVSTJyPove9/eyCDOozEBUhSPpEDvSs
+TI5tdtnRnNhVe6whNVmuQA/TcO5VlUCwTOpauoMqtRw
+--- FCXwxwx3KHMqQic8vkJVcxRqvUIisZRtoVA4lRo9+8o
+c;)s9xXPG6>u@1o\ -<1 ,⯨RS(Q8oἐJy7fK>#FU S,AQ}xV0QOށ[%?u
\ No newline at end of file
diff --git a/update.sh b/update.sh
new file mode 100755
index 0000000..6167e8c
--- /dev/null
+++ b/update.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env -S nix shell 'nixpkgs#git' 'nixpkgs#curl' -c bash
+
+update_kernel() {
+ previous_ver=$(cat packages/linux-lava/sources.nix | grep "version =" | sed --expression='s/[^0-9.]//g')
+ kernel_ver=$(curl -s https://www.kernel.org/finger_banner | grep -m1 stable | awk '{print $NF}')
+
+ if [ "$previous_ver" = "$kernel_ver" ]; then
+ return
+ fi
+
+ kernel_major=$(cut -d '.' -f 1 <<< "$kernel_ver")
+ kernel_mmver=$(cut -d '.' -f 1,2 <<< "$kernel_ver")
+
+ hash_mm=$(nix-prefetch-url "https://cdn.kernel.org/pub/linux/kernel/v${kernel_major}.x/linux-${kernel_mmver}.tar.xz")
+ hash_patch=$(nix-prefetch-url "https://cdn.kernel.org/pub/linux/kernel/v${kernel_major}.x/patch-${kernel_ver}.xz")
+
+ sed -i "/version =/c\ version = \"${kernel_ver}\";" packages/linux-lava/sources.nix
+ sed -i "/kernelHash =/c\ kernelHash = \"${hash_mm}\";" packages/linux-lava/sources.nix
+ sed -i "/kernelPatchHash =/c\ kernelPatchHash = \"${hash_patch}\";" packages/linux-lava/sources.nix
+
+ git add packages/linux-lava/sources.nix
+ git commit -m "packages/linux-lava: bump to ${kernel_ver}"
+}
+
+bump_inputs() {
+ nix flake update
+ git add flake.lock
+ git commit -m "flake: bump inputs"
+}
+
+bump_inputs
+update_kernel
diff --git a/users/hana/default.nix b/users/hana/default.nix
new file mode 100644
index 0000000..69558ea
--- /dev/null
+++ b/users/hana/default.nix
@@ -0,0 +1,36 @@
+{ config, lib, modules, pkgs, ... }: {
+ programs.nh.flake = "/persist/hana/flakes";
+ programs.zsh.enable = true;
+ users.users.hana = {
+ isNormalUser = true;
+ extraGroups = [ "wheel" ];
+ shell = pkgs.zsh;
+ uid = 1002;
+ hashedPassword = "$y$j9T$3xCNDudmfrIu5VfQQoDkj/$ugzJWq0gORN9jnhDsREu31CkL3zwniQu6KoLbmg6Wr/";
+ openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPru5eTBvHJ4ZmrrzPRHCGM09wQP/ZHSaKYalDuBVO15 rin@anemone"
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILhP8yi/CdACtql3I4j0xI+r0KV4AVCb265Bd/RTFBu4 hana@dandelion"
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ5l9t8dc6mPsKKYqZlPKvhOdyqz+DS5UOcvHuh3uVGt cilly@hibiscus"
+ ];
+ };
+
+ home-manager.users.hana = { config, lib, pkgs, ... }: {
+ home = {
+ username = "hana";
+ homeDirectory = "/home/hana";
+ stateVersion = "24.11";
+ };
+
+ imports = with modules.user; [
+ comma
+ direnv
+ git
+ neovim-minimal
+ sessionVariables
+ zsh
+ ];
+
+ programs.git.signing.signByDefault = lib.mkForce false;
+ programs.zsh.history.path = lib.mkForce "/persist/hana/zsh_history";
+ };
+}
diff --git a/users/rin/alacritty.nix b/users/rin/alacritty.nix
deleted file mode 100644
index bd814dd..0000000
--- a/users/rin/alacritty.nix
+++ /dev/null
@@ -1,38 +0,0 @@
-{ config, ... }: {
- programs.alacritty = {
- enable = true;
- settings = {
- scrolling = {
- history = 10000;
- multiplier = 3;
- };
- font = {
- normal = {
- family = "CascadiaCode";
- style = "Regular";
- };
- size = 8.6;
- };
- window = {
- dynamic_title = true;
- padding = {
- x = 5;
- y = 0;
- };
- };
- # TODO: how
- # hints.enabled = [{
- # command = "xdg-open";
- # post_processing = true;
- # mouse = {
- # enabled = true;
- # mods = "Control";
- # };
- # }];
-
- colors.primary.background = "#000000";
- background_opacity = 0.65;
- draw_bold_text_with_bright_colors = true;
- };
- };
-}
diff --git a/users/rin/bspwm.nix b/users/rin/bspwm.nix
deleted file mode 100644
index d20632d..0000000
--- a/users/rin/bspwm.nix
+++ /dev/null
@@ -1,16 +0,0 @@
-{ config, ... }: {
- xsession.windowManager.bspwm = {
- enable = true;
- monitors = { eDP-1 = [ "I" "II" "III" "IV" "V" "VI" "VII" "VIII" "XI" "X" ]; };
- settings = {
- window_gap = 10;
- border_width = 0;
- split_ratio = 0.5;
- top_padding = 25;
- };
- extraConfig = ''
- feh --no-fehbg --bg-fill ${config.xdg.configHome}/xorg/wallpaper.png
- systemctl --user restart polybar # home-manager loads this too early
- '';
- };
-}
diff --git a/users/rin/default.nix b/users/rin/default.nix
index dd9a585..a70d716 100644
--- a/users/rin/default.nix
+++ b/users/rin/default.nix
@@ -1,9 +1,62 @@
-{ config, pkgs, ... }: {
+{ config, modules, pkgs, ... }: {
+ programs.nh.flake = "/home/rin/Projects/flakes";
+ programs.zsh.enable = true;
users.users.rin = {
isNormalUser = true;
- extraGroups = [ "audio" "video" "wheel" ];
+ extraGroups = [ "adbusers" "audio" "corectrl" "dialout" "docker" "libvirtd" "networkmanager" "video" "wheel" "wireshark" ];
shell = pkgs.zsh;
uid = 1001;
+ hashedPasswordFile = config.age.secrets.passwd.path;
+ };
+ home-manager.users.rin = { config, lib, pkgs, ... }: {
+ home = {
+ username = "rin";
+ homeDirectory = "/home/rin";
+ stateVersion = "21.05";
+ keyboard = null; # see https://github.com/nix-community/home-manager/issues/2219
+ };
+
+ imports = with modules.user; [
+ ./packages.nix
+ sessionVariables
+
+ catppuccin
+ comma
+ direnv
+ git
+ gpg
+ neovim
+ npm
+ zsh
+ # HACK: include all gui for now due to infinite recursion (inability to dynamically control imports)
+ # ] ++ lib.optionals config.me.gui [
+ ] ++ [
+ theming
+ xdg
+
+ hypridle
+ hyprlock
+ kitty
+ mpv
+ obs
+ rofi
+
+ dunst
+ eww
+
+ spicetify
+ ];
+
+ services.mpris-proxy.enable = true;
+ home.packages = [ pkgs.wl-clipboard ];
+
+ home.file.".local/bin/ipc-bridge.exe".source = builtins.fetchurl {
+ url = "https://github.com/0e4ef622/wine-discord-ipc-bridge/releases/download/v0.0.1/winediscordipcbridge.exe";
+ sha256 = "1swn9spxpq6blm74kjmfz4ipq6a8qjzccvb2msb25pf5b1z7jnns";
+ };
+ home.file.".local/bin/osu" = {
+ executable = true;
+ source = ../../scripts/osu;
+ };
};
- home-manager.users.rin = import ./home.nix;
}
diff --git a/users/rin/dunst.nix b/users/rin/dunst.nix
deleted file mode 100644
index 9699e94..0000000
--- a/users/rin/dunst.nix
+++ /dev/null
@@ -1,68 +0,0 @@
-# TODO: i've literally never configured dunst ever since i first installed it (the rc was copypasted from somewhere i forgot im sorry), should play around with it later
-{ config, ... }: {
- services.dunst = {
- enable = true;
- settings = {
- global = {
- monitor = 0;
- follow = "mouse";
- #geometry = "250x50-24+24";
- geometry = "600x50-24+24";
- indicate_hidden = true;
- shrink = true;
- separator_height = 0;
- padding = 16;
- horizontal_padding = 24;
- frame_width = 2;
- sort = false;
- idle_threshold = 120;
- font = "Open Sans 8";
- line_height = 4;
- markup = "full";
- format = "%s\\n%b";
- alignment = "left";
- show_age_threshold = 60;
- word_wrap = true;
- ignore_newline = false;
- stack_duplicates = false;
- hide_duplicate_count = true;
- show_indicators = false;
- icon_position = "left";
- max_icon_size = 32;
- sticky_history = true;
- history_length = 20;
- browser = "/run/current-system/sw/bin/firefox -new-tab";
- always_run_script = true;
- title = "Dunst";
- class = "Dunst";
- corner_radius = 5;
- };
-
- shortcuts = {
- close = "ctrl+space";
- close_all = "ctrl+shift+space";
- history = "ctrl+grave";
- context = "ctrl+shift+period";
- };
-
- urgency_low = {
- background = "#2f343f";
- foreground = "#d8dee8";
- timeout = 2;
- };
-
- urgency_normal = {
- background = "#2f343f";
- foreground = "#d8dee8";
- timeout = 4;
- };
-
- urgency_critical = {
- background = "#2f343f";
- foreground = "#d8dee8";
- frame_color = "#bf616a";
- timeout = 0;
- };
- };
- };
-}
diff --git a/users/rin/home.nix b/users/rin/home.nix
deleted file mode 100644
index d866e69..0000000
--- a/users/rin/home.nix
+++ /dev/null
@@ -1,103 +0,0 @@
-{ config, pkgs, ... }: rec {
- home = {
- username = "rin";
- homeDirectory = "/home/rin";
- stateVersion = "21.05";
- packages = with pkgs; [
- appimage-run
- brave
- discord-canary
- element-desktop
- ffmpeg
- gnome.file-roller
- ghidra-bin
- gimp
- gnupg
- inkscape
- kotatogram-desktop
- lf
- mps-youtube
- neofetch
- pamixer
- pavucontrol
- tor-browser-bundle-bin
- transcrypt
- transmission-remote-gtk
- unrar
- vlc
- wine-osu
- (winetricks.override { wine = wine-osu; })
- xorg.xgamma
- youtube-dl
- ];
- };
-
- imports = [
- ./theming.nix
- ./xdg.nix
-
- ./alacritty.nix
- ./mpv.nix
- ./neovim.nix
- ./npm.nix
- ./rofi.nix
- # ./urxvt.nix
- ./zsh.nix
-
- ./dunst.nix
- ./picom.nix
- ./polybar.bspwm.nix
- # ./polybar.i3.nix
-
- ./xorg.nix
- ./sxhkd.nix
- ./bspwm.nix
- # ./i3.nix
- ];
-
- programs = {
- feh.enable = true;
-
- direnv = {
- enable = true;
- nix-direnv = {
- enable = true;
- enableFlakes = true;
- };
- };
- git = {
- enable = true;
- userName = "LavaDesu";
- userEmail = "me@lava.moe";
- signing = {
- key = "059F098EBF0E9A13E10A46BF6500251E087653C9";
- signByDefault = true;
- };
- extraConfig = {
- core.abbrev = 11;
- };
- };
- gpg = {
- enable = true;
- homedir = "${config.xdg.dataHome}/gnupg";
- };
- };
-
- services = {
- # TODO: borked
- clipmenu.enable = false;
- gpg-agent = {
- enable = true;
- pinentryFlavor = "gnome3";
- };
- };
-
- home.file.".local/bin/ipc-bridge.exe".source = builtins.fetchurl {
- url = "https://github.com/0e4ef622/wine-discord-ipc-bridge/releases/download/v0.0.1/winediscordipcbridge.exe";
- sha256 = "1swn9spxpq6blm74kjmfz4ipq6a8qjzccvb2msb25pf5b1z7jnns";
- };
- home.file.".local/bin/osu" = {
- executable = true;
- source = ./scripts/osu;
- };
-}
diff --git a/users/rin/i3.nix b/users/rin/i3.nix
deleted file mode 100644
index 4c7cbc2..0000000
--- a/users/rin/i3.nix
+++ /dev/null
@@ -1,233 +0,0 @@
-{ config, pkgs, ... }:
-let
- super = "Mod4";
- alt = "Mod1";
-
- mkGapsMode = mode: {
- "plus" = "gaps ${mode} current plus 5";
- "minus" = "gaps ${mode} current minus 5";
- "0" = "gaps ${mode} current set 0";
- "Shift+plus" = "gaps ${mode} all plus 5";
- "Shift+minus" = "gaps ${mode} all minus 5";
- "Shift+0" = "gaps ${mode} all set 0";
- "Return" = "mode gapsMode";
- "Escape" = "mode default";
- };
- genGapsModes = modes: builtins.listToAttrs (builtins.map (mode: {
- name = mode;
- value = mkGapsMode mode;
- }) modes);
- genColors = states: builtins.listToAttrs (builtins.map (state: {
- name = state;
- value = {
- background = "#2f343f";
- border = "#2f343f";
- childBorder = "#2f343f";
- indicator = "#2f343f";
- text = "#d8dee8";
- };
- }) states);
-
-in rec {
- xsession.windowManager.i3 = {
- enable = true;
- package = pkgs.i3-gaps;
-
- config = {
- startup = [
- {
- # HACK: what is this lol
- command = "systemctl --user restart polybar";
- always = true;
- notification = false;
- }
- {
- command = "feh --no-fehbg --bg-fill ${config.xdg.configHome}/xorg/wallpaper.png";
- always = true;
- notification = false;
- }
- ];
-
- fonts = {
- names = [
- "Open Sans"
- "HanaMinA"
- "HanaMinB"
- ];
- style = "Regular";
- size = 8.0;
- };
-
- floating = {
- titlebar = false;
- modifier = super;
- border = 0;
- };
-
- window.border = 0;
- bars = [];
-
- gaps = {
- smartGaps = true;
- inner = 5;
- };
-
- colors = genColors [
- "focused"
- "focusedInactive"
- "unfocused"
- "urgent"
- "placeholder"
- ] // { background = "#2f343f"; };
- #colors.focused.background = "#1d242f";
-
- modifier = super;
- keybindings = {
- # Rofi (App launcher)
- "${super}+Return" = "exec rofi -lines 12 -padding 18 -width 60 -location 0 -show drun -sidebar-mode -columns 3 -font 'Noto Sans 8'";
-
- # Printscreen
- "Print" = "exec maim -us | tee ~/Pictures/Screenshots/$(date +%s)c.png | xclip -selection clipboard -t image/png";
- "Shift+Print" = "exec maim -u | tee ~/Pictures/Screenshots/$(date +%s).png | xclip -selection clipboard -t image/png";
-
- # Quick-kill picom
- "${super}+p" = "exec systemctl --user stop picom";
- "${super}+Shift+p" = "exec systemctl --user restart picom";
-
- # Volume
- "XF86AudioRaiseVolume" = "exec pamixer -i 5%";
- "XF86AudioLowerVolume" = "exec pamixer -d 5%";
- "XF86AudioMute" = "exec pamixer -t";
-
- # Brightness
- "XF86MonBrightnessUp" = "exec light -A 10";
- "XF86MonBrightnessDown" = "exec light -U 10";
- "Shift+XF86MonBrightnessUp" = "exec light -A 1";
- "Shift+XF86MonBrightnessDown" = "exec light -U 1";
- "Ctrl+XF86MonBrightnessUp" = "exec xgamma -gamma 1.3";
- "Ctrl+XF86MonBrightnessDown" = "exec xgamma -gamma 1";
-
- # Music control
- # "XF86AudioNext" = "exec mpc next";
- # "XF86AudioPrev" = "exec mpc prev";
- # "XF86AudioPlay" = "exec mpc toggle";
- # "XF86AudioStop" = "exec mpc stop";
-
- # Kill focused window
- "${super}+c" = "kill";
- "${alt}+F4" = "kill";
-
- # Change focus
- "${super}+Left" = "focus left";
- "${super}+Down" = "focus down";
- "${super}+Up" = "focus up";
- "${super}+Right" = "focus right";
- "${super}+h" = "focus left";
- "${super}+j" = "focus down";
- "${super}+k" = "focus up";
- "${super}+l" = "focus right";
-
- # Move focused window
- "${super}+Shift+Left" = "move left";
- "${super}+Shift+Down" = "move down";
- "${super}+Shift+Up" = "move up";
- "${super}+Shift+Right" = "move right";
- "${super}+Shift+h" = "move left";
- "${super}+Shift+j" = "move down";
- "${super}+Shift+k" = "move up";
- "${super}+Shift+l" = "move right";
-
- # Change split modes
- "${super}+b" = "split h";
- "${super}+v" = "split v";
- "${super}+s" = "layout toggle split";
- "${super}+w" = "layout tabbed";
-
- # Enter fullscreen
- "${super}+f" = "fullscreen toggle";
-
- # Toggle floating windows
- "${super}+space" = "floating toggle";
-
- # Restart / Exit i3
- "${super}+Shift+r" = "restart";
- "${super}+q" = "exec i3-nagbar -m 'Exit?' -b 'Yes' 'i3-msg exit'";
-
- # Modes
- "${super}+r" = "mode Resize";
- "${super}+Shift+g" = "mode Gaps";
-
- # Workspace switching
- "${super}+1" = "workspace number $ws1";
- "${super}+2" = "workspace number $ws2";
- "${super}+3" = "workspace number $ws3";
- "${super}+4" = "workspace number $ws4";
- "${super}+5" = "workspace number $ws5";
- "${super}+6" = "workspace number $ws6";
- "${super}+7" = "workspace number $ws7";
- "${super}+8" = "workspace number $ws8";
- "${super}+9" = "workspace number $ws9";
- "${super}+0" = "workspace number $ws10";
- "${alt}+Control+Left" = "workspace prev";
- "${alt}+Control+Right" = "workspace next";
- "${alt}+Control+h" = "workspace prev";
- "${alt}+Control+l" = "workspace next";
-
- "${super}+Shift+1" = "move container to workspace number $ws1";
- "${super}+Shift+2" = "move container to workspace number $ws2";
- "${super}+Shift+3" = "move container to workspace number $ws3";
- "${super}+Shift+4" = "move container to workspace number $ws4";
- "${super}+Shift+5" = "move container to workspace number $ws5";
- "${super}+Shift+6" = "move container to workspace number $ws6";
- "${super}+Shift+7" = "move container to workspace number $ws7";
- "${super}+Shift+8" = "move container to workspace number $ws8";
- "${super}+Shift+9" = "move container to workspace number $ws9";
- "${super}+Shift+0" = "move container to workspace number $ws10";
- };
-
- modes = {
- "Resize" = {
- "Left" = "resize shrink width 5 px or 5 ppt";
- "Down" = "resize grow height 5 px or 5 ppt";
- "Up" = "resize shrink height 5 px or 5 ppt";
- "Right" = "resize grow width 5 px or 5 ppt";
- "Return" = "mode default";
- };
- "Gaps" = {
- "o" = "mode Outer";
- "i" = "mode Inner";
- "h" = "mode Horizontal";
- "v" = "mode Vertical";
- "t" = "mode Top";
- "r" = "mode Right";
- "b" = "mode Bottom";
- "l" = "mode Left";
- "Return" = "mode Gaps";
- "Escape" = "mode default";
- };
- } // genGapsModes [
- "Outer"
- "Inner"
- "Horizontal"
- "Vertical"
- "Top"
- "Right"
- "Bottom"
- "Left"
- ];
- };
-
- extraConfig = ''
- set $ws1 "1:code"
- set $ws2 "2:web"
- set $ws3 "3:discord"
- set $ws4 "4:game"
- set $ws5 "5"
- set $ws6 "6"
- set $ws7 "7"
- set $ws8 "8:steam"
- set $ws9 "9:spotify"
- set $ws10 "10:term"
- '';
- };
-}
diff --git a/users/rin/neovim.nix b/users/rin/neovim.nix
deleted file mode 100644
index 982264d..0000000
--- a/users/rin/neovim.nix
+++ /dev/null
@@ -1,91 +0,0 @@
-{ config, pkgs, ... }:
-let
- vim-material = pkgs.vimUtils.buildVimPlugin {
- name = "vim-material";
- src = pkgs.fetchFromGitHub {
- owner = "hzchirs";
- repo = "vim-material";
- rev = "05461c967b861ef532c44d5348555febac94b0d5";
- sha256 = "1w59zqrx3scqsrg1a43497xybc3m4zm00kwfqpvjfw6qrpk2zb3f";
- };
- };
-in {
- programs.neovim = {
- enable = true;
- viAlias = true;
- vimAlias = true;
- vimdiffAlias = true;
-
- plugins = with pkgs.vimPlugins; [
- # nerdtree
- # vim-fugitive
- ale
- coc-nvim
- dart-vim-plugin
- vim-airline
- vim-javascript
- vim-material
- vim-nix
- vim-repeat
- vim-surround
-
- lf-vim
- vim-floaterm
- ];
- withNodeJs = true;
-
- extraConfig = ''
- " configuration
- syntax enable
- set relativenumber number
- set noswapfile
- set hlsearch
- set ignorecase
- set incsearch
- set title
- set clipboard^=unnamed
- set tabstop=8 softtabstop=0 expandtab shiftwidth=4 smarttab
- set expandtab
-
- " theming
- set termguicolors
- hi MatchParen cterm=underline ctermbg=none ctermfg=white
- let g:material_style='oceanic'
- let g:airline_theme='material'
- set background=dark
- colorscheme vim-material
-
- " using tab for trigger completion
- function! s:check_back_space() abort
- let col = col('.') - 1
- return !col || getline('.')[col - 1] =~ '\s'
- endfunction
-
- inoremap
- \ pumvisible() ? "\" :
- \ check_back_space() ? "\" :
- \ coc#refresh()
-
- inoremap pumvisible() ? "\" : "\u\"
- inoremap coc#refresh()
-
- " various aliases
- nnoremap :Lf
- nnoremap r :source $MYVIMRC
- command! -nargs=0 Sw w !doas tee % > /dev/null
-
- " disable read-only warning
- au BufEnter * set noro
-
- " disable empty line tildes
- set fcs=eob:\
-
- let g:coc_global_extensions = ['coc-tsserver', 'coc-rust-analyzer', 'coc-flutter']
- '';
- };
- xdg.configFile."nvim/coc-settings.json".text = builtins.toJSON {
- "rust-analyzer.lens.enable" = false;
- "rust-analyzer.inlayHints.enable" = false;
- "rust-analyzer.serverPath" = pkgs.rust-analyzer + "/bin/rust-analyzer";
- };
-}
diff --git a/users/rin/packages.nix b/users/rin/packages.nix
new file mode 100644
index 0000000..3fe0129
--- /dev/null
+++ b/users/rin/packages.nix
@@ -0,0 +1,70 @@
+{ config, inputs, pkgs, ... }:
+let
+ dotnet-combined = (with pkgs.dotnetCorePackages; combinePackages [
+ dotnet_10.sdk
+ aspnetcore_10_0-bin
+ ]);
+in {
+ programs.firefox = {
+ enable = true;
+ nativeMessagingHosts = [];
+ };
+
+ home.packages = with pkgs; [
+ dconf
+ ffmpeg
+ gnupg
+ kitty
+ nodejs_latest
+ pamixer
+ pnpm
+ unrar
+ yt-dlp
+ ] ++ lib.optionals (config.me.environment == "desktop") [
+ krita
+ lutris
+ mangohud
+ inputs.nix-gaming.packages.x86_64-linux.osu-lazer-bin
+ qmk
+ tetrio-desktop
+ tor-browser
+ virt-manager
+ winetricks
+ ] ++ lib.optionals config.me.gui [
+ android-studio
+ brightnessctl
+ drawio
+ evince
+ eww
+ feh
+ feishin
+ file-roller
+ gamescope
+ gimp3
+ grim
+ lm_sensors
+ maim
+ me.psensor
+ obsidian
+ pavucontrol
+ (prismlauncher.override {
+ jdks = [
+ jdk21
+ temurin-bin-25
+ ];
+ })
+ qbittorrent
+ rivalcfg
+ screenkey
+ slurp
+ swaybg
+ texliveFull
+ transmission-remote-gtk
+ vesktop
+ zathura
+ zenity
+
+ (vscode.fhsWithPackages (_: [ dotnet-combined ]))
+ dotnet-combined
+ ];
+}
diff --git a/users/rin/picom.nix b/users/rin/picom.nix
deleted file mode 100644
index 7cf8349..0000000
--- a/users/rin/picom.nix
+++ /dev/null
@@ -1,41 +0,0 @@
-{ config, ... }: {
- services.picom = {
- enable = true;
- experimentalBackends = true;
-
- blur = true;
- blurExclude = [
- (builtins.concatStringsSep " && " [
- "class_g != 'Alacritty'"
- #"class_g != 'Polybar'"
- "class_g != 'URxvt'"
- ])
- ];
- fade = true;
- fadeDelta = 5;
- fadeSteps = [ "0.05" "0.05" ];
-
- opacityRule = [
- "80:class_g = 'Alacritty' && !focused"
- ];
- vSync = true;
-
- extraOptions = ''
- glx-no-stencil = true;
- glx-copy-from-front = false;
- glx-no-rebind-pixmap = true;
- use-damage = true;
-
- blur-method = "dual_kawase";
- blur-strength = 15;
-
- detect-transient = true;
- detect-client-leader = true;
- detect-client-opacity = true;
- detect-rounded-corners = true;
- use-ewmh-active-win = true;
- mark-wmwin-focused = true;
- mark-ovredir-focused = true;
- '';
- };
-}
diff --git a/users/rin/polybar.bspwm.nix b/users/rin/polybar.bspwm.nix
deleted file mode 100644
index 27fe0cb..0000000
--- a/users/rin/polybar.bspwm.nix
+++ /dev/null
@@ -1,96 +0,0 @@
-{ config, ... }: {
- services.polybar = {
- enable = true;
- script = builtins.readFile ./scripts/polybar.sh;
- settings = {
- "bar/top" = {
- monitor = "eDP-1";
- width = "100%";
- height = 35;
- #background = "#64506c";
- background = "#00000000";
- foreground = "#fff";
-
- spacing = 2;
- padding = {
- left = 5;
- right = 5;
- bottom = 5;
- };
- override-redirect = true;
-
- font = [
- "NotoSans:style=Regular:size=11:antialias=true;2"
- "NotoSans:size=11:antialias=true;2"
- "MaterialIcons:size=17:antialias=true;6"
-
- "HanaMinA:size=9.8;1"
- "HanaMinB:size=9.8;1"
- ];
-
- modules = {
- left = "workspaces";
- center = "title";
- right = "datetime";
- };
-
- enable-ipc = true;
- scroll = {
- up = "#workspaces.prev";
- down = "#workspaces.next";
- };
- };
-
- "module/workspaces" = {
- type = "internal/bspwm";
-
- pin-workspaces = true;
- enable-click = true;
- enable-scroll = false;
- reverse-scroll = false;
-
- #ws-icon.default = "%{T3}"; # ef4a
- label = {
- monitor = "";
- focused = "%{T3}"; # ef4a
- occupied = {
- text = "%{T3}"; # e837
- foreground = "#80FFFFFF";
- };
- empty = {
- text = "%{T3}"; # ef4a
- foreground = "#80FFFFFF";
- };
- urgent = {
- text = "%{T3}"; # e837
- foreground = "#EE1012";
- };
-
- separator = {
- text = " ";
- padding = "0";
- };
- };
- };
-
- "module/title" = {
- type = "internal/xwindow";
- format = {
- text = "%{T1}