From 2a599bcff5286b9dfb28060d986a324ed83ddf5a Mon Sep 17 00:00:00 2001 From: Chris Marshall Date: Wed, 16 Sep 2020 17:53:51 -0400 Subject: [PATCH] Build standalone ioq3ded, fix asset timeout (#16) When specifying `BUILD_STANDALONE=1` for ioq3ded, the default `com_homepath`, `com_basegame`, and `com_gamename` change to foo/foobar, so this sets those explicitly to their previously default values. This can be exposed via option later to allow for custom games. This also fixes the short read timeout used by CopyAssets. --- Dockerfile | 2 +- Makefile | 2 +- cmd/q3/app/server/server.go | 11 +---------- example.yaml | 4 ++-- internal/quake/client/server.go | 4 ++-- internal/quake/server/server.go | 3 +++ internal/util/net/http/http.go | 2 +- public/index.html | 1 + public/zz_generated.static.go | 4 ++-- 9 files changed, 14 insertions(+), 19 deletions(-) diff --git a/Dockerfile b/Dockerfile index f64f5b4..bfe67ba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ FROM alpine:3.12 as quake-n-bake RUN apk add --no-cache git gcc make libc-dev RUN git clone https://github.com/ioquake/ioq3 -RUN cd /ioq3 && make BUILD_MISSIONPACK=0 BUILD_BASEGAME=0 BUILD_CLIENT=0 BUILD_SERVER=1 BUILD_GAME_SO=0 BUILD_GAME_QVM=0 BUILD_RENDERER_OPENGL2=0 +RUN cd /ioq3 && make BUILD_MISSIONPACK=0 BUILD_BASEGAME=0 BUILD_CLIENT=0 BUILD_SERVER=1 BUILD_GAME_SO=0 BUILD_GAME_QVM=0 BUILD_RENDERER_OPENGL2=0 BUILD_STANDALONE=1 RUN cp /ioq3/build/release-linux-$(uname -m)/ioq3ded.$(uname -m) /usr/local/bin/ioq3ded FROM alpine:3.12 diff --git a/Makefile b/Makefile index 0a09e29..d95efbe 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ q3: gen gen: ## Generate and embed templates @go run tools/genstatic.go public public -VERSION ?= v1.0.4 +VERSION ?= v1.0.5 IMAGE ?= docker.io/criticalstack/quake:$(VERSION) .PHONY: build diff --git a/cmd/q3/app/server/server.go b/cmd/q3/app/server/server.go index 4e96a9b..4250943 100644 --- a/cmd/q3/app/server/server.go +++ b/cmd/q3/app/server/server.go @@ -12,7 +12,6 @@ import ( quakeclient "github.com/criticalstack/quake-kube/internal/quake/client" "github.com/criticalstack/quake-kube/internal/quake/content" quakeserver "github.com/criticalstack/quake-kube/internal/quake/server" - netutil "github.com/criticalstack/quake-kube/internal/util/net" httputil "github.com/criticalstack/quake-kube/internal/util/net/http" "github.com/criticalstack/quake-kube/public" ) @@ -33,14 +32,6 @@ func NewCommand() *cobra.Command { Short: "q3 server", SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { - if opts.ClientAddr == "" { - hostIPv4, err := netutil.DetectHostIPv4() - if err != nil { - return err - } - opts.ClientAddr = fmt.Sprintf("%s:8080", hostIPv4) - } - ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -94,7 +85,7 @@ func NewCommand() *cobra.Command { cmd.Flags().StringVar(&opts.ContentServer, "content-server", "http://content.quakejs.com", "content server url") cmd.Flags().BoolVar(&opts.AcceptEula, "agree-eula", false, "agree to the Quake 3 demo EULA") cmd.Flags().StringVar(&opts.AssetsDir, "assets-dir", "assets", "location for game files") - cmd.Flags().StringVar(&opts.ClientAddr, "client-addr", "", "client address :") + cmd.Flags().StringVar(&opts.ClientAddr, "client-addr", "0.0.0.0:8080", "client address :") cmd.Flags().StringVar(&opts.ServerAddr, "server-addr", "0.0.0.0:27960", "dedicated server :") cmd.Flags().DurationVar(&opts.WatchInterval, "watch-interval", 15*time.Second, "dedicated server :") return cmd diff --git a/example.yaml b/example.yaml index 4cd73f7..89d6991 100644 --- a/example.yaml +++ b/example.yaml @@ -22,7 +22,7 @@ spec: - --config=/config/config.yaml - --content-server=http://localhost:9090 - --agree-eula - image: docker.io/criticalstack/quake:v1.0.4 + image: docker.io/criticalstack/quake:v1.0.5 name: server ports: - containerPort: 8080 @@ -40,7 +40,7 @@ spec: - q3 - content - --seed-content-url=http://content.quakejs.com - image: docker.io/criticalstack/quake:v1.0.4 + image: docker.io/criticalstack/quake:v1.0.5 name: content-server ports: - containerPort: 9090 diff --git a/internal/quake/client/server.go b/internal/quake/client/server.go index 8e2e88a..c246166 100644 --- a/internal/quake/client/server.go +++ b/internal/quake/client/server.go @@ -23,8 +23,8 @@ func (s *Server) Serve(l net.Listener) error { s := &http.Server{ Addr: s.Addr, Handler: s.Handler, - ReadTimeout: 10 * time.Second, - WriteTimeout: 10 * time.Second, + ReadTimeout: 5 * time.Minute, + WriteTimeout: 5 * time.Minute, MaxHeaderBytes: 1 << 20, } if err := s.Serve(httpL); err != cmux.ErrListenerClosed { diff --git a/internal/quake/server/server.go b/internal/quake/server/server.go index 8c42b06..cf4cc58 100644 --- a/internal/quake/server/server.go +++ b/internal/quake/server/server.go @@ -58,6 +58,9 @@ func (s *Server) Start(ctx context.Context) error { "+set", "dedicated", "1", "+set", "net_ip", host, "+set", "net_port", port, + "+set", "com_homepath", s.Dir, + "+set", "com_basegame", "baseq3", + "+set", "com_gamename", "Quake3Arena", "+exec", "server.cfg", } cmd := exec.CommandContext(ctx, "ioq3ded", args...) diff --git a/internal/util/net/http/http.go b/internal/util/net/http/http.go index 7fb10da..c79984c 100644 --- a/internal/util/net/http/http.go +++ b/internal/util/net/http/http.go @@ -10,7 +10,7 @@ import ( func GetBody(url string) ([]byte, error) { client := http.Client{ - Timeout: 30 * time.Second, + Timeout: 5 * time.Minute, } resp, err := client.Get(url) if err != nil { diff --git a/public/index.html b/public/index.html index 01b4e9e..e15dbf5 100644 --- a/public/index.html +++ b/public/index.html @@ -138,6 +138,7 @@ if (!host.includes(":")) { host = host + ":80" } var args = ['+set', 'fs_cdn', host, '+connect', host]; args.push.apply(args, ['+set', 'cl_allowDownload', '1']) + args.push.apply(args, ['+set', 'cl_timeout', '15']) args.push.apply(args, ['+name', localStorage.playerName]) args.push.apply(args, getQueryCommands()); var inputPassword = document.getElementById("password"); diff --git a/public/zz_generated.static.go b/public/zz_generated.static.go index 7bb0249..4f323a0 100644 --- a/public/zz_generated.static.go +++ b/public/zz_generated.static.go @@ -217,9 +217,9 @@ var Files = func() http.FileSystem { "/index.html": &vfsgen۰CompressedFileInfo{ name: "index.html", modTime: time.Time{}, - uncompressedSize: 6052, + uncompressedSize: 6116, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x58\x6d\x6f\xdb\x38\x12\xfe\xbe\xbf\x62\xaa\xa2\x95\x8c\xc4\x92\xed\xbc\xb5\xae\x15\xe0\x2e\xdb\xc5\x76\xd1\xeb\x66\x2f\xbd\x3b\x1c\x02\xdf\x82\x16\xc7\x16\x1b\x8a\x54\x49\xda\x56\x92\xcd\x7f\x3f\x50\x94\x6d\x49\x76\x9c\xa4\xf9\x12\x71\xe6\x99\x67\x86\xc3\x21\x39\xf4\xfd\x3d\xc5\x29\x13\x08\x1e\x13\x14\x0b\xef\xe1\x61\xf4\xea\xe7\xdf\x2f\xbe\xfe\xf7\xf2\x23\xa4\x26\xe3\xe7\x3f\x8d\xdc\x3f\x80\x51\x8a\x84\xda\x0f\x80\x91\x61\x86\xe3\xf9\x1f\x73\x72\x83\xbf\x5d\xc1\x67\x99\x10\x3e\x8a\x9c\xd0\x01\x38\x13\x37\xa0\x90\xc7\x9e\x36\xb7\x1c\x75\x8a\x68\x3c\x48\x15\x4e\x63\x6f\x46\x32\x0c\x13\xad\xbd\xf3\x51\x64\x71\x95\x89\x4e\x14\xcb\x0d\x98\xdb\x1c\x63\xcf\x60\x61\xa2\x6f\x64\x41\x9c\xd4\x03\xad\x92\xd8\x63\xf2\xbb\x75\x79\x14\x7e\x2b\x8d\x9d\x6e\xcb\x23\xc9\x73\x8e\x5d\x23\xe7\x49\xda\x65\x89\x14\x1e\x68\x76\x87\x3a\xf6\x4e\xce\x8a\x93\xb3\x55\x14\x11\xcb\xc8\x0c\x75\xe4\xd0\x16\xd7\x2d\xf5\x61\x2e\x66\xde\xf3\x39\x4f\x7b\xc5\x69\x6f\x0f\x67\xa9\x7f\x21\xe7\xd9\xa0\x38\x1b\xec\xe1\x2c\xf5\x2f\xe5\x3c\x2d\xce\x4e\xf7\x71\x5a\xfd\x0b\x39\xfb\xfd\xe3\xa2\xdf\x3f\xde\xc3\x5a\x21\x5e\xca\x3b\xe8\x15\xfd\xc1\xbe\xac\x56\x88\x97\xf2\x1e\x1f\x17\xfd\xe3\xbd\xf1\x3a\xc4\x4b\x79\x4f\x06\x45\xff\x64\xdf\x8a\x55\x88\x97\xf2\xbe\xeb\x15\xfd\x77\x7b\xf3\xe0\x10\xbb\x79\x1d\x97\xdb\x4f\xa5\x69\x64\x61\x6b\xf2\xf7\x83\xa2\xff\x7e\xe0\x41\x9b\x5d\x50\x25\x19\xad\xf8\x1d\xe8\x47\xf8\x8f\x06\xc5\xd1\x56\x4a\xa6\x64\x51\xf2\x96\xca\x1f\x61\x7d\x7f\x5a\xbc\xdf\x2a\xe3\x15\x6b\xa9\xfc\xa1\x5c\x9c\x16\xfd\x47\x59\x4b\xe5\x6e\xd6\x8c\x08\x36\x45\xbd\x3e\xd9\xa2\x95\x20\xfc\xa6\xa5\x58\xe1\x33\x34\x04\x04\xc9\x30\xf6\x32\x6d\x17\x8f\x25\xc4\x30\x29\xba\x5f\x19\xc7\x0b\xc9\xa5\xf2\x20\x91\xc2\xa0\x30\xb1\xf7\x7a\x5a\xfe\x3d\xcb\xf6\x93\x0d\xb4\x66\xbb\x8a\x3c\xd3\x8f\x56\x73\x8d\xcf\xa4\x98\x61\x37\xd9\xef\x7f\xef\xa1\xec\x30\x00\xd3\xb9\x48\x6c\x50\x30\x43\xf3\xc7\x1c\xd5\xed\x85\xcc\x32\x22\xa8\x0e\x3a\x70\x5f\x61\x00\x16\x44\x81\x46\xa2\x92\x14\x62\x88\x82\xeb\xff\xbd\x8d\xc7\x07\x9d\x68\xf6\xa1\x81\xf8\x6e\xed\x01\x62\x58\x32\x41\xe5\x32\xe4\xd2\x4d\x38\x74\xa6\xa1\x9e\x4f\xb4\x51\x4c\xcc\x82\x7e\xe7\xc3\x4f\x0d\x53\xa2\x66\x1a\x62\xb8\x1e\xb7\xe4\x19\x31\x49\xba\xf1\xb2\x4c\x19\x47\x08\x4a\x29\xc4\x55\x48\x21\x16\x98\x04\xa5\xf3\x4e\x3d\x68\xc7\xb0\x20\x1c\x62\xa0\x98\x48\x8a\xff\xfa\xe7\xa7\x0b\x99\xe5\x52\xa0\x30\x8e\xe4\xba\x3f\xee\x7c\x68\x58\x58\xf4\x82\xf0\x50\xe7\x9c\x99\xc0\x07\xbf\xad\xbf\xee\x8d\x21\x06\xff\xc0\x87\x83\x6a\x58\x07\xd8\x89\x84\xf9\x5c\xa7\xa1\x5d\xf1\xdb\xc0\x8e\x0f\x2d\xae\x46\xf3\xb0\x99\xa3\x42\x33\x57\xa2\xb4\x5a\xe9\xd7\xda\x2a\x8b\x52\x70\x49\x28\xc4\x9b\xa5\x6a\x2c\xcd\x5a\xaa\xd0\xee\x88\x7f\x33\x5c\xe6\x52\x99\xa0\x99\x09\x36\x85\xe0\x15\x93\xdf\x8f\xc2\x84\x88\x05\xd1\x4d\x2d\x40\x14\x01\x9b\x09\xa9\xd0\x22\x4d\x8a\xe0\x60\x90\x12\x2d\x7c\x03\xb7\x68\x80\x09\x66\x18\xe1\xec\x0e\x69\xc3\xd4\x4d\xa1\x9e\x83\x87\x96\xe3\x80\xca\x64\x9e\xa1\x30\xd7\xfe\x12\x27\x37\xcc\xfc\x32\xe7\xfc\x2a\x51\x88\xe2\x23\x47\xab\xf0\xc7\xf0\xd7\x5f\xb0\x0b\xa6\xb7\x60\x0d\xe7\xf6\x6f\x63\x96\xc9\xbb\x27\xa9\x2b\xcc\x8b\x78\xa7\x4f\x91\x4e\xb7\x19\x3b\x8f\xa7\xd8\xad\x14\xe0\x02\x85\xd1\x40\xe7\x08\x46\xc2\x4c\x32\x31\x83\x0d\xd1\x4b\x72\x6c\xd7\x55\xa3\xb9\x28\xd7\xec\x8a\xdd\x61\x50\x8a\x16\x55\x2d\x84\x72\x3a\xd5\x68\xfe\xc3\xa8\x49\x0f\x61\x97\xea\x57\x64\xb3\xd4\xec\x2e\xd1\x06\xde\x6e\xa5\x6a\xd6\xe1\x0c\x4d\x35\xdb\xbf\xdf\x7e\xa2\x81\xbf\xc2\x74\xa7\x8a\x64\x58\xdf\x37\x25\x05\x3a\xec\xa5\x64\xc2\xa0\xfa\x2c\x93\x1b\x88\xc1\xa8\x39\xb6\x71\x05\x33\xbf\x12\x41\x39\xaa\x46\xd1\xa3\x52\xdb\x35\xbd\x25\x74\x9b\x7e\x2a\x55\x56\x0f\x35\x51\x48\x0c\x56\xd1\x06\xbe\x55\x37\xf7\x35\x94\x26\x36\x89\x7f\x33\x46\xb1\xc9\xdc\x60\xe0\x67\x68\x52\x49\xfd\x43\xf0\x2f\x7f\xbf\xfa\xfa\x0c\x03\x52\x86\x6a\x0d\x22\xbf\x7e\xc2\xad\xc2\x4a\x19\xa5\x28\x7e\x61\xc8\xe9\x9e\xe8\x98\xc8\xe7\xa6\xed\xad\x66\xda\x72\x6a\xcf\x77\xeb\xd2\x21\x9e\x6f\x67\x6f\x12\x6b\x87\x4a\x49\xf5\x7c\xb3\x05\xe1\x73\x6b\x67\x33\xbf\x23\x21\x24\xcf\x51\xd0\x8b\x94\x71\x1a\xd4\x48\xda\xd9\x58\xcf\x7d\x22\xe9\x6d\xc3\xc8\xb2\xec\xcc\xf4\x7c\x92\x31\x13\xb4\x54\xbb\x36\x46\x6d\xd0\xbe\x88\xec\x55\x6f\x0f\xef\xc8\xdf\x59\xea\x15\x9c\x50\xfa\xd1\xee\xcd\xcf\x4c\x1b\x14\xa8\x02\xdf\xed\x58\xff\xb0\x75\xc8\xae\x83\x79\x70\x1f\xad\x67\x4d\xf9\x7c\x5a\x5d\xb4\x61\x82\xb6\xee\x91\xd6\xca\x35\x97\x9a\xd9\xb8\x86\x30\x65\x05\xd2\x4d\x4c\x46\xe6\x43\x38\xed\xbd\xd9\x48\x38\x4e\xcd\x10\x4e\xea\x22\xa3\x88\xd0\x36\x37\x43\xf7\xc9\x89\xc1\xa0\x7b\xd2\x7b\x73\x08\xdd\xd3\xde\x9b\xce\x07\x58\x43\xef\xba\xe5\x13\x71\x08\xfd\xcd\x2d\x53\x85\x55\x6e\x95\xb2\xe4\xae\xcb\x4e\xc1\x36\x0a\xe3\x43\x70\x83\x9c\x68\xbd\x94\x8a\x8e\x6b\x41\x67\x44\xcd\x98\x18\xc2\xbb\xbc\x80\xde\x26\x1a\xca\x74\xce\xc9\xed\x10\x98\xe0\x4c\x60\x77\xc2\x65\x72\xb3\x51\x4f\xa4\xa2\xa8\x86\xd0\xcf\x0b\xd0\x92\x33\x0a\xaf\x93\x24\xa9\xeb\x8b\xae\x4e\x09\x95\x4b\xcb\xa0\xd1\x40\xaf\xc4\x1e\xe5\x05\xbc\xa6\xb4\x96\x9b\xae\xbb\x1c\xba\xa5\x05\xbb\x63\x62\x36\xac\xd8\xad\xa8\x86\xcb\xe4\xdd\x93\xa0\xa7\xf4\x39\xa1\x94\x89\x59\xd7\xa5\x7f\xd0\xcb\x77\xe8\x94\x3d\x3b\x1f\x53\x96\x2b\xd9\x3f\xdd\xa5\x9a\x48\x63\x64\xd6\xd4\xae\x97\x65\x32\x37\x46\x8a\x5a\xda\x27\x24\xb9\x99\x29\x39\x17\xd4\xf5\x7d\x43\x78\x3d\xc5\xfe\xa0\x8f\xdb\x39\x16\x52\xd4\xa4\x15\x7a\x99\x32\x83\x5b\x41\x38\xef\x70\x34\xa8\x07\x68\x4b\xa0\x4b\x38\x9b\x89\x21\xb8\xaa\x6d\xe9\x6c\x37\xa5\x88\xab\xdc\xa6\xb3\x27\xaa\x60\x2a\x85\xb1\xf9\xc6\x5d\xb3\x1e\x45\xeb\x0d\x33\x8a\x56\x3f\x58\x8c\xec\x01\x51\xed\x27\xca\x16\xc0\xa8\x6d\xdd\x99\x58\x37\xb0\x6b\xe9\x64\xe6\x9d\x8f\x22\xca\x16\x0d\x4d\xc2\x89\xd6\xb1\xb7\xda\x7c\x6b\x33\x80\x51\x59\xf9\x95\xde\x7e\xd7\x74\x00\xa3\x72\x4b\xd4\x9a\x67\xaf\x74\x62\x27\x87\xea\x0b\xc9\xb0\x81\xbe\xbf\x87\x25\x33\x29\x84\x5f\x10\xa9\xbe\x24\x5a\xc3\xc3\x43\xe3\xa0\x6a\xf0\xad\xb6\x95\x07\x39\x27\x09\xa6\x92\x53\x54\x75\x71\xe9\x6a\x35\x6a\x39\x42\x41\x9b\xe4\xa3\xaa\x56\xa4\x48\x38\x4b\x6e\x62\xef\x9b\x64\x22\xe8\xac\x9e\x4c\xee\xe0\xf4\x56\x33\x75\x60\xef\xfc\x37\xc9\xc4\x28\x72\xa3\x5a\x52\x22\x9b\x89\xda\xf8\x59\x8f\x88\xb2\xa0\x36\x33\x81\x18\xbc\x32\xdf\xe0\xd2\x55\x3e\x5a\xbc\xd6\xcd\x6d\xcf\x64\x7e\x65\xa4\x22\x33\x0c\x37\x69\x6d\xdf\xe6\x4d\xda\x47\x8c\x1e\xe9\x8b\x1e\xeb\x54\xea\xab\xd8\x09\x9b\x1e\x6a\xa3\x1a\xd3\xba\x0b\x71\xa9\xdd\x6e\x38\xca\xd5\xbd\x5c\xd3\xee\x69\x93\x1a\xce\x9b\x97\x99\x4d\x4b\x8b\x28\x2c\xaf\x5b\x78\x15\x83\xe7\xb5\x53\x63\x6f\x85\x7a\x3e\x34\x9a\x4f\x06\xb3\x86\x87\xc3\x76\x64\x8e\xb0\xe5\xb8\x59\xaa\xa9\xd4\x8d\x3e\x6f\x73\x7b\x4a\x6d\xb6\x02\x7e\x65\xa5\x21\x13\x09\x9f\x53\xd4\x81\x37\xf4\x6c\xe7\xbb\x22\x29\xff\x1d\x80\x37\x7c\xd7\xf3\x5a\x6e\xea\xcf\x3e\xff\x40\xa3\xb1\xcd\xc8\x54\xff\x99\x50\xdb\x41\x59\xc3\x43\xf0\x0f\x12\x29\x04\x26\xa6\x92\x8c\x9b\x71\xef\x7e\x6c\x6d\xd8\x12\xfe\x27\xe1\x5c\x2e\x7f\x96\xcb\xf2\x11\x65\x65\x7d\x7f\xdc\x79\x1e\x49\xd5\x20\x3d\x52\x73\xcf\x62\xd9\x7e\x54\xb7\x32\xbf\xa9\x9d\x6a\xb7\xef\xad\x9c\xd5\x89\xf0\x68\xdd\xac\x48\xde\xbe\x6d\xb2\x3e\x51\x46\x4f\xe5\x71\xe5\xd8\x3f\xdc\x45\x3b\xde\x5b\x4d\x76\x86\x55\xeb\xbf\x6f\x6e\xe5\x99\xde\x22\xaa\xcc\xc2\x9c\x28\x14\xe6\x8b\xa4\x18\x2a\xcc\xe4\x02\x5d\xa7\x58\xa9\xdb\xc9\x70\x8f\x5c\xce\xff\x41\x98\x28\x67\xd2\xd9\xfd\x6e\x6a\x36\x6b\x76\xbc\xbe\x3b\x6a\x9f\xcd\x9b\xa7\xf9\xc4\xa9\xdd\x37\xa3\xc8\xdd\x53\xa3\xc8\xfd\xe4\x7e\x7f\x8f\x82\x3e\x3c\xfc\xf4\xff\x00\x00\x00\xff\xff\xc0\x6b\x75\xb9\xa4\x17\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x58\xe1\x6e\xdb\x38\x12\xfe\xbf\x4f\x31\x55\xd1\x5a\x46\x62\xc9\x76\x9a\xb4\x75\xad\x02\x77\xd9\x2e\xb6\x8b\x5e\xb7\x7b\xe9\xdd\xe1\x10\xe4\x16\xb4\x38\xb6\xd8\x50\xa4\x4a\xd2\xb6\x92\x6c\xde\xfd\x40\x52\xb6\x25\xd9\x71\xe2\xe6\x4f\x44\xce\x37\xdf\x0c\x87\x43\xce\xd0\x77\x77\x14\xa7\x4c\x20\x04\x4c\x50\x2c\x83\xfb\xfb\xf1\xb3\x9f\x7f\x3f\xff\xfa\xdf\x2f\x1f\x20\x33\x39\x7f\xff\xd3\xd8\xff\x03\x18\x67\x48\xa8\xfd\x00\x18\x1b\x66\x38\xbe\xff\x63\x4e\xae\xf1\xb7\x0b\xf8\x24\x53\xc2\xc7\xb1\x9f\xf4\x00\xce\xc4\x35\x28\xe4\x49\xa0\xcd\x0d\x47\x9d\x21\x9a\x00\x32\x85\xd3\x24\x98\x91\x1c\xa3\x54\xeb\xe0\xfd\x38\xb6\xb8\x4a\x45\xa7\x8a\x15\x06\xcc\x4d\x81\x49\x60\xb0\x34\xf1\x37\xb2\x20\x7e\x36\x00\xad\xd2\x24\x60\xf2\xbb\x35\x79\x12\x7d\x73\xca\x5e\xb6\x65\x91\x14\x05\xc7\x9e\x91\xf3\x34\xeb\xb1\x54\x8a\x00\x34\xbb\x45\x9d\x04\xa7\xaf\xcb\xd3\xd7\x2b\x2f\x62\x96\x93\x19\xea\xd8\xa3\x2d\xae\xe7\xe4\x51\x21\x66\xc1\xd3\x39\xcf\xfa\xe5\x59\x7f\x0f\xa7\x93\x1f\xc8\xf9\x7a\x58\xbe\x1e\xee\xe1\x74\xf2\x43\x39\xcf\xca\xd7\x67\xfb\x38\xad\xfc\x40\xce\xc1\xe0\x55\x39\x18\xbc\xda\xc3\x5a\x21\x0e\xe5\x1d\xf6\xcb\xc1\x70\x5f\x54\x2b\xc4\xa1\xbc\xaf\x5e\x95\x83\x57\x7b\xfd\xf5\x88\x43\x79\x4f\x87\xe5\xe0\x74\xdf\x8e\x55\x88\x43\x79\xdf\xf4\xcb\xc1\x9b\xbd\x71\xf0\x88\xdd\xbc\x9e\xcb\x9f\x27\xa7\x1a\x5b\xd8\x9a\xfc\xed\xb0\x1c\xbc\x1d\x06\xd0\x66\x17\x54\x49\x46\x2b\x7e\x0f\xfa\x11\xfe\x93\x61\x79\xb2\x15\x92\x29\x59\x38\x5e\x27\xfc\x11\xd6\xb7\x67\xe5\xdb\xad\x34\x5e\xb1\x3a\xe1\x0f\xc5\xe2\xac\x1c\x3c\xc8\xea\x84\xbb\x59\x73\x22\xd8\x14\xf5\xfa\x66\x8b\x57\x13\xd1\x37\x2d\xc5\x0a\x9f\xa3\x21\x20\x48\x8e\x49\x90\x6b\xbb\x79\x2c\x25\x86\x49\xd1\xfb\xca\x38\x9e\x4b\x2e\x55\x00\xa9\x14\x06\x85\x49\x82\xe7\x53\xf7\xf7\x24\xdd\x8f\xd6\xd1\x9a\xee\xca\xf3\x5c\x3f\x98\xcd\x35\x3e\x93\x61\x8e\xbd\x74\xbf\xfd\xbd\x97\xb2\xc7\x00\x4c\xe7\x22\xb5\x4e\xc1\x0c\xcd\x1f\x73\x54\x37\xe7\x32\xcf\x89\xa0\x3a\xec\xc2\x5d\x85\x01\x58\x10\x05\x1a\x89\x4a\x33\x48\x20\x0e\x2f\xff\xf7\x32\xb9\x3a\xea\xc6\xb3\x77\x0d\xc4\x77\xab\x0f\x90\xc0\x92\x09\x2a\x97\x11\x97\x7e\xc1\x91\x57\x8d\xf4\x7c\xa2\x8d\x62\x62\x16\x0e\xba\xef\x7e\x6a\xa8\x12\x35\xd3\x90\xc0\xe5\x55\x6b\x3e\x27\x26\xcd\x36\x56\x96\x19\xe3\x08\xa1\x9b\x85\xa4\x72\x29\xc2\x12\xd3\xd0\x19\xef\xd6\x9d\xf6\x0c\x0b\xc2\x21\x01\x8a\xa9\xa4\xf8\xaf\x7f\x7e\x3c\x97\x79\x21\x05\x0a\xe3\x49\x2e\x07\x57\xdd\x77\x0d\x0d\x8b\x5e\x10\x1e\xe9\x82\x33\x13\x76\xa0\xd3\x96\x5f\xf6\xaf\x20\x81\xce\x51\x07\x8e\xaa\x61\x1d\x60\x17\x12\x15\x73\x9d\x45\x76\xc7\x6f\x42\x3b\x3e\xb6\xb8\x1a\xcd\xfd\x66\x8d\x0a\xcd\x5c\x09\xa7\xb5\x92\xaf\xa5\x55\x14\xa5\xe0\x92\x50\x48\x36\x5b\xd5\xd8\x9a\xf5\xac\x42\x7b\x22\xfe\xcd\x70\x59\x48\x65\xc2\x66\x24\xd8\x14\xc2\x67\x4c\x7e\x3f\x89\x52\x22\x16\x44\x37\xa5\x00\x71\x0c\x6c\x26\xa4\x42\x8b\x34\x19\x82\x87\x41\x46\xb4\xe8\x18\xb8\x41\x03\x4c\x30\xc3\x08\x67\xb7\x48\x1b\xaa\x7e\x09\xf5\x18\xdc\xb7\x0c\x87\x54\xa6\xf3\x1c\x85\xb9\xec\x2c\x71\x72\xcd\xcc\x2f\x73\xce\x2f\x52\x85\x28\x3e\x70\xb4\x82\xce\x15\xfc\xf5\x17\xec\x82\xe9\x2d\x58\xc3\xb8\xfd\xdb\xa8\xe5\xf2\xf6\x51\xea\x0a\x73\x10\xef\xf4\x31\xd2\xe9\x36\x63\xf7\xe1\x10\xfb\x9d\x02\x5c\xa0\x30\x1a\xe8\x1c\xc1\x48\x98\x49\x26\x66\xb0\x21\x3a\x24\xc6\x76\x5f\x35\x9a\x73\xb7\x67\x17\xec\x16\x43\x37\xb5\xa8\x72\x21\x92\xd3\xa9\x46\xf3\x1f\x46\x4d\x76\x0c\xbb\x44\xbf\x22\x9b\x65\x66\x77\x8a\x36\xf0\xf6\x28\x55\xab\x8e\x66\x68\xaa\xd5\xfe\xfd\xe6\x23\x0d\x3b\x2b\x4c\x6f\xaa\x48\x8e\xf5\x73\xe3\x28\xd0\x63\xbf\x48\x26\x0c\xaa\x4f\x32\xbd\x86\x04\x8c\x9a\x63\x1b\x57\x32\xf3\x2b\x11\x94\xa3\x6a\x24\x3d\x2a\xb5\x9d\xd3\x5b\x93\xfe\xd0\x4f\xa5\xca\xeb\xae\xa6\x0a\x89\xc1\xca\xdb\xb0\x63\xc5\xcd\x73\x0d\x4e\xc5\x06\xf1\x6f\xc6\x28\x36\x99\x1b\x0c\x3b\x39\x9a\x4c\xd2\xce\x31\x74\xbe\xfc\x7e\xf1\xf5\x09\x0a\xc4\xb9\x6a\x15\xe2\x4e\xfd\x86\x5b\xb9\x95\x31\x4a\x51\xfc\xc2\x90\xd3\x3d\xde\x31\x51\xcc\x4d\xdb\x5a\x4d\xb5\x65\xd4\xde\xef\xd6\xa4\x47\x3c\x5d\xcf\x56\x12\xab\x87\x4a\x49\xf5\x74\xb5\x05\xe1\x73\xab\x67\x23\xbf\x23\x20\xa4\x28\x50\xd0\xf3\x8c\x71\x1a\xd6\x48\xda\xd1\x58\xaf\x7d\x22\xe9\x4d\x43\xc9\xb2\xec\x8c\xf4\x7c\x92\x33\x13\xb6\x44\xbb\x0e\x46\x6d\xd0\x2e\x44\xb6\xd4\xdb\xcb\x3b\xee\xec\x4c\xf5\x0a\x4e\x28\xfd\x60\xcf\xe6\x27\xa6\x0d\x0a\x54\x61\xc7\x9f\xd8\xce\x71\xeb\x92\x5d\x3b\x73\xef\x3f\x5a\xcf\x1a\xf7\x7c\x5a\x15\xda\x28\x45\x9b\xf7\x48\x6b\xe9\x5a\x48\xcd\xac\x5f\x23\x98\xb2\x12\xe9\xc6\x27\x23\x8b\x11\x9c\xf5\x5f\x6c\x66\x38\x4e\xcd\x08\x4e\xeb\x53\x46\x11\xa1\x6d\x6c\x46\xfe\x93\x13\x83\x61\xef\xb4\xff\xe2\x18\x7a\x67\xfd\x17\xdd\x77\xb0\x86\xde\xf6\xdc\x13\x71\x04\x83\x4d\x95\xa9\xdc\x72\x47\xc5\xa5\xdc\xa5\xeb\x14\x6c\xa3\x70\x75\x0c\x7e\x50\x10\xad\x97\x52\xd1\xab\x9a\xd3\x39\x51\x33\x26\x46\xf0\xa6\x28\xa1\xbf\xf1\x86\x32\x5d\x70\x72\x33\x02\x26\x38\x13\xd8\x9b\x70\x99\x5e\x6f\xc4\x13\xa9\x28\xaa\x11\x0c\x8a\x12\xb4\xe4\x8c\xc2\xf3\x34\x4d\xeb\xf2\xb2\xa7\x33\x42\xe5\xd2\x32\x68\x34\xd0\x77\xd8\x93\xa2\x84\xe7\x94\xd6\x62\xd3\xf3\xc5\xa1\xe7\x34\xd8\x2d\x13\xb3\x51\xc5\x6e\xa7\x6a\xb8\x5c\xde\x3e\x0a\x7a\x4c\x5e\x10\x4a\x99\x98\xf5\x7c\xf8\x87\xfd\x62\x87\x4c\xd9\xbb\xf3\x21\xa1\xdb\xc9\xc1\xd9\x2e\xd1\x44\x1a\x23\xf3\xa6\x74\xbd\x2d\x93\xb9\x31\x52\xd4\xc2\x3e\x21\xe9\xf5\x4c\xc9\xb9\xa0\xbe\xef\x1b\xc1\xf3\x29\x0e\x86\x03\xdc\x8e\xb1\x90\xa2\x36\x5b\xa1\x97\x19\x33\xb8\xe5\x84\xb7\x0e\x27\xc3\xba\x83\x36\x05\x7a\x84\xb3\x99\x18\x81\xcf\xda\x96\xcc\x76\x53\x8a\xf8\xcc\x6d\x1a\x7b\x24\x0b\xa6\x52\x18\x1b\x6f\xdc\xb5\xea\x71\xbc\x3e\x30\xe3\x78\xf5\x83\xc5\xd8\x5e\x10\xd5\x79\xa2\x6c\x01\x8c\xda\xd6\x9d\x89\x75\x03\xbb\x9e\x9d\xcc\x82\xf7\xe3\x98\xb2\x45\x43\x92\x72\xa2\x75\x12\xac\x0e\xdf\x5a\x0d\x60\xec\x32\xbf\x92\xdb\xef\x9a\x0c\x60\xec\x8e\x44\xad\x79\x0e\x9c\x11\xbb\x38\x54\x9f\x49\x8e\x0d\xf4\xdd\x1d\x2c\x99\xc9\x20\xfa\x8c\x48\xf5\x17\xa2\x35\xdc\xdf\x37\x2e\xaa\x06\xdf\xea\x58\x05\x50\x70\x92\x62\x26\x39\x45\x55\x9f\x76\xa6\x56\xa3\x96\x21\x14\xb4\x49\x3e\xae\x72\x45\x8a\x94\xb3\xf4\x3a\x09\xbe\x49\x26\xc2\xee\xea\xc9\xe4\x2f\xce\x60\xb5\x52\x0f\x0e\xde\xff\x26\x99\x18\xc7\x7e\x54\x0b\x4a\x6c\x23\x51\x1b\x3f\xe9\x11\xe1\x12\x6a\xb3\x12\x48\x20\x70\xf1\x06\x1f\x2e\xf7\x68\x09\x5a\x95\xdb\xde\xc9\xfc\xc2\x48\x45\x66\x18\x6d\xc2\xda\xae\xe6\x4d\xda\x07\x94\x1e\xe8\x8b\x1e\xea\x54\xea\xbb\xd8\x8d\x9a\x16\x6a\xa3\x1a\xd3\xba\x0b\xf1\xa1\xdd\x6e\x38\xdc\xee\x7e\x59\xd3\xee\x69\x93\x1a\xc6\x9b\xc5\xcc\x86\xa5\x45\x14\xb9\x72\x0b\xcf\x12\x08\x82\x76\x68\x6c\x55\xa8\xc7\x43\xa3\xf9\x68\x30\x6f\x58\x38\x6e\x7b\xe6\x09\x5b\x86\x9b\xa9\x9a\x49\xdd\xe8\xf3\x36\xd5\x53\x6a\xb3\xe5\xf0\x33\x3b\x1b\x31\x91\xf2\x39\x45\x1d\x06\xa3\xc0\x76\xbe\x2b\x12\xf7\xef\x08\x82\xd1\x9b\x7e\xd0\x32\x53\x7f\xf6\x75\x8e\x34\x1a\xdb\x8c\x4c\xf5\x9f\x29\xb5\x1d\x94\x55\x3c\x86\xce\x51\x2a\x85\xc0\xd4\x54\x33\x57\x4d\xbf\x77\x3f\xb6\x36\x6c\x29\xff\x93\x70\x2e\x97\x3f\xcb\xa5\x7b\x44\xd9\xb9\x41\xe7\xaa\x7b\x28\x89\x61\x39\xca\xb9\x1b\x0d\x4e\x9f\xac\x5f\x35\x58\x0f\xe4\xec\x93\x58\xb6\x1f\xe5\xad\x9d\xdb\xe4\x5e\x75\x5b\xec\xcd\xbc\xd5\x8d\xf2\x60\xde\xad\x48\x5e\xbe\x6c\xb2\x3e\x92\x86\x8f\x85\x70\x65\xb8\x73\xbc\x8b\xf6\x6a\x6f\x36\xda\x15\x56\x4f\x87\x7d\x6b\x73\x35\xa1\x45\x54\xa9\x45\x05\x51\x28\xcc\x67\x49\x31\x52\x98\xcb\x05\xfa\x4e\xb3\x12\xb7\x83\xe1\x1f\xc9\x9c\xff\x83\x30\xe1\x56\xd2\xdd\xfd\xee\x6a\x36\x7b\x76\xbc\xae\x3d\xb5\xcf\x66\xe5\x6a\x3e\x91\x6a\xf5\x6a\x1c\xfb\x3a\x37\x8e\xfd\x4f\xf6\x77\x77\x28\xe8\xfd\xfd\x4f\xff\x0f\x00\x00\xff\xff\x77\x93\xda\x48\xe4\x17\x00\x00"), }, "/ioquake3.js": &vfsgen۰CompressedFileInfo{ name: "ioquake3.js",