mirror of
				https://github.com/ggml-org/llama.cpp.git
				synced 2025-11-04 09:32:00 +00:00 
			
		
		
		
	Merge branch 'master' into HEAD
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							@@ -111,6 +111,7 @@ jobs:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      - name: Dependencies
 | 
					      - name: Dependencies
 | 
				
			||||||
        id: depends
 | 
					        id: depends
 | 
				
			||||||
 | 
					        continue-on-error: true
 | 
				
			||||||
        run: |
 | 
					        run: |
 | 
				
			||||||
          brew update
 | 
					          brew update
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -129,6 +130,7 @@ jobs:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      - name: Dependencies
 | 
					      - name: Dependencies
 | 
				
			||||||
        id: depends
 | 
					        id: depends
 | 
				
			||||||
 | 
					        continue-on-error: true
 | 
				
			||||||
        run: |
 | 
					        run: |
 | 
				
			||||||
          brew update
 | 
					          brew update
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,7 +79,7 @@ option(LLAMA_QKK_64                          "llama: use super-block size of 64
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
option(LLAMA_BUILD_TESTS                "llama: build tests"    ${LLAMA_STANDALONE})
 | 
					option(LLAMA_BUILD_TESTS                "llama: build tests"    ${LLAMA_STANDALONE})
 | 
				
			||||||
option(LLAMA_BUILD_EXAMPLES             "llama: build examples" ${LLAMA_STANDALONE})
 | 
					option(LLAMA_BUILD_EXAMPLES             "llama: build examples" ${LLAMA_STANDALONE})
 | 
				
			||||||
option(LLAMA_BUILD_SERVER               "llama: build server example"                           OFF)
 | 
					option(LLAMA_BUILD_SERVER               "llama: build server example"                           ON)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Build info header
 | 
					# Build info header
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,11 +1,5 @@
 | 
				
			|||||||
# Define the default target now so that it is always the first target
 | 
					# Define the default target now so that it is always the first target
 | 
				
			||||||
BUILD_TARGETS = main quantize quantize-stats perplexity embedding vdot train-text-from-scratch simple libembdinput.so embd-input-test
 | 
					BUILD_TARGETS = main quantize quantize-stats perplexity embedding vdot train-text-from-scratch simple server libembdinput.so embd-input-test
 | 
				
			||||||
 | 
					 | 
				
			||||||
ifdef LLAMA_BUILD_SERVER
 | 
					 | 
				
			||||||
	BUILD_TARGETS += server
 | 
					 | 
				
			||||||
	LLAMA_SERVER_VERBOSE ?= 1
 | 
					 | 
				
			||||||
server: private CXXFLAGS += -DSERVER_VERBOSE=$(LLAMA_SERVER_VERBOSE)
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
default: $(BUILD_TARGETS)
 | 
					default: $(BUILD_TARGETS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -61,6 +55,10 @@ else
 | 
				
			|||||||
	CXXFLAGS += -DNDEBUG
 | 
						CXXFLAGS += -DNDEBUG
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifdef LLAMA_SERVER_VERBOSE
 | 
				
			||||||
 | 
						CXXFLAGS += -DSERVER_VERBOSE=$(LLAMA_SERVER_VERBOSE)
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# warnings
 | 
					# warnings
 | 
				
			||||||
CFLAGS   += -Wall -Wextra -Wpedantic -Wcast-qual -Wdouble-promotion -Wshadow -Wstrict-prototypes -Wpointer-arith
 | 
					CFLAGS   += -Wall -Wextra -Wpedantic -Wcast-qual -Wdouble-promotion -Wshadow -Wstrict-prototypes -Wpointer-arith
 | 
				
			||||||
CXXFLAGS += -Wall -Wextra -Wpedantic -Wcast-qual -Wno-unused-function -Wno-multichar
 | 
					CXXFLAGS += -Wall -Wextra -Wpedantic -Wcast-qual -Wno-unused-function -Wno-multichar
 | 
				
			||||||
@@ -272,7 +270,7 @@ libllama.so: llama.o ggml.o $(OBJS)
 | 
				
			|||||||
	$(CXX) $(CXXFLAGS) -shared -fPIC -o $@ $^ $(LDFLAGS)
 | 
						$(CXX) $(CXXFLAGS) -shared -fPIC -o $@ $^ $(LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	rm -vf *.o *.so main quantize quantize-stats perplexity embedding benchmark-matmult save-load-state server vdot train-text-from-scratch embd-input-test build-info.h
 | 
						rm -vf *.o *.so main quantize quantize-stats perplexity embedding benchmark-matmult save-load-state server simple vdot train-text-from-scratch embd-input-test build-info.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Examples
 | 
					# Examples
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ struct gpt_params {
 | 
				
			|||||||
    int32_t n_gpu_layers                    = 0;   // number of layers to store in VRAM
 | 
					    int32_t n_gpu_layers                    = 0;   // number of layers to store in VRAM
 | 
				
			||||||
    int32_t main_gpu                        = 0;   // the GPU that is used for scratch and small tensors
 | 
					    int32_t main_gpu                        = 0;   // the GPU that is used for scratch and small tensors
 | 
				
			||||||
    float   tensor_split[LLAMA_MAX_DEVICES] = {0}; // how split tensors should be distributed across GPUs
 | 
					    float   tensor_split[LLAMA_MAX_DEVICES] = {0}; // how split tensors should be distributed across GPUs
 | 
				
			||||||
    bool    low_vram                        = 0;   // if true, reduce VRAM usage at the cost of performance
 | 
					    int32_t n_probs                         = 0;   // if greater than 0, output the probabilities of top n_probs tokens.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // sampling parameters
 | 
					    // sampling parameters
 | 
				
			||||||
    std::unordered_map<llama_token, float> logit_bias; // logit bias for specific tokens
 | 
					    std::unordered_map<llama_token, float> logit_bias; // logit bias for specific tokens
 | 
				
			||||||
@@ -59,6 +59,7 @@ struct gpt_params {
 | 
				
			|||||||
    std::string lora_adapter = "";  // lora adapter path
 | 
					    std::string lora_adapter = "";  // lora adapter path
 | 
				
			||||||
    std::string lora_base    = "";  // base model path for the lora adapter
 | 
					    std::string lora_base    = "";  // base model path for the lora adapter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool low_vram          = false;   // if true, reduce VRAM usage at the cost of performance
 | 
				
			||||||
    bool memory_f16        = true;  // use f16 instead of f32 for memory kv
 | 
					    bool memory_f16        = true;  // use f16 instead of f32 for memory kv
 | 
				
			||||||
    bool random_prompt     = false; // do not randomize prompt if none provided
 | 
					    bool random_prompt     = false; // do not randomize prompt if none provided
 | 
				
			||||||
    bool use_color         = false; // use color to distinguish generations and inputs
 | 
					    bool use_color         = false; // use color to distinguish generations and inputs
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -190,3 +190,19 @@ Run with bash:
 | 
				
			|||||||
```sh
 | 
					```sh
 | 
				
			||||||
bash chat.sh
 | 
					bash chat.sh
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### API like OAI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					API example using Python Flask: [api_like_OAI.py](api_like_OAI.py)
 | 
				
			||||||
 | 
					This example must be used with server.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```sh
 | 
				
			||||||
 | 
					python api_like_OAI.py
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After running the API server, you can use it in Python by setting the API base URL.
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					openai.api_base = "http://<Your api-server IP>:port"
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then you can utilize llama.cpp as an OpenAI's **chat.completion** or **text_completion** API
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										219
									
								
								examples/server/api_like_OAI.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										219
									
								
								examples/server/api_like_OAI.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,219 @@
 | 
				
			|||||||
 | 
					import argparse
 | 
				
			||||||
 | 
					from flask import Flask, jsonify, request, Response
 | 
				
			||||||
 | 
					import urllib.parse
 | 
				
			||||||
 | 
					import requests
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app = Flask(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser = argparse.ArgumentParser(description="An example of using server.cpp with a similar API to OAI. It must be used together with server.cpp.")
 | 
				
			||||||
 | 
					parser.add_argument("--chat-prompt", type=str, help="the top prompt in chat completions(default: 'A chat between a curious user and an artificial intelligence assistant. The assistant follows the given rules no matter what.\\n')", default='A chat between a curious user and an artificial intelligence assistant. The assistant follows the given rules no matter what.\\n')
 | 
				
			||||||
 | 
					parser.add_argument("--user-name", type=str, help="USER name in chat completions(default: '\\nUSER: ')", default="\\nUSER: ")
 | 
				
			||||||
 | 
					parser.add_argument("--ai-name", type=str, help="ASSISTANT name in chat completions(default: '\\nASSISTANT: ')", default="\\nASSISTANT: ")
 | 
				
			||||||
 | 
					parser.add_argument("--system-name", type=str, help="SYSTEM name in chat completions(default: '\\nASSISTANT's RULE: ')", default="\\nASSISTANT's RULE: ")
 | 
				
			||||||
 | 
					parser.add_argument("--stop", type=str, help="the end of response in chat completions(default: '</s>')", default="</s>")
 | 
				
			||||||
 | 
					parser.add_argument("--llama-api", type=str, help="Set the address of server.cpp in llama.cpp(default: http://127.0.0.1:8080)", default='http://127.0.0.1:8080')
 | 
				
			||||||
 | 
					parser.add_argument("--api-key", type=str, help="Set the api key to allow only few user(default: NULL)", default="")
 | 
				
			||||||
 | 
					parser.add_argument("--host", type=str, help="Set the ip address to listen.(default: 127.0.0.1)", default='127.0.0.1')
 | 
				
			||||||
 | 
					parser.add_argument("--port", type=int, help="Set the port to listen.(default: 8081)", default=8081)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def is_present(json, key):
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        buf = json[key]
 | 
				
			||||||
 | 
					    except KeyError:
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#convert chat to prompt
 | 
				
			||||||
 | 
					def convert_chat(messages):
 | 
				
			||||||
 | 
					    prompt = "" + args.chat_prompt.replace("\\n", "\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    system_n = args.system_name.replace("\\n", "\n")
 | 
				
			||||||
 | 
					    user_n = args.user_name.replace("\\n", "\n")
 | 
				
			||||||
 | 
					    ai_n = args.ai_name.replace("\\n", "\n")
 | 
				
			||||||
 | 
					    stop = args.stop.replace("\\n", "\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for line in messages:
 | 
				
			||||||
 | 
					        if (line["role"] == "system"):
 | 
				
			||||||
 | 
					            prompt += f"{system_n}{line['content']}"
 | 
				
			||||||
 | 
					        if (line["role"] == "user"):
 | 
				
			||||||
 | 
					            prompt += f"{user_n}{line['content']}"
 | 
				
			||||||
 | 
					        if (line["role"] == "assistant"):
 | 
				
			||||||
 | 
					            prompt += f"{ai_n}{line['content']}{stop}"
 | 
				
			||||||
 | 
					    prompt += ai_n.rstrip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return prompt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def make_postData(body, chat=False, stream=False):
 | 
				
			||||||
 | 
					    postData = {}
 | 
				
			||||||
 | 
					    if (chat):
 | 
				
			||||||
 | 
					        postData["prompt"] = convert_chat(body["messages"])
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        postData["prompt"] = body["prompt"]
 | 
				
			||||||
 | 
					    if(is_present(body, "temperature")): postData["temperature"] = body["temperature"]
 | 
				
			||||||
 | 
					    if(is_present(body, "top_k")): postData["top_k"] = body["top_k"]
 | 
				
			||||||
 | 
					    if(is_present(body, "top_p")): postData["top_p"] = body["top_p"]
 | 
				
			||||||
 | 
					    if(is_present(body, "max_tokens")): postData["n_predict"] = body["max_tokens"]
 | 
				
			||||||
 | 
					    if(is_present(body, "presence_penalty")): postData["presence_penalty"] = body["presence_penalty"]
 | 
				
			||||||
 | 
					    if(is_present(body, "frequency_penalty")): postData["frequency_penalty"] = body["frequency_penalty"]
 | 
				
			||||||
 | 
					    if(is_present(body, "repeat_penalty")): postData["repeat_penalty"] = body["repeat_penalty"]
 | 
				
			||||||
 | 
					    if(is_present(body, "mirostat")): postData["mirostat"] = body["mirostat"]
 | 
				
			||||||
 | 
					    if(is_present(body, "mirostat_tau")): postData["mirostat_tau"] = body["mirostat_tau"]
 | 
				
			||||||
 | 
					    if(is_present(body, "mirostat_eta")): postData["mirostat_eta"] = body["mirostat_eta"]
 | 
				
			||||||
 | 
					    if(is_present(body, "seed")): postData["seed"] = body["seed"]
 | 
				
			||||||
 | 
					    if(is_present(body, "logit_bias")): postData["logit_bias"] = [[int(token), body["logit_bias"][token]] for token in body["logit_bias"].keys()]
 | 
				
			||||||
 | 
					    if (args.stop != ""):
 | 
				
			||||||
 | 
					        postData["stop"] = [args.stop]
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        postData["stop"] = []
 | 
				
			||||||
 | 
					    if(is_present(body, "stop")): postData["stop"] += body["stop"]
 | 
				
			||||||
 | 
					    postData["n_keep"] = -1
 | 
				
			||||||
 | 
					    postData["stream"] = stream
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return postData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def make_resData(data, chat=False, promptToken=[]):
 | 
				
			||||||
 | 
					    resData = {
 | 
				
			||||||
 | 
					        "id": "chatcmpl" if (chat) else "cmpl",
 | 
				
			||||||
 | 
					        "object": "chat.completion" if (chat) else "text_completion",
 | 
				
			||||||
 | 
					        "created": int(time.time()),
 | 
				
			||||||
 | 
					        "truncated": data["truncated"],
 | 
				
			||||||
 | 
					        "model": "LLaMA_CPP",
 | 
				
			||||||
 | 
					        "usage": {
 | 
				
			||||||
 | 
					            "prompt_tokens": data["tokens_evaluated"],
 | 
				
			||||||
 | 
					            "completion_tokens": data["tokens_predicted"],
 | 
				
			||||||
 | 
					            "total_tokens": data["tokens_evaluated"] + data["tokens_predicted"]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (len(promptToken) != 0):
 | 
				
			||||||
 | 
					        resData["promptToken"] = promptToken
 | 
				
			||||||
 | 
					    if (chat):
 | 
				
			||||||
 | 
					        #only one choice is supported
 | 
				
			||||||
 | 
					        resData["choices"] = [{
 | 
				
			||||||
 | 
					            "index": 0,
 | 
				
			||||||
 | 
					            "message": {
 | 
				
			||||||
 | 
					                "role": "assistant",
 | 
				
			||||||
 | 
					                "content": data["content"],
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "finish_reason": "stop" if (data["stopped_eos"] or data["stopped_word"]) else "length"
 | 
				
			||||||
 | 
					        }]
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        #only one choice is supported
 | 
				
			||||||
 | 
					        resData["choices"] = [{
 | 
				
			||||||
 | 
					            "text": data["content"],
 | 
				
			||||||
 | 
					            "index": 0,
 | 
				
			||||||
 | 
					            "logprobs": None,
 | 
				
			||||||
 | 
					            "finish_reason": "stop" if (data["stopped_eos"] or data["stopped_word"]) else "length"
 | 
				
			||||||
 | 
					        }]
 | 
				
			||||||
 | 
					    return resData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def make_resData_stream(data, chat=False, time_now = 0, start=False):
 | 
				
			||||||
 | 
					    resData = {
 | 
				
			||||||
 | 
					        "id": "chatcmpl" if (chat) else "cmpl",
 | 
				
			||||||
 | 
					        "object": "chat.completion.chunk" if (chat) else "text_completion.chunk",
 | 
				
			||||||
 | 
					        "created": time_now,
 | 
				
			||||||
 | 
					        "model": "LLaMA_CPP",
 | 
				
			||||||
 | 
					        "choices": [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "finish_reason": None,
 | 
				
			||||||
 | 
					                "index": 0
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (chat):
 | 
				
			||||||
 | 
					        if (start):
 | 
				
			||||||
 | 
					            resData["choices"][0]["delta"] =  {
 | 
				
			||||||
 | 
					                "role": "assistant"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            resData["choices"][0]["delta"] =  {
 | 
				
			||||||
 | 
					                "content": data["content"]
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (data["stop"]):
 | 
				
			||||||
 | 
					                resData["choices"][0]["finish_reason"] = "stop" if (data["stopped_eos"] or data["stopped_word"]) else "length"
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        resData["choices"][0]["text"] = data["content"]
 | 
				
			||||||
 | 
					        if (data["stop"]):
 | 
				
			||||||
 | 
					            resData["choices"][0]["finish_reason"] = "stop" if (data["stopped_eos"] or data["stopped_word"]) else "length"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return resData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/chat/completions', methods=['POST'])
 | 
				
			||||||
 | 
					@app.route('/v1/chat/completions', methods=['POST'])
 | 
				
			||||||
 | 
					def chat_completions():
 | 
				
			||||||
 | 
					    if (args.api_key != "" and request.headers["Authorization"].split()[1] != args.api_key):
 | 
				
			||||||
 | 
					        return Response(status=403)
 | 
				
			||||||
 | 
					    body = request.get_json()
 | 
				
			||||||
 | 
					    stream = False
 | 
				
			||||||
 | 
					    tokenize = False
 | 
				
			||||||
 | 
					    if(is_present(body, "stream")): stream = body["stream"]
 | 
				
			||||||
 | 
					    if(is_present(body, "tokenize")): tokenize = body["tokenize"]
 | 
				
			||||||
 | 
					    postData = make_postData(body, chat=True, stream=stream)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    promptToken = []
 | 
				
			||||||
 | 
					    if (tokenize):
 | 
				
			||||||
 | 
					        tokenData = requests.request("POST", urllib.parse.urljoin(args.llama_api, "/tokenize"), data=json.dumps({"content": postData["prompt"]})).json()
 | 
				
			||||||
 | 
					        promptToken = tokenData["tokens"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (not stream):
 | 
				
			||||||
 | 
					        data = requests.request("POST", urllib.parse.urljoin(args.llama_api, "/completion"), data=json.dumps(postData))
 | 
				
			||||||
 | 
					        print(data.json())
 | 
				
			||||||
 | 
					        resData = make_resData(data.json(), chat=True, promptToken=promptToken)
 | 
				
			||||||
 | 
					        return jsonify(resData)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        def generate():
 | 
				
			||||||
 | 
					            data = requests.request("POST", urllib.parse.urljoin(args.llama_api, "/completion"), data=json.dumps(postData), stream=True)
 | 
				
			||||||
 | 
					            time_now = int(time.time())
 | 
				
			||||||
 | 
					            resData = make_resData_stream({}, chat=True, time_now=time_now, start=True)
 | 
				
			||||||
 | 
					            yield 'data: {}\n'.format(json.dumps(resData))
 | 
				
			||||||
 | 
					            for line in data.iter_lines():
 | 
				
			||||||
 | 
					                if line:
 | 
				
			||||||
 | 
					                    decoded_line = line.decode('utf-8')
 | 
				
			||||||
 | 
					                    resData = make_resData_stream(json.loads(decoded_line[6:]), chat=True, time_now=time_now)
 | 
				
			||||||
 | 
					                    yield 'data: {}\n'.format(json.dumps(resData))
 | 
				
			||||||
 | 
					        return Response(generate(), mimetype='text/event-stream')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/completions', methods=['POST'])
 | 
				
			||||||
 | 
					@app.route('/v1/completions', methods=['POST'])
 | 
				
			||||||
 | 
					def completion():
 | 
				
			||||||
 | 
					    if (args.api_key != "" and request.headers["Authorization"].split()[1] != args.api_key):
 | 
				
			||||||
 | 
					        return Response(status=403)
 | 
				
			||||||
 | 
					    body = request.get_json()
 | 
				
			||||||
 | 
					    stream = False
 | 
				
			||||||
 | 
					    tokenize = False
 | 
				
			||||||
 | 
					    if(is_present(body, "stream")): stream = body["stream"]
 | 
				
			||||||
 | 
					    if(is_present(body, "tokenize")): tokenize = body["tokenize"]
 | 
				
			||||||
 | 
					    postData = make_postData(body, chat=False, stream=stream)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    promptToken = []
 | 
				
			||||||
 | 
					    if (tokenize):
 | 
				
			||||||
 | 
					        tokenData = requests.request("POST", urllib.parse.urljoin(args.llama_api, "/tokenize"), data=json.dumps({"content": postData["prompt"]})).json()
 | 
				
			||||||
 | 
					        promptToken = tokenData["tokens"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (not stream):
 | 
				
			||||||
 | 
					        data = requests.request("POST", urllib.parse.urljoin(args.llama_api, "/completion"), data=json.dumps(postData))
 | 
				
			||||||
 | 
					        print(data.json())
 | 
				
			||||||
 | 
					        resData = make_resData(data.json(), chat=False, promptToken=promptToken)
 | 
				
			||||||
 | 
					        return jsonify(resData)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        def generate():
 | 
				
			||||||
 | 
					            data = requests.request("POST", urllib.parse.urljoin(args.llama_api, "/completion"), data=json.dumps(postData), stream=True)
 | 
				
			||||||
 | 
					            time_now = int(time.time())
 | 
				
			||||||
 | 
					            for line in data.iter_lines():
 | 
				
			||||||
 | 
					                if line:
 | 
				
			||||||
 | 
					                    decoded_line = line.decode('utf-8')
 | 
				
			||||||
 | 
					                    resData = make_resData_stream(json.loads(decoded_line[6:]), chat=False, time_now=time_now)
 | 
				
			||||||
 | 
					                    yield 'data: {}\n'.format(json.dumps(resData))
 | 
				
			||||||
 | 
					        return Response(generate(), mimetype='text/event-stream')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    app.run(args.host, port=args.port)
 | 
				
			||||||
							
								
								
									
										193
									
								
								examples/server/completion.js.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								examples/server/completion.js.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,193 @@
 | 
				
			|||||||
 | 
					unsigned char completion_js[] = {
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x44,
 | 
				
			||||||
 | 
					  0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x3a, 0x20, 0x74, 0x72,
 | 
				
			||||||
 | 
					  0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x64,
 | 
				
			||||||
 | 
					  0x69, 0x63, 0x74, 0x3a, 0x20, 0x35, 0x30, 0x30, 0x2c, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x3a,
 | 
				
			||||||
 | 
					  0x20, 0x30, 0x2e, 0x32, 0x2c, 0x0a, 0x20, 0x20, 0x73, 0x74, 0x6f, 0x70,
 | 
				
			||||||
 | 
					  0x3a, 0x20, 0x5b, 0x22, 0x3c, 0x2f, 0x73, 0x3e, 0x22, 0x5d, 0x0a, 0x7d,
 | 
				
			||||||
 | 
					  0x3b, 0x0a, 0x0a, 0x2f, 0x2a, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x54, 0x68,
 | 
				
			||||||
 | 
					  0x69, 0x73, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68,
 | 
				
			||||||
 | 
					  0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x65, 0x78, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c, 0x6c, 0x61,
 | 
				
			||||||
 | 
					  0x6d, 0x61, 0x20, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72,
 | 
				
			||||||
 | 
					  0x79, 0x2e, 0x0a, 0x20, 0x2a, 0x20, 0x40, 0x70, 0x61, 0x72, 0x61, 0x6d,
 | 
				
			||||||
 | 
					  0x20, 0x7b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x20, 0x70, 0x61,
 | 
				
			||||||
 | 
					  0x72, 0x61, 0x6d, 0x73, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x70,
 | 
				
			||||||
 | 
					  0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x66, 0x6f,
 | 
				
			||||||
 | 
					  0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
 | 
				
			||||||
 | 
					  0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x2e, 0x0a, 0x20, 0x2a, 0x20, 0x40, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20,
 | 
				
			||||||
 | 
					  0x7b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x20, 0x63, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x61, 0x6e,
 | 
				
			||||||
 | 
					  0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66,
 | 
				
			||||||
 | 
					  0x20, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
 | 
				
			||||||
 | 
					  0x6c, 0x6c, 0x65, 0x72, 0x20, 0x69, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x20,
 | 
				
			||||||
 | 
					  0x6e, 0x65, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x65, 0x2c, 0x20, 0x6f, 0x72,
 | 
				
			||||||
 | 
					  0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2e, 0x0a, 0x20, 0x2a, 0x20, 0x40, 0x70,
 | 
				
			||||||
 | 
					  0x61, 0x72, 0x61, 0x6d, 0x20, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x7d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
 | 
				
			||||||
 | 
					  0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62,
 | 
				
			||||||
 | 
					  0x61, 0x63, 0x6b, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x20, 0x74, 0x6f, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x77, 0x68, 0x65,
 | 
				
			||||||
 | 
					  0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
 | 
				
			||||||
 | 
					  0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x64, 0x6f, 0x6e, 0x65,
 | 
				
			||||||
 | 
					  0x2e, 0x0a, 0x20, 0x2a, 0x20, 0x40, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
 | 
				
			||||||
 | 
					  0x73, 0x20, 0x7b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7d, 0x20, 0x74,
 | 
				
			||||||
 | 
					  0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64,
 | 
				
			||||||
 | 
					  0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x73,
 | 
				
			||||||
 | 
					  0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x20, 0x49, 0x64, 0x65, 0x61, 0x6c,
 | 
				
			||||||
 | 
					  0x6c, 0x79, 0x20, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x2c, 0x20,
 | 
				
			||||||
 | 
					  0x61, 0x6e, 0x64, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x67, 0x65, 0x74, 0x20,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x20, 0x69, 0x74, 0x20, 0x76, 0x69, 0x61, 0x20, 0x74, 0x68,
 | 
				
			||||||
 | 
					  0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x2a, 0x2f, 0x0a, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x43, 0x6f,
 | 
				
			||||||
 | 
					  0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x61, 0x73, 0x79,
 | 
				
			||||||
 | 
					  0x6e, 0x63, 0x20, 0x28, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2c, 0x20,
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x20,
 | 
				
			||||||
 | 
					  0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x29, 0x20, 0x3d, 0x3e,
 | 
				
			||||||
 | 
					  0x20, 0x7b, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x63, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x29, 0x20, 0x7b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
 | 
				
			||||||
 | 
					  0x65, 0x72, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x62, 0x6f,
 | 
				
			||||||
 | 
					  0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x63, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x7b,
 | 
				
			||||||
 | 
					  0x20, 0x2e, 0x2e, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x44, 0x65, 0x66,
 | 
				
			||||||
 | 
					  0x61, 0x75, 0x6c, 0x74, 0x73, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x70, 0x61,
 | 
				
			||||||
 | 
					  0x72, 0x61, 0x6d, 0x73, 0x20, 0x7d, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x2f,
 | 
				
			||||||
 | 
					  0x2f, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x66, 0x65, 0x74,
 | 
				
			||||||
 | 
					  0x63, 0x68, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x20,
 | 
				
			||||||
 | 
					  0x68, 0x65, 0x72, 0x65, 0x20, 0x62, 0x65, 0x63, 0x61, 0x73, 0x75, 0x65,
 | 
				
			||||||
 | 
					  0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x20, 0x69,
 | 
				
			||||||
 | 
					  0x6e, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20,
 | 
				
			||||||
 | 
					  0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20,
 | 
				
			||||||
 | 
					  0x50, 0x4f, 0x53, 0x54, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x3d, 0x20,
 | 
				
			||||||
 | 
					  0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28,
 | 
				
			||||||
 | 
					  0x22, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x22, 0x2c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74,
 | 
				
			||||||
 | 
					  0x68, 0x6f, 0x64, 0x3a, 0x20, 0x27, 0x50, 0x4f, 0x53, 0x54, 0x27, 0x2c,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x20, 0x4a,
 | 
				
			||||||
 | 
					  0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66,
 | 
				
			||||||
 | 
					  0x79, 0x28, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3a, 0x20, 0x7b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
 | 
				
			||||||
 | 
					  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x3a, 0x20, 0x27, 0x6b, 0x65, 0x65,
 | 
				
			||||||
 | 
					  0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x27, 0x2c, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x2d, 0x54, 0x79, 0x70, 0x65, 0x27, 0x3a, 0x20, 0x27, 0x61, 0x70, 0x70,
 | 
				
			||||||
 | 
					  0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, 0x41,
 | 
				
			||||||
 | 
					  0x63, 0x63, 0x65, 0x70, 0x74, 0x27, 0x3a, 0x20, 0x27, 0x74, 0x65, 0x78,
 | 
				
			||||||
 | 
					  0x74, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x61, 0x6d, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x3a, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x69,
 | 
				
			||||||
 | 
					  0x67, 0x6e, 0x61, 0x6c, 0x2c, 0x0a, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x61,
 | 
				
			||||||
 | 
					  0x64, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x73, 0x65, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x67, 0x65, 0x74, 0x52,
 | 
				
			||||||
 | 
					  0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x73, 0x74, 0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x78, 0x74, 0x44,
 | 
				
			||||||
 | 
					  0x65, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3b, 0x0a, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x22, 0x22, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x74, 0x72,
 | 
				
			||||||
 | 
					  0x79, 0x20, 0x7b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65,
 | 
				
			||||||
 | 
					  0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65,
 | 
				
			||||||
 | 
					  0x20, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x73, 0x75, 0x6c, 0x74, 0x20, 0x3d, 0x20, 0x61, 0x77, 0x61, 0x69, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64,
 | 
				
			||||||
 | 
					  0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66,
 | 
				
			||||||
 | 
					  0x20, 0x28, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x64, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x65, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f,
 | 
				
			||||||
 | 
					  0x2f, 0x20, 0x73, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x73, 0x77, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72,
 | 
				
			||||||
 | 
					  0x6d, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x6c,
 | 
				
			||||||
 | 
					  0x69, 0x6e, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x3a, 0x20, 0x76, 0x61, 0x6c,
 | 
				
			||||||
 | 
					  0x75, 0x65, 0x5c, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x64, 0x61,
 | 
				
			||||||
 | 
					  0x74, 0x61, 0x20, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x20, 0x70, 0x72,
 | 
				
			||||||
 | 
					  0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x6b,
 | 
				
			||||||
 | 
					  0x65, 0x79, 0x2e, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x75, 0x72, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x61, 0x73, 0x65, 0x20, 0x77, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x2f, 0x2f, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x6c, 0x79, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x61, 0x72, 0x65, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68,
 | 
				
			||||||
 | 
					  0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x6b, 0x65, 0x79, 0x20,
 | 
				
			||||||
 | 
					  0x68, 0x65, 0x72, 0x65, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20,
 | 
				
			||||||
 | 
					  0x77, 0x65, 0x20, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x20, 0x61, 0x73,
 | 
				
			||||||
 | 
					  0x20, 0x6a, 0x73, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x3d,
 | 
				
			||||||
 | 
					  0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x64, 0x65, 0x63,
 | 
				
			||||||
 | 
					  0x6f, 0x64, 0x65, 0x28, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x76,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x2f, 0x2f, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x61,
 | 
				
			||||||
 | 
					  0x6c, 0x6c, 0x20, 0x73, 0x73, 0x65, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x64, 0x64, 0x20, 0x74, 0x68,
 | 
				
			||||||
 | 
					  0x65, 0x6d, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x2f, 0x5e, 0x28,
 | 
				
			||||||
 | 
					  0x5c, 0x53, 0x2b, 0x29, 0x3a, 0x5c, 0x73, 0x28, 0x2e, 0x2a, 0x29, 0x24,
 | 
				
			||||||
 | 
					  0x2f, 0x67, 0x6d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66,
 | 
				
			||||||
 | 
					  0x6f, 0x72, 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6d, 0x61,
 | 
				
			||||||
 | 
					  0x74, 0x63, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2e,
 | 
				
			||||||
 | 
					  0x6d, 0x61, 0x74, 0x63, 0x68, 0x41, 0x6c, 0x6c, 0x28, 0x72, 0x65, 0x67,
 | 
				
			||||||
 | 
					  0x65, 0x78, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5b, 0x6d, 0x61,
 | 
				
			||||||
 | 
					  0x74, 0x63, 0x68, 0x5b, 0x31, 0x5d, 0x5d, 0x20, 0x3d, 0x20, 0x6d, 0x61,
 | 
				
			||||||
 | 
					  0x74, 0x63, 0x68, 0x5b, 0x32, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f,
 | 
				
			||||||
 | 
					  0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x65, 0x20, 0x6b, 0x6e,
 | 
				
			||||||
 | 
					  0x6f, 0x77, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6c,
 | 
				
			||||||
 | 
					  0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x63, 0x70, 0x70, 0x2c, 0x20, 0x6c, 0x65,
 | 
				
			||||||
 | 
					  0x74, 0x27, 0x73, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x64, 0x65, 0x63,
 | 
				
			||||||
 | 
					  0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6a, 0x73, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x20, 0x69, 0x6e, 0x20, 0x64, 0x61, 0x74, 0x61, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x64, 0x61,
 | 
				
			||||||
 | 
					  0x74, 0x61, 0x20, 0x3d, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x70, 0x61,
 | 
				
			||||||
 | 
					  0x72, 0x73, 0x65, 0x28, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x64,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x61, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x2b, 0x3d, 0x20, 0x72,
 | 
				
			||||||
 | 
					  0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x63,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x61, 0x63,
 | 
				
			||||||
 | 
					  0x6b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28,
 | 
				
			||||||
 | 
					  0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x29, 0x20, 0x7b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28,
 | 
				
			||||||
 | 
					  0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x29, 0x20, 0x21, 0x3d, 0x20, 0x66,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x73, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20,
 | 
				
			||||||
 | 
					  0x69, 0x66, 0x20, 0x77, 0x65, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x61, 0x20,
 | 
				
			||||||
 | 
					  0x73, 0x74, 0x6f, 0x70, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x66,
 | 
				
			||||||
 | 
					  0x72, 0x6f, 0x6d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2c, 0x20,
 | 
				
			||||||
 | 
					  0x77, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x72, 0x65, 0x61,
 | 
				
			||||||
 | 
					  0x6b, 0x20, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e,
 | 
				
			||||||
 | 
					  0x64, 0x61, 0x74, 0x61, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x29, 0x20, 0x7b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x61, 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x7d, 0x20, 0x63, 0x61,
 | 
				
			||||||
 | 
					  0x74, 0x63, 0x68, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x72, 0x6f, 0x72, 0x28, 0x22, 0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x20, 0x65,
 | 
				
			||||||
 | 
					  0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, 0x22, 0x2c, 0x20, 0x65, 0x29, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, 0x65,
 | 
				
			||||||
 | 
					  0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x66, 0x69, 0x6e, 0x61,
 | 
				
			||||||
 | 
					  0x6c, 0x6c, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x62, 0x6f,
 | 
				
			||||||
 | 
					  0x72, 0x74, 0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x6e, 0x74, 0x3b, 0x0a, 0x7d, 0x0a
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					unsigned int completion_js_len = 2275;
 | 
				
			||||||
							
								
								
									
										22
									
								
								examples/server/deps.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								examples/server/deps.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					# Download and update deps for binary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# get the directory of this script file
 | 
				
			||||||
 | 
					DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
 | 
				
			||||||
 | 
					PUBLIC=$DIR/public
 | 
				
			||||||
 | 
					OUTPUT=$DIR/templats.hpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "// Generated file, do not edit" > $OUTPUT
 | 
				
			||||||
 | 
					echo "" > $OUTPUT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "download js bundle files"
 | 
				
			||||||
 | 
					curl https://npm.reversehttp.com/@preact/signals-core,@preact/signals,htm/preact,preact,preact/hooks > $PUBLIC/index.js
 | 
				
			||||||
 | 
					echo >> $PUBLIC/index.js # add newline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FILES=$(ls $PUBLIC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for FILE in $FILES; do
 | 
				
			||||||
 | 
					  func=$(echo $FILE | tr '.' '_')
 | 
				
			||||||
 | 
					  echo "generate $FILE.hpp ($func)"
 | 
				
			||||||
 | 
					  xxd -n $func -i $PUBLIC/$FILE > $DIR/$FILE.hpp
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
							
								
								
									
										846
									
								
								examples/server/index.html.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										846
									
								
								examples/server/index.html.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,846 @@
 | 
				
			|||||||
 | 
					unsigned char index_html[] = {
 | 
				
			||||||
 | 
					  0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x0a, 0x3c, 0x68, 0x65, 0x61,
 | 
				
			||||||
 | 
					  0x64, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, 0x55, 0x54, 0x46, 0x2d,
 | 
				
			||||||
 | 
					  0x38, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20,
 | 
				
			||||||
 | 
					  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x69, 0x65, 0x77, 0x70, 0x6f,
 | 
				
			||||||
 | 
					  0x72, 0x74, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d,
 | 
				
			||||||
 | 
					  0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x64, 0x65, 0x76, 0x69, 0x63,
 | 
				
			||||||
 | 
					  0x65, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x20, 0x69, 0x6e, 0x69,
 | 
				
			||||||
 | 
					  0x74, 0x69, 0x61, 0x6c, 0x2d, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x3d, 0x31,
 | 
				
			||||||
 | 
					  0x2c, 0x20, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x2d, 0x73, 0x63,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x65, 0x3d, 0x31, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x6c, 0x6c, 0x61, 0x6d, 0x61,
 | 
				
			||||||
 | 
					  0x2e, 0x63, 0x70, 0x70, 0x20, 0x2d, 0x20, 0x63, 0x68, 0x61, 0x74, 0x3c,
 | 
				
			||||||
 | 
					  0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x62, 0x6f, 0x64, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
 | 
				
			||||||
 | 
					  0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c,
 | 
				
			||||||
 | 
					  0x79, 0x3a, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2d, 0x75, 0x69,
 | 
				
			||||||
 | 
					  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x39, 0x30, 0x25, 0x3b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23,
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e,
 | 
				
			||||||
 | 
					  0x3a, 0x20, 0x30, 0x65, 0x6d, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61,
 | 
				
			||||||
 | 
					  0x79, 0x3a, 0x20, 0x66, 0x6c, 0x65, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x66, 0x6c, 0x65, 0x78, 0x2d, 0x64, 0x69, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d,
 | 
				
			||||||
 | 
					  0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6a, 0x75, 0x73,
 | 
				
			||||||
 | 
					  0x74, 0x69, 0x66, 0x79, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x3a, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2d, 0x62, 0x65, 0x74, 0x77,
 | 
				
			||||||
 | 
					  0x65, 0x65, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68,
 | 
				
			||||||
 | 
					  0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2c, 0x20, 0x66, 0x6f, 0x6f, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d,
 | 
				
			||||||
 | 
					  0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x7b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69,
 | 
				
			||||||
 | 
					  0x6e, 0x3a, 0x20, 0x33, 0x70, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x66,
 | 
				
			||||||
 | 
					  0x6c, 0x65, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66,
 | 
				
			||||||
 | 
					  0x6c, 0x65, 0x78, 0x2d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x3a, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x3b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79,
 | 
				
			||||||
 | 
					  0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x73, 0x70,
 | 
				
			||||||
 | 
					  0x61, 0x63, 0x65, 0x2d, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x61, 0x70, 0x3a, 0x20,
 | 
				
			||||||
 | 
					  0x31, 0x65, 0x6d, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x66, 0x6c, 0x65, 0x78, 0x2d, 0x67, 0x72, 0x6f, 0x77, 0x3a, 0x20, 0x31,
 | 
				
			||||||
 | 
					  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x76, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x66, 0x6c, 0x6f, 0x77, 0x2d, 0x79, 0x3a, 0x20, 0x61, 0x75, 0x74, 0x6f,
 | 
				
			||||||
 | 
					  0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x72,
 | 
				
			||||||
 | 
					  0x64, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c,
 | 
				
			||||||
 | 
					  0x69, 0x64, 0x20, 0x23, 0x63, 0x63, 0x63, 0x3b, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61,
 | 
				
			||||||
 | 
					  0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x35, 0x70, 0x78, 0x3b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67,
 | 
				
			||||||
 | 
					  0x3a, 0x20, 0x30, 0x2e, 0x35, 0x65, 0x6d, 0x3b, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x64, 0x79,
 | 
				
			||||||
 | 
					  0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x78,
 | 
				
			||||||
 | 
					  0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x36, 0x30, 0x30, 0x70,
 | 
				
			||||||
 | 
					  0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x69, 0x6e,
 | 
				
			||||||
 | 
					  0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x33, 0x30, 0x30, 0x70,
 | 
				
			||||||
 | 
					  0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e,
 | 
				
			||||||
 | 
					  0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x2e,
 | 
				
			||||||
 | 
					  0x32, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x72,
 | 
				
			||||||
 | 
					  0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69,
 | 
				
			||||||
 | 
					  0x6e, 0x67, 0x3a, 0x20, 0x30, 0x20, 0x30, 0x2e, 0x35, 0x65, 0x6d, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x70, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x76,
 | 
				
			||||||
 | 
					  0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x3a,
 | 
				
			||||||
 | 
					  0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2d, 0x77, 0x6f, 0x72, 0x64, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x2d,
 | 
				
			||||||
 | 
					  0x77, 0x72, 0x61, 0x70, 0x3a, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2d,
 | 
				
			||||||
 | 
					  0x77, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x3a, 0x20, 0x61, 0x75, 0x74,
 | 
				
			||||||
 | 
					  0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x72,
 | 
				
			||||||
 | 
					  0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x30, 0x2e, 0x35,
 | 
				
			||||||
 | 
					  0x65, 0x6d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61,
 | 
				
			||||||
 | 
					  0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a,
 | 
				
			||||||
 | 
					  0x20, 0x30, 0x2e, 0x35, 0x65, 0x6d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x77, 0x72, 0x69, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x31,
 | 
				
			||||||
 | 
					  0x65, 0x6d, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a,
 | 
				
			||||||
 | 
					  0x20, 0x66, 0x6c, 0x65, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x66, 0x6c, 0x65, 0x78, 0x2d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
 | 
				
			||||||
 | 
					  0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x61, 0x70, 0x3a, 0x20,
 | 
				
			||||||
 | 
					  0x30, 0x2e, 0x35, 0x65, 0x6d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x2d, 0x69, 0x74, 0x65, 0x6d, 0x73,
 | 
				
			||||||
 | 
					  0x3a, 0x20, 0x73, 0x74, 0x72, 0x65, 0x74, 0x63, 0x68, 0x3b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x72,
 | 
				
			||||||
 | 
					  0x69, 0x67, 0x68, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x66, 0x6c,
 | 
				
			||||||
 | 
					  0x65, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c,
 | 
				
			||||||
 | 
					  0x65, 0x78, 0x2d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x3a, 0x20, 0x72, 0x6f, 0x77, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x67, 0x61, 0x70, 0x3a, 0x20, 0x30, 0x2e, 0x35, 0x65, 0x6d, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x69,
 | 
				
			||||||
 | 
					  0x66, 0x79, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x20,
 | 
				
			||||||
 | 
					  0x66, 0x6c, 0x65, 0x78, 0x2d, 0x65, 0x6e, 0x64, 0x3b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x69, 0x65,
 | 
				
			||||||
 | 
					  0x6c, 0x64, 0x73, 0x65, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x6e, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61,
 | 
				
			||||||
 | 
					  0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20,
 | 
				
			||||||
 | 
					  0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x7b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69,
 | 
				
			||||||
 | 
					  0x6e, 0x67, 0x3a, 0x20, 0x35, 0x70, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x66, 0x6c, 0x65, 0x78, 0x2d, 0x67, 0x72, 0x6f, 0x77,
 | 
				
			||||||
 | 
					  0x3a, 0x20, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77,
 | 
				
			||||||
 | 
					  0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70,
 | 
				
			||||||
 | 
					  0x72, 0x65, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a,
 | 
				
			||||||
 | 
					  0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64,
 | 
				
			||||||
 | 
					  0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x32, 0x32,
 | 
				
			||||||
 | 
					  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
 | 
				
			||||||
 | 
					  0x72, 0x3a, 0x20, 0x23, 0x64, 0x64, 0x64, 0x3b, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20,
 | 
				
			||||||
 | 
					  0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x20, 0x6d, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x6f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x30,
 | 
				
			||||||
 | 
					  0x2e, 0x31, 0x65, 0x6d, 0x20, 0x30, 0x2e, 0x33, 0x65, 0x6d, 0x3b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x33, 0x70, 0x78,
 | 
				
			||||||
 | 
					  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x20, 0x6c, 0x61,
 | 
				
			||||||
 | 
					  0x62, 0x65, 0x6c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30, 0x2e, 0x35, 0x65,
 | 
				
			||||||
 | 
					  0x6d, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64,
 | 
				
			||||||
 | 
					  0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x62, 0x6c, 0x6f, 0x63,
 | 
				
			||||||
 | 
					  0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d,
 | 
				
			||||||
 | 
					  0x22, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x22, 0x3e, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x7b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x20, 0x68,
 | 
				
			||||||
 | 
					  0x2c, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x2c, 0x20, 0x65, 0x66,
 | 
				
			||||||
 | 
					  0x66, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x64, 0x2c, 0x20, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2c, 0x20,
 | 
				
			||||||
 | 
					  0x75, 0x73, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x2c, 0x20, 0x75,
 | 
				
			||||||
 | 
					  0x73, 0x65, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x75, 0x73,
 | 
				
			||||||
 | 
					  0x65, 0x52, 0x65, 0x66, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x66,
 | 
				
			||||||
 | 
					  0x72, 0x6f, 0x6d, 0x20, 0x27, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e,
 | 
				
			||||||
 | 
					  0x6a, 0x73, 0x27, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6d,
 | 
				
			||||||
 | 
					  0x70, 0x6f, 0x72, 0x74, 0x20, 0x7b, 0x20, 0x6c, 0x6c, 0x61, 0x6d, 0x61,
 | 
				
			||||||
 | 
					  0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x7d, 0x20, 0x66,
 | 
				
			||||||
 | 
					  0x72, 0x6f, 0x6d, 0x20, 0x27, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
 | 
				
			||||||
 | 
					  0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6a, 0x73, 0x27, 0x3b, 0x0a, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x73, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61,
 | 
				
			||||||
 | 
					  0x6c, 0x28, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72,
 | 
				
			||||||
 | 
					  0x6f, 0x6d, 0x70, 0x74, 0x3a, 0x20, 0x22, 0x54, 0x68, 0x69, 0x73, 0x20,
 | 
				
			||||||
 | 
					  0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65,
 | 
				
			||||||
 | 
					  0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c,
 | 
				
			||||||
 | 
					  0x6c, 0x61, 0x6d, 0x61, 0x2c, 0x20, 0x61, 0x20, 0x66, 0x72, 0x69, 0x65,
 | 
				
			||||||
 | 
					  0x6e, 0x64, 0x6c, 0x79, 0x20, 0x63, 0x68, 0x61, 0x74, 0x62, 0x6f, 0x74,
 | 
				
			||||||
 | 
					  0x2e, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x20, 0x69, 0x6e,
 | 
				
			||||||
 | 
					  0x20, 0x6d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x2e, 0x22, 0x2c,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x65, 0x3a, 0x20, 0x22, 0x7b, 0x7b, 0x70, 0x72, 0x6f, 0x6d,
 | 
				
			||||||
 | 
					  0x70, 0x74, 0x7d, 0x7d, 0x5c, 0x6e, 0x5c, 0x6e, 0x7b, 0x7b, 0x68, 0x69,
 | 
				
			||||||
 | 
					  0x73, 0x74, 0x6f, 0x72, 0x79, 0x7d, 0x7d, 0x5c, 0x6e, 0x7b, 0x7b, 0x63,
 | 
				
			||||||
 | 
					  0x68, 0x61, 0x72, 0x7d, 0x7d, 0x3a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65,
 | 
				
			||||||
 | 
					  0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x22, 0x7b, 0x7b, 0x6e,
 | 
				
			||||||
 | 
					  0x61, 0x6d, 0x65, 0x7d, 0x7d, 0x3a, 0x20, 0x7b, 0x7b, 0x6d, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x73, 0x61, 0x67, 0x65, 0x7d, 0x7d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70,
 | 
				
			||||||
 | 
					  0x74, 0x3a, 0x20, 0x5b, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x63, 0x68, 0x61, 0x74,
 | 
				
			||||||
 | 
					  0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x61,
 | 
				
			||||||
 | 
					  0x72, 0x3a, 0x20, 0x22, 0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x22, 0x2c, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x20,
 | 
				
			||||||
 | 
					  0x22, 0x55, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x7d, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73,
 | 
				
			||||||
 | 
					  0x74, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
 | 
				
			||||||
 | 
					  0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x72,
 | 
				
			||||||
 | 
					  0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x29, 0x20, 0x3d, 0x3e,
 | 
				
			||||||
 | 
					  0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d,
 | 
				
			||||||
 | 
					  0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2e,
 | 
				
			||||||
 | 
					  0x2e, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61,
 | 
				
			||||||
 | 
					  0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x63, 0x68, 0x61, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x28,
 | 
				
			||||||
 | 
					  0x28, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e,
 | 
				
			||||||
 | 
					  0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74,
 | 
				
			||||||
 | 
					  0x68, 0x20, 0x3e, 0x20, 0x30, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x28, 0x7b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x64,
 | 
				
			||||||
 | 
					  0x69, 0x63, 0x74, 0x3a, 0x20, 0x34, 0x30, 0x30, 0x2c, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74,
 | 
				
			||||||
 | 
					  0x75, 0x72, 0x65, 0x3a, 0x20, 0x30, 0x2e, 0x37, 0x2c, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x6c,
 | 
				
			||||||
 | 
					  0x61, 0x73, 0x74, 0x5f, 0x6e, 0x3a, 0x20, 0x32, 0x35, 0x36, 0x2c, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74,
 | 
				
			||||||
 | 
					  0x5f, 0x70, 0x65, 0x6e, 0x61, 0x6c, 0x74, 0x79, 0x3a, 0x20, 0x31, 0x2e,
 | 
				
			||||||
 | 
					  0x31, 0x38, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f,
 | 
				
			||||||
 | 
					  0x70, 0x5f, 0x6b, 0x3a, 0x20, 0x34, 0x30, 0x2c, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x74, 0x6f, 0x70, 0x5f, 0x70, 0x3a, 0x20, 0x30, 0x2e,
 | 
				
			||||||
 | 
					  0x35, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x0a, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x69,
 | 
				
			||||||
 | 
					  0x67, 0x6e, 0x61, 0x6c, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x67, 0x65, 0x6e,
 | 
				
			||||||
 | 
					  0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x63, 0x6f,
 | 
				
			||||||
 | 
					  0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x28, 0x28, 0x29, 0x20, 0x3d, 0x3e,
 | 
				
			||||||
 | 
					  0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
 | 
				
			||||||
 | 
					  0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x6e, 0x75, 0x6c,
 | 
				
			||||||
 | 
					  0x6c, 0x20, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20,
 | 
				
			||||||
 | 
					  0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x74, 0x65,
 | 
				
			||||||
 | 
					  0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x28, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x72, 0x2c, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x53, 0x65, 0x74, 0x74,
 | 
				
			||||||
 | 
					  0x69, 0x6e, 0x67, 0x73, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x65, 0x74,
 | 
				
			||||||
 | 
					  0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x73, 0x73,
 | 
				
			||||||
 | 
					  0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x65, 0x78, 0x74,
 | 
				
			||||||
 | 
					  0x72, 0x61, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x29, 0x20,
 | 
				
			||||||
 | 
					  0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65,
 | 
				
			||||||
 | 
					  0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x20, 0x2e,
 | 
				
			||||||
 | 
					  0x2e, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2c, 0x20,
 | 
				
			||||||
 | 
					  0x2e, 0x2e, 0x2e, 0x65, 0x78, 0x74, 0x72, 0x61, 0x53, 0x65, 0x74, 0x74,
 | 
				
			||||||
 | 
					  0x69, 0x6e, 0x67, 0x73, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x74, 0x75, 0x72, 0x6e, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28,
 | 
				
			||||||
 | 
					  0x73, 0x74, 0x72, 0x29, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
 | 
				
			||||||
 | 
					  0x41, 0x6c, 0x6c, 0x28, 0x2f, 0x5c, 0x7b, 0x5c, 0x7b, 0x28, 0x2e, 0x2a,
 | 
				
			||||||
 | 
					  0x3f, 0x29, 0x5c, 0x7d, 0x5c, 0x7d, 0x2f, 0x67, 0x2c, 0x20, 0x28, 0x5f,
 | 
				
			||||||
 | 
					  0x2c, 0x20, 0x6b, 0x65, 0x79, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x74, 0x65,
 | 
				
			||||||
 | 
					  0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x73, 0x65, 0x74, 0x74, 0x69,
 | 
				
			||||||
 | 
					  0x6e, 0x67, 0x73, 0x5b, 0x6b, 0x65, 0x79, 0x5d, 0x29, 0x29, 0x3b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f,
 | 
				
			||||||
 | 
					  0x2f, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61,
 | 
				
			||||||
 | 
					  0x67, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x68, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x20,
 | 
				
			||||||
 | 
					  0x28, 0x6d, 0x73, 0x67, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x63, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x76, 0x61, 0x6c, 0x75,
 | 
				
			||||||
 | 
					  0x65, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67,
 | 
				
			||||||
 | 
					  0x28, 0x27, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x20, 0x72, 0x75,
 | 
				
			||||||
 | 
					  0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x2e, 0x2e, 0x27, 0x29, 0x3b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
 | 
				
			||||||
 | 
					  0x72, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
 | 
				
			||||||
 | 
					  0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d,
 | 
				
			||||||
 | 
					  0x20, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x43, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x28, 0x29, 0x3b, 0x0a,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73,
 | 
				
			||||||
 | 
					  0x63, 0x72, 0x69, 0x70, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28,
 | 
				
			||||||
 | 
					  0x5b, 0x2e, 0x2e, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e,
 | 
				
			||||||
 | 
					  0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63,
 | 
				
			||||||
 | 
					  0x72, 0x69, 0x70, 0x74, 0x2c, 0x20, 0x5b, 0x22, 0x7b, 0x7b, 0x75, 0x73,
 | 
				
			||||||
 | 
					  0x65, 0x72, 0x7d, 0x7d, 0x22, 0x2c, 0x20, 0x6d, 0x73, 0x67, 0x5d, 0x5d,
 | 
				
			||||||
 | 
					  0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x73, 0x74, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3d,
 | 
				
			||||||
 | 
					  0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x73, 0x65,
 | 
				
			||||||
 | 
					  0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e,
 | 
				
			||||||
 | 
					  0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x7b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x73, 0x73,
 | 
				
			||||||
 | 
					  0x61, 0x67, 0x65, 0x3a, 0x20, 0x6d, 0x73, 0x67, 0x2c, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72,
 | 
				
			||||||
 | 
					  0x79, 0x3a, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x75, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72,
 | 
				
			||||||
 | 
					  0x69, 0x70, 0x74, 0x2e, 0x66, 0x6c, 0x61, 0x74, 0x4d, 0x61, 0x70, 0x28,
 | 
				
			||||||
 | 
					  0x28, 0x5b, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x6d, 0x65, 0x73, 0x73,
 | 
				
			||||||
 | 
					  0x61, 0x67, 0x65, 0x5d, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x74, 0x65, 0x6d,
 | 
				
			||||||
 | 
					  0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x68, 0x69, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x6f, 0x72, 0x79, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2c,
 | 
				
			||||||
 | 
					  0x20, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x6d, 0x65, 0x73, 0x73,
 | 
				
			||||||
 | 
					  0x61, 0x67, 0x65, 0x7d, 0x29, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28,
 | 
				
			||||||
 | 
					  0x22, 0x5c, 0x6e, 0x22, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x6c, 0x65, 0x74, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4d,
 | 
				
			||||||
 | 
					  0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x3d, 0x20, 0x73,
 | 
				
			||||||
 | 
					  0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65,
 | 
				
			||||||
 | 
					  0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x0a,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x2e, 0x2e, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x76,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x3a, 0x20, 0x70, 0x61,
 | 
				
			||||||
 | 
					  0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x73, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x5b, 0x22, 0x3c,
 | 
				
			||||||
 | 
					  0x2f, 0x73, 0x3e, 0x22, 0x2c, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
 | 
				
			||||||
 | 
					  0x74, 0x65, 0x28, 0x22, 0x7b, 0x7b, 0x63, 0x68, 0x61, 0x72, 0x7d, 0x7d,
 | 
				
			||||||
 | 
					  0x3a, 0x22, 0x29, 0x2c, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x28, 0x22, 0x7b, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x7d, 0x7d, 0x3a,
 | 
				
			||||||
 | 
					  0x22, 0x29, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d,
 | 
				
			||||||
 | 
					  0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x77, 0x61, 0x69,
 | 
				
			||||||
 | 
					  0x74, 0x20, 0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
 | 
				
			||||||
 | 
					  0x65, 0x74, 0x65, 0x28, 0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x50, 0x61, 0x72,
 | 
				
			||||||
 | 
					  0x61, 0x6d, 0x73, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
 | 
				
			||||||
 | 
					  0x6c, 0x65, 0x72, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x28,
 | 
				
			||||||
 | 
					  0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20,
 | 
				
			||||||
 | 
					  0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x73, 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x6d,
 | 
				
			||||||
 | 
					  0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x75, 0x72,
 | 
				
			||||||
 | 
					  0x72, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20,
 | 
				
			||||||
 | 
					  0x2b, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x6e, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x6c,
 | 
				
			||||||
 | 
					  0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65,
 | 
				
			||||||
 | 
					  0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x73, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x5e, 0x5c, 0x73, 0x2b, 0x2f,
 | 
				
			||||||
 | 
					  0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70,
 | 
				
			||||||
 | 
					  0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x5b, 0x2e, 0x2e, 0x2e,
 | 
				
			||||||
 | 
					  0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2c, 0x20, 0x5b, 0x22, 0x7b,
 | 
				
			||||||
 | 
					  0x7b, 0x63, 0x68, 0x61, 0x72, 0x7d, 0x7d, 0x22, 0x2c, 0x20, 0x63, 0x75,
 | 
				
			||||||
 | 
					  0x72, 0x72, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
 | 
				
			||||||
 | 
					  0x5d, 0x5d, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x69, 0x66, 0x20, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x6f, 0x70, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e,
 | 
				
			||||||
 | 
					  0x6c, 0x6f, 0x67, 0x28, 0x22, 0x2d, 0x2d, 0x3e, 0x22, 0x2c, 0x20, 0x64,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x61, 0x2c, 0x20, 0x27, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x73, 0x65, 0x20, 0x77, 0x61, 0x73, 0x3a, 0x27, 0x2c, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
 | 
				
			||||||
 | 
					  0x65, 0x2c, 0x20, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69,
 | 
				
			||||||
 | 
					  0x70, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x27, 0x2c, 0x20,
 | 
				
			||||||
 | 
					  0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75,
 | 
				
			||||||
 | 
					  0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
 | 
				
			||||||
 | 
					  0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x0a, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
 | 
				
			||||||
 | 
					  0x6c, 0x65, 0x72, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20,
 | 
				
			||||||
 | 
					  0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x70,
 | 
				
			||||||
 | 
					  0x75, 0x74, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61,
 | 
				
			||||||
 | 
					  0x67, 0x65, 0x20, 0x3d, 0x20, 0x75, 0x73, 0x65, 0x53, 0x69, 0x67, 0x6e,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x28, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x74, 0x6f, 0x70,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x28, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x2e, 0x70, 0x72,
 | 
				
			||||||
 | 
					  0x65, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
 | 
				
			||||||
 | 
					  0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x69, 0x66, 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
 | 
				
			||||||
 | 
					  0x65, 0x72, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, 0x7b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x76, 0x61, 0x6c,
 | 
				
			||||||
 | 
					  0x75, 0x65, 0x2e, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x28, 0x29, 0x3b, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x76, 0x61, 0x6c,
 | 
				
			||||||
 | 
					  0x75, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20,
 | 
				
			||||||
 | 
					  0x3d, 0x20, 0x28, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x6f, 0x70, 0x28,
 | 
				
			||||||
 | 
					  0x65, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x55, 0x70,
 | 
				
			||||||
 | 
					  0x64, 0x61, 0x74, 0x65, 0x28, 0x5b, 0x5d, 0x29, 0x3b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x69,
 | 
				
			||||||
 | 
					  0x74, 0x20, 0x3d, 0x20, 0x28, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x6f,
 | 
				
			||||||
 | 
					  0x70, 0x28, 0x65, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x63, 0x68, 0x61, 0x74, 0x28, 0x6d, 0x65, 0x73, 0x73, 0x61,
 | 
				
			||||||
 | 
					  0x67, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61,
 | 
				
			||||||
 | 
					  0x67, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x22,
 | 
				
			||||||
 | 
					  0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
 | 
				
			||||||
 | 
					  0x65, 0x6e, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x73,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x3d,
 | 
				
			||||||
 | 
					  0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x69, 0x66, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x77, 0x68,
 | 
				
			||||||
 | 
					  0x69, 0x63, 0x68, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x31, 0x33, 0x20, 0x26,
 | 
				
			||||||
 | 
					  0x26, 0x20, 0x21, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x68, 0x69,
 | 
				
			||||||
 | 
					  0x66, 0x74, 0x4b, 0x65, 0x79, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x69,
 | 
				
			||||||
 | 
					  0x74, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x3b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72,
 | 
				
			||||||
 | 
					  0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x60, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x66, 0x6f, 0x72,
 | 
				
			||||||
 | 
					  0x6d, 0x20, 0x6f, 0x6e, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3d, 0x24,
 | 
				
			||||||
 | 
					  0x7b, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x7d, 0x3e, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76,
 | 
				
			||||||
 | 
					  0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x74, 0x79,
 | 
				
			||||||
 | 
					  0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x72, 0x6f,
 | 
				
			||||||
 | 
					  0x77, 0x73, 0x3d, 0x32, 0x20, 0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x70, 0x72,
 | 
				
			||||||
 | 
					  0x65, 0x73, 0x73, 0x3d, 0x24, 0x7b, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x53,
 | 
				
			||||||
 | 
					  0x75, 0x62, 0x6d, 0x69, 0x74, 0x73, 0x7d, 0x20, 0x76, 0x61, 0x6c, 0x75,
 | 
				
			||||||
 | 
					  0x65, 0x3d, 0x22, 0x24, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
 | 
				
			||||||
 | 
					  0x7d, 0x22, 0x20, 0x6f, 0x6e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3d, 0x24,
 | 
				
			||||||
 | 
					  0x7b, 0x28, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x6d, 0x65, 0x73, 0x73,
 | 
				
			||||||
 | 
					  0x61, 0x67, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20,
 | 
				
			||||||
 | 
					  0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x76, 0x61, 0x6c,
 | 
				
			||||||
 | 
					  0x75, 0x65, 0x7d, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c,
 | 
				
			||||||
 | 
					  0x64, 0x65, 0x72, 0x3d, 0x22, 0x53, 0x61, 0x79, 0x20, 0x73, 0x6f, 0x6d,
 | 
				
			||||||
 | 
					  0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x2e, 0x2e, 0x22, 0x2f, 0x3e,
 | 
				
			||||||
 | 
					  0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c,
 | 
				
			||||||
 | 
					  0x61, 0x73, 0x73, 0x3d, 0x22, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d,
 | 
				
			||||||
 | 
					  0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x64, 0x69, 0x73,
 | 
				
			||||||
 | 
					  0x61, 0x62, 0x6c, 0x65, 0x64, 0x3d, 0x24, 0x7b, 0x21, 0x67, 0x65, 0x6e,
 | 
				
			||||||
 | 
					  0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x61, 0x6c, 0x75,
 | 
				
			||||||
 | 
					  0x65, 0x7d, 0x20, 0x3e, 0x53, 0x65, 0x6e, 0x64, 0x3c, 0x2f, 0x62, 0x75,
 | 
				
			||||||
 | 
					  0x74, 0x74, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x24, 0x7b, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x6f, 0x70, 0x7d, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64,
 | 
				
			||||||
 | 
					  0x3d, 0x24, 0x7b, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e,
 | 
				
			||||||
 | 
					  0x67, 0x7d, 0x3e, 0x53, 0x74, 0x6f, 0x70, 0x3c, 0x2f, 0x62, 0x75, 0x74,
 | 
				
			||||||
 | 
					  0x74, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x24, 0x7b, 0x72, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x65, 0x74, 0x7d, 0x3e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x3c, 0x2f, 0x62,
 | 
				
			||||||
 | 
					  0x75, 0x74, 0x74, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x66, 0x6f,
 | 
				
			||||||
 | 
					  0x72, 0x6d, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x73, 0x74, 0x20, 0x43, 0x68, 0x61, 0x74, 0x4c, 0x6f, 0x67,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x28, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x29, 0x20, 0x3d,
 | 
				
			||||||
 | 
					  0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x75, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72,
 | 
				
			||||||
 | 
					  0x69, 0x70, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
 | 
				
			||||||
 | 
					  0x65, 0x72, 0x20, 0x3d, 0x20, 0x75, 0x73, 0x65, 0x52, 0x65, 0x66, 0x28,
 | 
				
			||||||
 | 
					  0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x75, 0x73, 0x65, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x28,
 | 
				
			||||||
 | 
					  0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c,
 | 
				
			||||||
 | 
					  0x20, 0x74, 0x6f, 0x20, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x28,
 | 
				
			||||||
 | 
					  0x69, 0x66, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x29, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x63,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72,
 | 
				
			||||||
 | 
					  0x72, 0x65, 0x6e, 0x74, 0x20, 0x26, 0x26, 0x20, 0x63, 0x6f, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
 | 
				
			||||||
 | 
					  0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x48, 0x65, 0x69, 0x67,
 | 
				
			||||||
 | 
					  0x68, 0x74, 0x20, 0x3c, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
 | 
				
			||||||
 | 
					  0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2e,
 | 
				
			||||||
 | 
					  0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x70, 0x20, 0x2b, 0x20,
 | 
				
			||||||
 | 
					  0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75,
 | 
				
			||||||
 | 
					  0x72, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74,
 | 
				
			||||||
 | 
					  0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x2b, 0x20, 0x33, 0x30, 0x30,
 | 
				
			||||||
 | 
					  0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e,
 | 
				
			||||||
 | 
					  0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f,
 | 
				
			||||||
 | 
					  0x6c, 0x6c, 0x54, 0x6f, 0x28, 0x30, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74,
 | 
				
			||||||
 | 
					  0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
 | 
				
			||||||
 | 
					  0x74, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x48, 0x65, 0x69, 0x67,
 | 
				
			||||||
 | 
					  0x68, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x20, 0x5b,
 | 
				
			||||||
 | 
					  0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x5d, 0x29, 0x0a, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
 | 
				
			||||||
 | 
					  0x63, 0x68, 0x61, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x28,
 | 
				
			||||||
 | 
					  0x5b, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x6d, 0x73, 0x67, 0x5d, 0x29,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x74, 0x6d,
 | 
				
			||||||
 | 
					  0x6c, 0x60, 0x3c, 0x70, 0x20, 0x6b, 0x65, 0x79, 0x3d, 0x24, 0x7b, 0x6d,
 | 
				
			||||||
 | 
					  0x73, 0x67, 0x7d, 0x3e, 0x3c, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e,
 | 
				
			||||||
 | 
					  0x24, 0x7b, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x75,
 | 
				
			||||||
 | 
					  0x73, 0x65, 0x72, 0x29, 0x7d, 0x3a, 0x3c, 0x2f, 0x73, 0x74, 0x72, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x67, 0x3e, 0x20, 0x3c, 0x24, 0x7b, 0x4d, 0x61, 0x72, 0x6b, 0x64,
 | 
				
			||||||
 | 
					  0x6f, 0x77, 0x6e, 0x7d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x3d, 0x24, 0x7b,
 | 
				
			||||||
 | 
					  0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x6d, 0x73, 0x67,
 | 
				
			||||||
 | 
					  0x29, 0x7d, 0x20, 0x2f, 0x3e, 0x3c, 0x2f, 0x70, 0x3e, 0x60, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x74,
 | 
				
			||||||
 | 
					  0x6d, 0x6c, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x64, 0x3d,
 | 
				
			||||||
 | 
					  0x22, 0x63, 0x68, 0x61, 0x74, 0x22, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x24,
 | 
				
			||||||
 | 
					  0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x7d, 0x3e,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24,
 | 
				
			||||||
 | 
					  0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x66, 0x6c,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x4d, 0x61, 0x70, 0x28, 0x63, 0x68, 0x61, 0x74, 0x4c, 0x69,
 | 
				
			||||||
 | 
					  0x6e, 0x65, 0x29, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x3c, 0x2f, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x60,
 | 
				
			||||||
 | 
					  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x66,
 | 
				
			||||||
 | 
					  0x69, 0x67, 0x46, 0x6f, 0x72, 0x6d, 0x20, 0x3d, 0x20, 0x28, 0x70, 0x72,
 | 
				
			||||||
 | 
					  0x6f, 0x70, 0x73, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x75, 0x70,
 | 
				
			||||||
 | 
					  0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20,
 | 
				
			||||||
 | 
					  0x3d, 0x20, 0x28, 0x65, 0x6c, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x73, 0x65,
 | 
				
			||||||
 | 
					  0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20,
 | 
				
			||||||
 | 
					  0x3d, 0x20, 0x7b, 0x20, 0x2e, 0x2e, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x5b, 0x65,
 | 
				
			||||||
 | 
					  0x6c, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x6e, 0x61, 0x6d,
 | 
				
			||||||
 | 
					  0x65, 0x5d, 0x3a, 0x20, 0x65, 0x6c, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65,
 | 
				
			||||||
 | 
					  0x74, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x7d, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x75, 0x70,
 | 
				
			||||||
 | 
					  0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x20, 0x3d,
 | 
				
			||||||
 | 
					  0x20, 0x28, 0x65, 0x6c, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x70, 0x61, 0x72,
 | 
				
			||||||
 | 
					  0x61, 0x6d, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20,
 | 
				
			||||||
 | 
					  0x7b, 0x20, 0x2e, 0x2e, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e,
 | 
				
			||||||
 | 
					  0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x5b, 0x65, 0x6c, 0x2e, 0x74,
 | 
				
			||||||
 | 
					  0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x3a,
 | 
				
			||||||
 | 
					  0x20, 0x65, 0x6c, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x76,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x75, 0x65, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x46, 0x6c, 0x6f, 0x61, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x3d, 0x20, 0x28, 0x65, 0x6c, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x70,
 | 
				
			||||||
 | 
					  0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20,
 | 
				
			||||||
 | 
					  0x3d, 0x20, 0x7b, 0x20, 0x2e, 0x2e, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d,
 | 
				
			||||||
 | 
					  0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x5b, 0x65, 0x6c,
 | 
				
			||||||
 | 
					  0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65,
 | 
				
			||||||
 | 
					  0x5d, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61,
 | 
				
			||||||
 | 
					  0x74, 0x28, 0x65, 0x6c, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e,
 | 
				
			||||||
 | 
					  0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68,
 | 
				
			||||||
 | 
					  0x74, 0x6d, 0x6c, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x66, 0x69, 0x65, 0x6c, 0x64,
 | 
				
			||||||
 | 
					  0x73, 0x65, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x3c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d,
 | 
				
			||||||
 | 
					  0x22, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x22, 0x3e, 0x50, 0x72, 0x6f,
 | 
				
			||||||
 | 
					  0x6d, 0x70, 0x74, 0x3c, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3e, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x3c, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x20,
 | 
				
			||||||
 | 
					  0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20,
 | 
				
			||||||
 | 
					  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74,
 | 
				
			||||||
 | 
					  0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x24, 0x7b, 0x73,
 | 
				
			||||||
 | 
					  0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65,
 | 
				
			||||||
 | 
					  0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x7d, 0x22, 0x20, 0x72, 0x6f,
 | 
				
			||||||
 | 
					  0x77, 0x73, 0x3d, 0x34, 0x20, 0x6f, 0x6e, 0x69, 0x6e, 0x70, 0x75, 0x74,
 | 
				
			||||||
 | 
					  0x3d, 0x24, 0x7b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69,
 | 
				
			||||||
 | 
					  0x76, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x75, 0x73, 0x65, 0x72, 0x22, 0x3e, 0x55, 0x73, 0x65, 0x72, 0x20, 0x6e,
 | 
				
			||||||
 | 
					  0x61, 0x6d, 0x65, 0x3c, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3e, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70,
 | 
				
			||||||
 | 
					  0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x6e, 0x61, 0x6d,
 | 
				
			||||||
 | 
					  0x65, 0x3d, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x20, 0x76, 0x61, 0x6c,
 | 
				
			||||||
 | 
					  0x75, 0x65, 0x3d, 0x22, 0x24, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x75, 0x73, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x7d, 0x22, 0x20, 0x6f, 0x6e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3d, 0x24,
 | 
				
			||||||
 | 
					  0x7b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x7d, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76,
 | 
				
			||||||
 | 
					  0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22, 0x62,
 | 
				
			||||||
 | 
					  0x6f, 0x74, 0x22, 0x3e, 0x42, 0x6f, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65,
 | 
				
			||||||
 | 
					  0x3c, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x63, 0x68, 0x61, 0x72, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d,
 | 
				
			||||||
 | 
					  0x22, 0x24, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x75, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x7d, 0x22, 0x20,
 | 
				
			||||||
 | 
					  0x6f, 0x6e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3d, 0x24, 0x7b, 0x75, 0x70,
 | 
				
			||||||
 | 
					  0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x7d,
 | 
				
			||||||
 | 
					  0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x61, 0x62,
 | 
				
			||||||
 | 
					  0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22, 0x74, 0x65, 0x6d, 0x70,
 | 
				
			||||||
 | 
					  0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6c,
 | 
				
			||||||
 | 
					  0x61, 0x62, 0x65, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x65, 0x78,
 | 
				
			||||||
 | 
					  0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x65,
 | 
				
			||||||
 | 
					  0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65,
 | 
				
			||||||
 | 
					  0x3d, 0x22, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x20,
 | 
				
			||||||
 | 
					  0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x24, 0x7b, 0x73, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x7d, 0x22, 0x20, 0x72, 0x6f,
 | 
				
			||||||
 | 
					  0x77, 0x73, 0x3d, 0x34, 0x20, 0x6f, 0x6e, 0x69, 0x6e, 0x70, 0x75, 0x74,
 | 
				
			||||||
 | 
					  0x3d, 0x24, 0x7b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69,
 | 
				
			||||||
 | 
					  0x76, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, 0x43, 0x68,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x20, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x6c, 0x61, 0x62,
 | 
				
			||||||
 | 
					  0x65, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x65, 0x78, 0x74, 0x61,
 | 
				
			||||||
 | 
					  0x72, 0x65, 0x61, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x65, 0x6d, 0x70,
 | 
				
			||||||
 | 
					  0x6c, 0x61, 0x74, 0x65, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x6d, 0x70, 0x6c,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x65, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x24, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x61,
 | 
				
			||||||
 | 
					  0x6c, 0x75, 0x65, 0x2e, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x54,
 | 
				
			||||||
 | 
					  0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x7d, 0x22, 0x20, 0x72, 0x6f,
 | 
				
			||||||
 | 
					  0x77, 0x73, 0x3d, 0x31, 0x20, 0x6f, 0x6e, 0x69, 0x6e, 0x70, 0x75, 0x74,
 | 
				
			||||||
 | 
					  0x3d, 0x24, 0x7b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73,
 | 
				
			||||||
 | 
					  0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69,
 | 
				
			||||||
 | 
					  0x76, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22,
 | 
				
			||||||
 | 
					  0x3e, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x3c, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74,
 | 
				
			||||||
 | 
					  0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x20,
 | 
				
			||||||
 | 
					  0x6d, 0x69, 0x6e, 0x3d, 0x22, 0x30, 0x2e, 0x30, 0x22, 0x20, 0x6d, 0x61,
 | 
				
			||||||
 | 
					  0x78, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70,
 | 
				
			||||||
 | 
					  0x3d, 0x22, 0x30, 0x2e, 0x30, 0x31, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65,
 | 
				
			||||||
 | 
					  0x3d, 0x22, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72,
 | 
				
			||||||
 | 
					  0x65, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x24, 0x7b,
 | 
				
			||||||
 | 
					  0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65,
 | 
				
			||||||
 | 
					  0x2e, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x7d, 0x22, 0x20, 0x6f, 0x6e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3d, 0x24,
 | 
				
			||||||
 | 
					  0x7b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d,
 | 
				
			||||||
 | 
					  0x73, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x7d, 0x20, 0x2f, 0x3e, 0x0a, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x24, 0x7b, 0x70, 0x61, 0x72,
 | 
				
			||||||
 | 
					  0x61, 0x6d, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x74, 0x65,
 | 
				
			||||||
 | 
					  0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x7d, 0x3c, 0x2f,
 | 
				
			||||||
 | 
					  0x73, 0x70, 0x61, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e,
 | 
				
			||||||
 | 
					  0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6c,
 | 
				
			||||||
 | 
					  0x61, 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22, 0x6e, 0x50,
 | 
				
			||||||
 | 
					  0x72, 0x65, 0x64, 0x69, 0x63, 0x74, 0x22, 0x3e, 0x50, 0x72, 0x65, 0x64,
 | 
				
			||||||
 | 
					  0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x6c, 0x61, 0x62,
 | 
				
			||||||
 | 
					  0x65, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74,
 | 
				
			||||||
 | 
					  0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x72, 0x61, 0x6e, 0x67, 0x65,
 | 
				
			||||||
 | 
					  0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6e, 0x50, 0x72, 0x65, 0x64, 0x69,
 | 
				
			||||||
 | 
					  0x63, 0x74, 0x22, 0x20, 0x6d, 0x69, 0x6e, 0x3d, 0x22, 0x31, 0x22, 0x20,
 | 
				
			||||||
 | 
					  0x6d, 0x61, 0x78, 0x3d, 0x22, 0x32, 0x30, 0x34, 0x38, 0x22, 0x20, 0x73,
 | 
				
			||||||
 | 
					  0x74, 0x65, 0x70, 0x3d, 0x22, 0x31, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65,
 | 
				
			||||||
 | 
					  0x3d, 0x22, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x74, 0x22,
 | 
				
			||||||
 | 
					  0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x24, 0x7b, 0x70, 0x61,
 | 
				
			||||||
 | 
					  0x72, 0x61, 0x6d, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x6e,
 | 
				
			||||||
 | 
					  0x5f, 0x70, 0x72, 0x65, 0x64, 0x69, 0x63, 0x74, 0x7d, 0x22, 0x20, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3d, 0x24, 0x7b, 0x75, 0x70, 0x64,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x46, 0x6c, 0x6f,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x7d, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x73, 0x70,
 | 
				
			||||||
 | 
					  0x61, 0x6e, 0x3e, 0x24, 0x7b, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e,
 | 
				
			||||||
 | 
					  0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x64,
 | 
				
			||||||
 | 
					  0x69, 0x63, 0x74, 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76,
 | 
				
			||||||
 | 
					  0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x66,
 | 
				
			||||||
 | 
					  0x6f, 0x72, 0x3d, 0x22, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x70,
 | 
				
			||||||
 | 
					  0x65, 0x6e, 0x61, 0x6c, 0x74, 0x79, 0x22, 0x3e, 0x50, 0x65, 0x6e, 0x61,
 | 
				
			||||||
 | 
					  0x6c, 0x69, 0x7a, 0x65, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x20,
 | 
				
			||||||
 | 
					  0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x3c, 0x2f, 0x6c, 0x61,
 | 
				
			||||||
 | 
					  0x62, 0x65, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75,
 | 
				
			||||||
 | 
					  0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x72, 0x61, 0x6e, 0x67,
 | 
				
			||||||
 | 
					  0x65, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x72, 0x65, 0x70, 0x65, 0x61,
 | 
				
			||||||
 | 
					  0x74, 0x5f, 0x70, 0x65, 0x6e, 0x61, 0x6c, 0x74, 0x79, 0x22, 0x20, 0x6d,
 | 
				
			||||||
 | 
					  0x69, 0x6e, 0x3d, 0x22, 0x30, 0x2e, 0x30, 0x22, 0x20, 0x6d, 0x61, 0x78,
 | 
				
			||||||
 | 
					  0x3d, 0x22, 0x32, 0x2e, 0x30, 0x22, 0x20, 0x73, 0x74, 0x65, 0x70, 0x3d,
 | 
				
			||||||
 | 
					  0x22, 0x30, 0x2e, 0x30, 0x31, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d,
 | 
				
			||||||
 | 
					  0x22, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x70, 0x65, 0x6e, 0x61,
 | 
				
			||||||
 | 
					  0x6c, 0x74, 0x79, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x24, 0x7b, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x76, 0x61, 0x6c,
 | 
				
			||||||
 | 
					  0x75, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x70, 0x65,
 | 
				
			||||||
 | 
					  0x6e, 0x61, 0x6c, 0x74, 0x79, 0x7d, 0x22, 0x20, 0x6f, 0x6e, 0x69, 0x6e,
 | 
				
			||||||
 | 
					  0x70, 0x75, 0x74, 0x3d, 0x24, 0x7b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
 | 
				
			||||||
 | 
					  0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x7d,
 | 
				
			||||||
 | 
					  0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x3e,
 | 
				
			||||||
 | 
					  0x24, 0x7b, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x76, 0x61, 0x6c,
 | 
				
			||||||
 | 
					  0x75, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x70, 0x65,
 | 
				
			||||||
 | 
					  0x6e, 0x61, 0x6c, 0x74, 0x79, 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e,
 | 
				
			||||||
 | 
					  0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64,
 | 
				
			||||||
 | 
					  0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x61, 0x62, 0x65, 0x6c,
 | 
				
			||||||
 | 
					  0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74,
 | 
				
			||||||
 | 
					  0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x22, 0x3e, 0x43, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x73, 0x69, 0x64, 0x65, 0x72, 0x20, 0x4e, 0x20, 0x74, 0x6f, 0x6b, 0x65,
 | 
				
			||||||
 | 
					  0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x65, 0x6e, 0x61, 0x6c,
 | 
				
			||||||
 | 
					  0x69, 0x7a, 0x65, 0x3c, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3e, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70,
 | 
				
			||||||
 | 
					  0x65, 0x3d, 0x22, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x20, 0x69, 0x64,
 | 
				
			||||||
 | 
					  0x3d, 0x22, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x6c, 0x61, 0x73,
 | 
				
			||||||
 | 
					  0x74, 0x5f, 0x6e, 0x22, 0x20, 0x6d, 0x69, 0x6e, 0x3d, 0x22, 0x30, 0x2e,
 | 
				
			||||||
 | 
					  0x30, 0x22, 0x20, 0x6d, 0x61, 0x78, 0x3d, 0x22, 0x32, 0x30, 0x34, 0x38,
 | 
				
			||||||
 | 
					  0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x72, 0x65, 0x70, 0x65,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x22, 0x20, 0x76,
 | 
				
			||||||
 | 
					  0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x24, 0x7b, 0x70, 0x61, 0x72, 0x61,
 | 
				
			||||||
 | 
					  0x6d, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x72, 0x65, 0x70,
 | 
				
			||||||
 | 
					  0x65, 0x61, 0x74, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x7d, 0x22,
 | 
				
			||||||
 | 
					  0x20, 0x6f, 0x6e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3d, 0x24, 0x7b, 0x75,
 | 
				
			||||||
 | 
					  0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x46,
 | 
				
			||||||
 | 
					  0x6c, 0x6f, 0x61, 0x74, 0x7d, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x73, 0x70, 0x61, 0x6e, 0x3e, 0x24, 0x7b, 0x70, 0x61, 0x72, 0x61, 0x6d,
 | 
				
			||||||
 | 
					  0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x65,
 | 
				
			||||||
 | 
					  0x61, 0x74, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x7d, 0x3c, 0x2f,
 | 
				
			||||||
 | 
					  0x73, 0x70, 0x61, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e,
 | 
				
			||||||
 | 
					  0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x3e, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x66, 0x6f,
 | 
				
			||||||
 | 
					  0x72, 0x6d, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20,
 | 
				
			||||||
 | 
					  0x4d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x20, 0x3d, 0x20, 0x28,
 | 
				
			||||||
 | 
					  0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x7b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6d, 0x64, 0x20,
 | 
				
			||||||
 | 
					  0x3d, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x74, 0x65, 0x78,
 | 
				
			||||||
 | 
					  0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61,
 | 
				
			||||||
 | 
					  0x63, 0x65, 0x28, 0x2f, 0x5e, 0x23, 0x7b, 0x31, 0x2c, 0x36, 0x7d, 0x20,
 | 
				
			||||||
 | 
					  0x28, 0x2e, 0x2a, 0x29, 0x24, 0x2f, 0x67, 0x69, 0x6d, 0x2c, 0x20, 0x27,
 | 
				
			||||||
 | 
					  0x3c, 0x68, 0x33, 0x3e, 0x24, 0x31, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x27,
 | 
				
			||||||
 | 
					  0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61,
 | 
				
			||||||
 | 
					  0x63, 0x65, 0x28, 0x2f, 0x5c, 0x2a, 0x5c, 0x2a, 0x28, 0x2e, 0x2a, 0x3f,
 | 
				
			||||||
 | 
					  0x29, 0x5c, 0x2a, 0x5c, 0x2a, 0x2f, 0x67, 0x2c, 0x20, 0x27, 0x3c, 0x73,
 | 
				
			||||||
 | 
					  0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x24, 0x31, 0x3c, 0x2f, 0x73, 0x74,
 | 
				
			||||||
 | 
					  0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x5f, 0x5f,
 | 
				
			||||||
 | 
					  0x28, 0x2e, 0x2a, 0x3f, 0x29, 0x5f, 0x5f, 0x2f, 0x67, 0x2c, 0x20, 0x27,
 | 
				
			||||||
 | 
					  0x3c, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x24, 0x31, 0x3c, 0x2f,
 | 
				
			||||||
 | 
					  0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x27, 0x29, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f,
 | 
				
			||||||
 | 
					  0x5c, 0x2a, 0x28, 0x2e, 0x2a, 0x3f, 0x29, 0x5c, 0x2a, 0x2f, 0x67, 0x2c,
 | 
				
			||||||
 | 
					  0x20, 0x27, 0x3c, 0x65, 0x6d, 0x3e, 0x24, 0x31, 0x3c, 0x2f, 0x65, 0x6d,
 | 
				
			||||||
 | 
					  0x3e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x72, 0x65, 0x70,
 | 
				
			||||||
 | 
					  0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x5f, 0x28, 0x2e, 0x2a, 0x3f, 0x29,
 | 
				
			||||||
 | 
					  0x5f, 0x2f, 0x67, 0x2c, 0x20, 0x27, 0x3c, 0x65, 0x6d, 0x3e, 0x24, 0x31,
 | 
				
			||||||
 | 
					  0x3c, 0x2f, 0x65, 0x6d, 0x3e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x60, 0x60,
 | 
				
			||||||
 | 
					  0x60, 0x2e, 0x2a, 0x3f, 0x5c, 0x6e, 0x28, 0x5b, 0x5c, 0x73, 0x5c, 0x53,
 | 
				
			||||||
 | 
					  0x5d, 0x2a, 0x3f, 0x29, 0x60, 0x60, 0x60, 0x2f, 0x67, 0x2c, 0x20, 0x27,
 | 
				
			||||||
 | 
					  0x3c, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x24,
 | 
				
			||||||
 | 
					  0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x3c, 0x2f, 0x70, 0x72,
 | 
				
			||||||
 | 
					  0x65, 0x3e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x72, 0x65,
 | 
				
			||||||
 | 
					  0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x60, 0x28, 0x2e, 0x2a, 0x3f,
 | 
				
			||||||
 | 
					  0x29, 0x60, 0x2f, 0x67, 0x2c, 0x20, 0x27, 0x3c, 0x63, 0x6f, 0x64, 0x65,
 | 
				
			||||||
 | 
					  0x3e, 0x24, 0x31, 0x3c, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3e, 0x27, 0x29,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63,
 | 
				
			||||||
 | 
					  0x65, 0x28, 0x2f, 0x5c, 0x6e, 0x2f, 0x67, 0x69, 0x6d, 0x2c, 0x20, 0x27,
 | 
				
			||||||
 | 
					  0x3c, 0x62, 0x72, 0x20, 0x2f, 0x3e, 0x27, 0x29, 0x3b, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x60,
 | 
				
			||||||
 | 
					  0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x6f, 0x75, 0x73, 0x6c, 0x79, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x6e, 0x65,
 | 
				
			||||||
 | 
					  0x72, 0x48, 0x54, 0x4d, 0x4c, 0x3d, 0x24, 0x7b, 0x7b, 0x20, 0x5f, 0x5f,
 | 
				
			||||||
 | 
					  0x68, 0x74, 0x6d, 0x6c, 0x3a, 0x20, 0x6d, 0x64, 0x20, 0x7d, 0x7d, 0x20,
 | 
				
			||||||
 | 
					  0x2f, 0x3e, 0x60, 0x3b, 0x0a, 0x7d, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x70,
 | 
				
			||||||
 | 
					  0x70, 0x28, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x29, 0x20, 0x7b, 0x0a, 0x0a,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
 | 
				
			||||||
 | 
					  0x20, 0x68, 0x74, 0x6d, 0x6c, 0x60, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x63, 0x6f,
 | 
				
			||||||
 | 
					  0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x3e, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x65,
 | 
				
			||||||
 | 
					  0x72, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x3c, 0x68, 0x31, 0x3e, 0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x63,
 | 
				
			||||||
 | 
					  0x70, 0x70, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x6d, 0x61, 0x69, 0x6e, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x63, 0x6f, 0x6e,
 | 
				
			||||||
 | 
					  0x74, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x24, 0x7b, 0x63, 0x68, 0x61, 0x74,
 | 
				
			||||||
 | 
					  0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x76, 0x61, 0x6c, 0x75,
 | 
				
			||||||
 | 
					  0x65, 0x20, 0x3f, 0x20, 0x43, 0x68, 0x61, 0x74, 0x4c, 0x6f, 0x67, 0x20,
 | 
				
			||||||
 | 
					  0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x6f, 0x72, 0x6d,
 | 
				
			||||||
 | 
					  0x7d, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x3c, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x3e, 0x0a, 0x0a, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x66, 0x6f, 0x6f, 0x74, 0x65,
 | 
				
			||||||
 | 
					  0x72, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x77, 0x72, 0x69, 0x74, 0x65, 0x22,
 | 
				
			||||||
 | 
					  0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x3c, 0x24, 0x7b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e,
 | 
				
			||||||
 | 
					  0x70, 0x75, 0x74, 0x7d, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72,
 | 
				
			||||||
 | 
					  0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c,
 | 
				
			||||||
 | 
					  0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x70, 0x3e, 0x50, 0x6f, 0x77,
 | 
				
			||||||
 | 
					  0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x3c, 0x61, 0x20, 0x68,
 | 
				
			||||||
 | 
					  0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
 | 
				
			||||||
 | 
					  0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
 | 
				
			||||||
 | 
					  0x67, 0x67, 0x65, 0x72, 0x67, 0x61, 0x6e, 0x6f, 0x76, 0x2f, 0x6c, 0x6c,
 | 
				
			||||||
 | 
					  0x61, 0x6d, 0x61, 0x2e, 0x63, 0x70, 0x70, 0x22, 0x3e, 0x6c, 0x6c, 0x61,
 | 
				
			||||||
 | 
					  0x6d, 0x61, 0x2e, 0x63, 0x70, 0x70, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x61,
 | 
				
			||||||
 | 
					  0x6e, 0x64, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22,
 | 
				
			||||||
 | 
					  0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x67, 0x6d, 0x6c,
 | 
				
			||||||
 | 
					  0x2e, 0x61, 0x69, 0x22, 0x3e, 0x67, 0x67, 0x6d, 0x6c, 0x2e, 0x61, 0x69,
 | 
				
			||||||
 | 
					  0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x70, 0x3e, 0x0a, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65,
 | 
				
			||||||
 | 
					  0x72, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64,
 | 
				
			||||||
 | 
					  0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x3b,
 | 
				
			||||||
 | 
					  0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
 | 
				
			||||||
 | 
					  0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x68, 0x28, 0x41, 0x70, 0x70,
 | 
				
			||||||
 | 
					  0x29, 0x2c, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
 | 
				
			||||||
 | 
					  0x62, 0x6f, 0x64, 0x79, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x3c, 0x2f, 0x73,
 | 
				
			||||||
 | 
					  0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x68, 0x65, 0x61,
 | 
				
			||||||
 | 
					  0x64, 0x3e, 0x0a, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c,
 | 
				
			||||||
 | 
					  0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x0a, 0x3c, 0x2f, 0x68, 0x74,
 | 
				
			||||||
 | 
					  0x6d, 0x6c, 0x3e, 0x0a
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					unsigned int index_html_len = 10108;
 | 
				
			||||||
							
								
								
									
										1851
									
								
								examples/server/index.js.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1851
									
								
								examples/server/index.js.hpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										81
									
								
								examples/server/public/completion.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								examples/server/public/completion.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					const paramDefaults = {
 | 
				
			||||||
 | 
					  stream: true,
 | 
				
			||||||
 | 
					  n_predict: 500,
 | 
				
			||||||
 | 
					  temperature: 0.2,
 | 
				
			||||||
 | 
					  stop: ["</s>"]
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This function completes the input text using a llama dictionary.
 | 
				
			||||||
 | 
					 * @param {object} params - The parameters for the completion request.
 | 
				
			||||||
 | 
					 * @param {object} controller - an instance of AbortController if you need one, or null.
 | 
				
			||||||
 | 
					 * @param {function} callback - The callback function to call when the completion is done.
 | 
				
			||||||
 | 
					 * @returns {string} the completed text as a string. Ideally ignored, and you get at it via the callback.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const llamaComplete = async (params, controller, callback) => {
 | 
				
			||||||
 | 
					  if (!controller) {
 | 
				
			||||||
 | 
					    controller = new AbortController();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const completionParams = { ...paramDefaults, ...params };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // we use fetch directly here becasue the built in fetchEventSource does not support POST
 | 
				
			||||||
 | 
					  const response = await fetch("/completion", {
 | 
				
			||||||
 | 
					    method: 'POST',
 | 
				
			||||||
 | 
					    body: JSON.stringify(completionParams),
 | 
				
			||||||
 | 
					    headers: {
 | 
				
			||||||
 | 
					      'Connection': 'keep-alive',
 | 
				
			||||||
 | 
					      'Content-Type': 'application/json',
 | 
				
			||||||
 | 
					      'Accept': 'text/event-stream'
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    signal: controller.signal,
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const reader = response.body.getReader();
 | 
				
			||||||
 | 
					  const decoder = new TextDecoder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let content = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let cont = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (cont) {
 | 
				
			||||||
 | 
					      const result = await reader.read();
 | 
				
			||||||
 | 
					      if (result.done) {
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // sse answers in the form multiple lines of: value\n with data always present as a key. in our case we
 | 
				
			||||||
 | 
					      // mainly care about the data: key here, which we expect as json
 | 
				
			||||||
 | 
					      const text = decoder.decode(result.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // parse all sse events and add them to result
 | 
				
			||||||
 | 
					      const regex = /^(\S+):\s(.*)$/gm;
 | 
				
			||||||
 | 
					      for (const match of text.matchAll(regex)) {
 | 
				
			||||||
 | 
					        result[match[1]] = match[2]
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // since we know this is llama.cpp, let's just decode the json in data
 | 
				
			||||||
 | 
					      result.data = JSON.parse(result.data);
 | 
				
			||||||
 | 
					      content += result.data.content;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // callack
 | 
				
			||||||
 | 
					      if (callback) {
 | 
				
			||||||
 | 
					        cont = callback(result) != false;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // if we got a stop token from server, we will break here
 | 
				
			||||||
 | 
					      if (result.data.stop) {
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } catch (e) {
 | 
				
			||||||
 | 
					    console.error("llama error: ", e);
 | 
				
			||||||
 | 
					    throw e;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  finally {
 | 
				
			||||||
 | 
					    controller.abort();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return content;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										359
									
								
								examples/server/public/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										359
									
								
								examples/server/public/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,359 @@
 | 
				
			|||||||
 | 
					<html>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
 | 
				
			||||||
 | 
					  <title>llama.cpp - chat</title>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    body {
 | 
				
			||||||
 | 
					      background-color: #fff;
 | 
				
			||||||
 | 
					      color: #000;
 | 
				
			||||||
 | 
					      font-family: system-ui;
 | 
				
			||||||
 | 
					      font-size: 90%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #container {
 | 
				
			||||||
 | 
					      margin: 0em auto;
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      flex-direction: column;
 | 
				
			||||||
 | 
					      justify-content: space-between;
 | 
				
			||||||
 | 
					      height: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    header, footer {
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    main {
 | 
				
			||||||
 | 
					      margin: 3px;
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      flex-direction: column;
 | 
				
			||||||
 | 
					      justify-content: space-between;
 | 
				
			||||||
 | 
					      gap: 1em;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      flex-grow: 1;
 | 
				
			||||||
 | 
					      overflow-y: auto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      border: 1px solid #ccc;
 | 
				
			||||||
 | 
					      border-radius: 5px;
 | 
				
			||||||
 | 
					      padding: 0.5em;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    body {
 | 
				
			||||||
 | 
					      max-width: 600px;
 | 
				
			||||||
 | 
					      min-width: 300px;
 | 
				
			||||||
 | 
					      line-height: 1.2;
 | 
				
			||||||
 | 
					      margin: 0 auto;
 | 
				
			||||||
 | 
					      padding: 0 0.5em;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    p {
 | 
				
			||||||
 | 
					      overflow-wrap: break-word;
 | 
				
			||||||
 | 
					      word-wrap: break-word;
 | 
				
			||||||
 | 
					      hyphens: auto;
 | 
				
			||||||
 | 
					      margin-top: 0.5em;
 | 
				
			||||||
 | 
					      margin-bottom: 0.5em;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #write form {
 | 
				
			||||||
 | 
					      margin: 1em 0 0 0;
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      flex-direction: column;
 | 
				
			||||||
 | 
					      gap: 0.5em;
 | 
				
			||||||
 | 
					      align-items: stretch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .right {
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      flex-direction: row;
 | 
				
			||||||
 | 
					      gap: 0.5em;
 | 
				
			||||||
 | 
					      justify-content: flex-end;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fieldset {
 | 
				
			||||||
 | 
					      border: none;
 | 
				
			||||||
 | 
					      padding: 0;
 | 
				
			||||||
 | 
					      margin: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    textarea {
 | 
				
			||||||
 | 
					      padding: 5px;
 | 
				
			||||||
 | 
					      flex-grow: 1;
 | 
				
			||||||
 | 
					      width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pre code {
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					      background-color: #222;
 | 
				
			||||||
 | 
					      color: #ddd;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    code {
 | 
				
			||||||
 | 
					      font-family: monospace;
 | 
				
			||||||
 | 
					      padding: 0.1em 0.3em;
 | 
				
			||||||
 | 
					      border-radius: 3px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fieldset label {
 | 
				
			||||||
 | 
					      margin: 0.5em 0;
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <script type="module">
 | 
				
			||||||
 | 
					    import {
 | 
				
			||||||
 | 
					      html, h, signal, effect, computed, render, useSignal, useEffect, useRef
 | 
				
			||||||
 | 
					    } from '/index.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    import { llamaComplete } from '/completion.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const session = signal({
 | 
				
			||||||
 | 
					      prompt: "This is a conversation between user and llama, a friendly chatbot. respond in markdown.",
 | 
				
			||||||
 | 
					      template: "{{prompt}}\n\n{{history}}\n{{char}}:",
 | 
				
			||||||
 | 
					      historyTemplate: "{{name}}: {{message}}",
 | 
				
			||||||
 | 
					      transcript: [],
 | 
				
			||||||
 | 
					      type: "chat",
 | 
				
			||||||
 | 
					      char: "llama",
 | 
				
			||||||
 | 
					      user: "User",
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const transcriptUpdate = (transcript) => {
 | 
				
			||||||
 | 
					      session.value = {
 | 
				
			||||||
 | 
					        ...session.value,
 | 
				
			||||||
 | 
					        transcript
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const chatStarted = computed(() => session.value.transcript.length > 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const params = signal({
 | 
				
			||||||
 | 
					      n_predict: 400,
 | 
				
			||||||
 | 
					      temperature: 0.7,
 | 
				
			||||||
 | 
					      repeat_last_n: 256,
 | 
				
			||||||
 | 
					      repeat_penalty: 1.18,
 | 
				
			||||||
 | 
					      top_k: 40,
 | 
				
			||||||
 | 
					      top_p: 0.5,
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const controller = signal(null)
 | 
				
			||||||
 | 
					    const generating = computed(() => controller.value == null )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // simple template replace
 | 
				
			||||||
 | 
					    const template = (str, extraSettings) => {
 | 
				
			||||||
 | 
					      let settings = session.value;
 | 
				
			||||||
 | 
					      if (extraSettings) {
 | 
				
			||||||
 | 
					        settings = { ...settings, ...extraSettings };
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return String(str).replaceAll(/\{\{(.*?)\}\}/g, (_, key) => template(settings[key]));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // send message to server
 | 
				
			||||||
 | 
					    const chat = async (msg) => {
 | 
				
			||||||
 | 
					      if (controller.value) {
 | 
				
			||||||
 | 
					        console.log('already running...');
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      controller.value = new AbortController();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      transcriptUpdate([...session.value.transcript, ["{{user}}", msg]])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const payload = template(session.value.template, {
 | 
				
			||||||
 | 
					        message: msg,
 | 
				
			||||||
 | 
					        history: session.value.transcript.flatMap(([name, message]) => template(session.value.historyTemplate, {name, message})).join("\n"),
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let currentMessage = '';
 | 
				
			||||||
 | 
					      const history = session.value.transcript
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const llamaParams = {
 | 
				
			||||||
 | 
					        ...params.value,
 | 
				
			||||||
 | 
					        prompt: payload,
 | 
				
			||||||
 | 
					        stop: ["</s>", template("{{char}}:"), template("{{user}}:")],
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await llamaComplete(llamaParams, controller.value, (message) => {
 | 
				
			||||||
 | 
					        const data = message.data;
 | 
				
			||||||
 | 
					        currentMessage += data.content;
 | 
				
			||||||
 | 
					        // remove leading whitespace
 | 
				
			||||||
 | 
					        currentMessage = currentMessage.replace(/^\s+/, "")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        transcriptUpdate([...history, ["{{char}}", currentMessage]])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (data.stop) {
 | 
				
			||||||
 | 
					          console.log("-->", data, ' response was:', currentMessage, 'transcript state:', session.value.transcript);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      controller.value = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function MessageInput() {
 | 
				
			||||||
 | 
					      const message = useSignal("")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const stop = (e) => {
 | 
				
			||||||
 | 
					        e.preventDefault();
 | 
				
			||||||
 | 
					        if (controller.value) {
 | 
				
			||||||
 | 
					          controller.value.abort();
 | 
				
			||||||
 | 
					          controller.value = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const reset = (e) => {
 | 
				
			||||||
 | 
					        stop(e);
 | 
				
			||||||
 | 
					        transcriptUpdate([]);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const submit = (e) => {
 | 
				
			||||||
 | 
					        stop(e);
 | 
				
			||||||
 | 
					        chat(message.value);
 | 
				
			||||||
 | 
					        message.value = "";
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const enterSubmits = (event) => {
 | 
				
			||||||
 | 
					        if (event.which === 13 && !event.shiftKey) {
 | 
				
			||||||
 | 
					          submit(event);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return html`
 | 
				
			||||||
 | 
					        <form onsubmit=${submit}>
 | 
				
			||||||
 | 
					          <div>
 | 
				
			||||||
 | 
					          <textarea type="text" rows=2 onkeypress=${enterSubmits} value="${message}" oninput=${(e) => message.value = e.target.value} placeholder="Say something..."/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div class="right">
 | 
				
			||||||
 | 
					          <button type="submit" disabled=${!generating.value} >Send</button>
 | 
				
			||||||
 | 
					          <button onclick=${stop} disabled=${generating}>Stop</button>
 | 
				
			||||||
 | 
					          <button onclick=${reset}>Reset</button>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					      `
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const ChatLog = (props) => {
 | 
				
			||||||
 | 
					      const messages = session.value.transcript;
 | 
				
			||||||
 | 
					      const container = useRef(null)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      useEffect(() => {
 | 
				
			||||||
 | 
					        // scroll to bottom (if needed)
 | 
				
			||||||
 | 
					        if (container.current && container.current.scrollHeight <= container.current.scrollTop + container.current.offsetHeight + 300) {
 | 
				
			||||||
 | 
					          container.current.scrollTo(0, container.current.scrollHeight)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }, [messages])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const chatLine = ([user, msg]) => {
 | 
				
			||||||
 | 
					        return html`<p key=${msg}><strong>${template(user)}:</strong> <${Markdown} text=${template(msg)} /></p>`
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return html`
 | 
				
			||||||
 | 
					        <section id="chat" ref=${container}>
 | 
				
			||||||
 | 
					          ${messages.flatMap(chatLine)}
 | 
				
			||||||
 | 
					        </section>`;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const ConfigForm = (props) => {
 | 
				
			||||||
 | 
					      const updateSession = (el) => session.value = { ...session.value, [el.target.name]: el.target.value }
 | 
				
			||||||
 | 
					      const updateParams = (el) => params.value = { ...params.value, [el.target.name]: el.target.value }
 | 
				
			||||||
 | 
					      const updateParamsFloat = (el) => params.value = { ...params.value, [el.target.name]: parseFloat(el.target.value) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return html`
 | 
				
			||||||
 | 
					        <form>
 | 
				
			||||||
 | 
					          <fieldset>
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <label for="prompt">Prompt</label>
 | 
				
			||||||
 | 
					              <textarea type="text" name="prompt" value="${session.value.prompt}" rows=4 oninput=${updateSession}/>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <label for="user">User name</label>
 | 
				
			||||||
 | 
					              <input type="text" name="user" value="${session.value.user}" oninput=${updateSession} />
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <label for="bot">Bot name</label>
 | 
				
			||||||
 | 
					              <input type="text" name="char" value="${session.value.char}" oninput=${updateSession} />
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <label for="template">Prompt template</label>
 | 
				
			||||||
 | 
					              <textarea id="template" name="template" value="${session.value.template}" rows=4 oninput=${updateSession}/>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <label for="template">Chat history template</label>
 | 
				
			||||||
 | 
					              <textarea id="template" name="historyTemplate" value="${session.value.historyTemplate}" rows=1 oninput=${updateSession}/>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <label for="temperature">Temperature</label>
 | 
				
			||||||
 | 
					              <input type="range" id="temperature" min="0.0" max="1.0" step="0.01" name="temperature" value="${params.value.temperature}" oninput=${updateParamsFloat} />
 | 
				
			||||||
 | 
					              <span>${params.value.temperature}</span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <label for="nPredict">Predictions</label>
 | 
				
			||||||
 | 
					              <input type="range" id="nPredict" min="1" max="2048" step="1" name="n_predict" value="${params.value.n_predict}" oninput=${updateParamsFloat} />
 | 
				
			||||||
 | 
					              <span>${params.value.n_predict}</span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <label for="repeat_penalty">Penalize repeat sequence</label>
 | 
				
			||||||
 | 
					              <input type="range" id="repeat_penalty" min="0.0" max="2.0" step="0.01" name="repeat_penalty" value="${params.value.repeat_penalty}" oninput=${updateParamsFloat} />
 | 
				
			||||||
 | 
					              <span>${params.value.repeat_penalty}</span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <label for="repeat_last_n">Consider N tokens for penalize</label>
 | 
				
			||||||
 | 
					              <input type="range" id="repeat_last_n" min="0.0" max="2048" name="repeat_last_n" value="${params.value.repeat_last_n}" oninput=${updateParamsFloat} />
 | 
				
			||||||
 | 
					              <span>${params.value.repeat_last_n}</span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          </fieldset>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					      `
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					const Markdown = (params) => {
 | 
				
			||||||
 | 
					  const md = params.text
 | 
				
			||||||
 | 
					    .replace(/^#{1,6} (.*)$/gim, '<h3>$1</h3>')
 | 
				
			||||||
 | 
					    .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
 | 
				
			||||||
 | 
					    .replace(/__(.*?)__/g, '<strong>$1</strong>')
 | 
				
			||||||
 | 
					    .replace(/\*(.*?)\*/g, '<em>$1</em>')
 | 
				
			||||||
 | 
					    .replace(/_(.*?)_/g, '<em>$1</em>')
 | 
				
			||||||
 | 
					    .replace(/```.*?\n([\s\S]*?)```/g, '<pre><code>$1</code></pre>')
 | 
				
			||||||
 | 
					    .replace(/`(.*?)`/g, '<code>$1</code>')
 | 
				
			||||||
 | 
					    .replace(/\n/gim, '<br />');
 | 
				
			||||||
 | 
					  return html`<span dangerouslySetInnerHTML=${{ __html: md }} />`;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function App(props) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return html`
 | 
				
			||||||
 | 
					      <div id="container">
 | 
				
			||||||
 | 
					        <header>
 | 
				
			||||||
 | 
					          <h1>llama.cpp</h1>
 | 
				
			||||||
 | 
					        </header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <main id="content">
 | 
				
			||||||
 | 
					          <${chatStarted.value ? ChatLog : ConfigForm} />
 | 
				
			||||||
 | 
					        </main>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <footer id="write">
 | 
				
			||||||
 | 
					          <${MessageInput} />
 | 
				
			||||||
 | 
					        </footer>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <footer>
 | 
				
			||||||
 | 
					          <p>Powered by <a href="https://github.com/ggerganov/llama.cpp">llama.cpp</a> and <a href="https://ggml.ai">ggml.ai</a></p>
 | 
				
			||||||
 | 
					        </footer>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      `;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render(h(App), document.body);
 | 
				
			||||||
 | 
					  </script>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										1
									
								
								examples/server/public/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								examples/server/public/index.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -2,8 +2,6 @@
 | 
				
			|||||||
#include "llama.h"
 | 
					#include "llama.h"
 | 
				
			||||||
#include "build-info.h"
 | 
					#include "build-info.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// single thread
 | 
					 | 
				
			||||||
#define CPPHTTPLIB_THREAD_POOL_COUNT 1
 | 
					 | 
				
			||||||
#ifndef NDEBUG
 | 
					#ifndef NDEBUG
 | 
				
			||||||
// crash the server in debug mode, otherwise send an http 500 error
 | 
					// crash the server in debug mode, otherwise send an http 500 error
 | 
				
			||||||
#define CPPHTTPLIB_NO_EXCEPTIONS 1
 | 
					#define CPPHTTPLIB_NO_EXCEPTIONS 1
 | 
				
			||||||
@@ -12,6 +10,11 @@
 | 
				
			|||||||
#include "httplib.h"
 | 
					#include "httplib.h"
 | 
				
			||||||
#include "json.hpp"
 | 
					#include "json.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// auto generated files (update with ./deps.sh)
 | 
				
			||||||
 | 
					#include "index.html.hpp"
 | 
				
			||||||
 | 
					#include "index.js.hpp"
 | 
				
			||||||
 | 
					#include "completion.js.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef SERVER_VERBOSE
 | 
					#ifndef SERVER_VERBOSE
 | 
				
			||||||
#define SERVER_VERBOSE 1
 | 
					#define SERVER_VERBOSE 1
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -21,11 +24,23 @@ using json = nlohmann::json;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct server_params {
 | 
					struct server_params {
 | 
				
			||||||
    std::string hostname = "127.0.0.1";
 | 
					    std::string hostname = "127.0.0.1";
 | 
				
			||||||
 | 
					    std::string public_path = "examples/server/public";
 | 
				
			||||||
    int32_t port = 8080;
 | 
					    int32_t port = 8080;
 | 
				
			||||||
    int32_t read_timeout = 600;
 | 
					    int32_t read_timeout = 600;
 | 
				
			||||||
    int32_t write_timeout = 600;
 | 
					    int32_t write_timeout = 600;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// completion token output with probabilities
 | 
				
			||||||
 | 
					struct completion_token_output {
 | 
				
			||||||
 | 
					    struct token_prob {
 | 
				
			||||||
 | 
					        llama_token tok;
 | 
				
			||||||
 | 
					        float prob;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<token_prob> probs;
 | 
				
			||||||
 | 
					    llama_token tok;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static size_t common_part(const std::vector<llama_token> & a, const std::vector<llama_token> & b) {
 | 
					static size_t common_part(const std::vector<llama_token> & a, const std::vector<llama_token> & b) {
 | 
				
			||||||
    size_t i;
 | 
					    size_t i;
 | 
				
			||||||
    for (i = 0; i < a.size() && i < b.size() && a[i] == b[i]; i++) {}
 | 
					    for (i = 0; i < a.size() && i < b.size() && a[i] == b[i]; i++) {}
 | 
				
			||||||
@@ -86,6 +101,40 @@ static void server_log(const char * level, const char * function, int line,
 | 
				
			|||||||
    fflush(stdout);
 | 
					    fflush(stdout);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// format incomplete utf-8 multibyte character for output
 | 
				
			||||||
 | 
					static std::string tokens_to_output_formatted_string(const llama_context * ctx, const llama_token token) {
 | 
				
			||||||
 | 
					    std::string out = token == -1 ? "" : llama_token_to_str(ctx, token);
 | 
				
			||||||
 | 
					    // if first bit is 1, meaning it's a partial character
 | 
				
			||||||
 | 
					    if (out.size() > 0 && (out[0] & 0x80) == 0x80) {
 | 
				
			||||||
 | 
					        std::stringstream ss;
 | 
				
			||||||
 | 
					        ss<< std::hex << (out[0] & 0xff);
 | 
				
			||||||
 | 
					        std::string res ( ss.str() );
 | 
				
			||||||
 | 
					        out = "byte: \\x" + res;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// convert a vector of completion_token_output to json
 | 
				
			||||||
 | 
					static json probs_vector_to_json(const llama_context * ctx, const std::vector<completion_token_output> probs) {
 | 
				
			||||||
 | 
					    json out = json::array();
 | 
				
			||||||
 | 
					    for (const auto & prob : probs) {
 | 
				
			||||||
 | 
					        json probs_for_token = json::array();
 | 
				
			||||||
 | 
					        for (const auto & p : prob.probs) {
 | 
				
			||||||
 | 
					            std::string tok_str = tokens_to_output_formatted_string(ctx, p.tok);
 | 
				
			||||||
 | 
					            probs_for_token.push_back(json {
 | 
				
			||||||
 | 
					                { "tok_str", tok_str },
 | 
				
			||||||
 | 
					                { "prob", p.prob },
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        std::string tok_str = tokens_to_output_formatted_string(ctx, prob.tok);
 | 
				
			||||||
 | 
					        out.push_back(json {
 | 
				
			||||||
 | 
					            {"content", tok_str},
 | 
				
			||||||
 | 
					            {"probs", probs_for_token},
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool server_verbose = false;
 | 
					static bool server_verbose = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if SERVER_VERBOSE != 1
 | 
					#if SERVER_VERBOSE != 1
 | 
				
			||||||
@@ -107,7 +156,9 @@ struct llama_server_context {
 | 
				
			|||||||
    bool stream = false;
 | 
					    bool stream = false;
 | 
				
			||||||
    bool has_next_token = false;
 | 
					    bool has_next_token = false;
 | 
				
			||||||
    std::string generated_text;
 | 
					    std::string generated_text;
 | 
				
			||||||
 | 
					    std::vector<completion_token_output> generated_token_probs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t num_prompt_tokens = 0;
 | 
				
			||||||
    size_t num_tokens_predicted = 0;
 | 
					    size_t num_tokens_predicted = 0;
 | 
				
			||||||
    size_t n_past = 0;
 | 
					    size_t n_past = 0;
 | 
				
			||||||
    size_t n_remain = 0;
 | 
					    size_t n_remain = 0;
 | 
				
			||||||
@@ -126,6 +177,12 @@ struct llama_server_context {
 | 
				
			|||||||
    std::string stopping_word;
 | 
					    std::string stopping_word;
 | 
				
			||||||
    int32_t multibyte_pending = 0;
 | 
					    int32_t multibyte_pending = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::mutex mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::unique_lock<std::mutex> lock() {
 | 
				
			||||||
 | 
					        return std::unique_lock<std::mutex>(mutex);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ~llama_server_context() {
 | 
					    ~llama_server_context() {
 | 
				
			||||||
        if (ctx) {
 | 
					        if (ctx) {
 | 
				
			||||||
            llama_free(ctx);
 | 
					            llama_free(ctx);
 | 
				
			||||||
@@ -139,9 +196,11 @@ struct llama_server_context {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void rewind() {
 | 
					    void rewind() {
 | 
				
			||||||
        params.antiprompt.clear();
 | 
					        params.antiprompt.clear();
 | 
				
			||||||
 | 
					        num_prompt_tokens = 0;
 | 
				
			||||||
        num_tokens_predicted = 0;
 | 
					        num_tokens_predicted = 0;
 | 
				
			||||||
        generated_text = "";
 | 
					        generated_text = "";
 | 
				
			||||||
        generated_text.reserve(params.n_ctx);
 | 
					        generated_text.reserve(params.n_ctx);
 | 
				
			||||||
 | 
					        generated_token_probs.clear();
 | 
				
			||||||
        truncated = false;
 | 
					        truncated = false;
 | 
				
			||||||
        stopped_eos = false;
 | 
					        stopped_eos = false;
 | 
				
			||||||
        stopped_word = false;
 | 
					        stopped_word = false;
 | 
				
			||||||
@@ -169,17 +228,18 @@ struct llama_server_context {
 | 
				
			|||||||
    void loadPrompt() {
 | 
					    void loadPrompt() {
 | 
				
			||||||
        params.prompt.insert(0, 1, ' '); // always add a first space
 | 
					        params.prompt.insert(0, 1, ' '); // always add a first space
 | 
				
			||||||
        std::vector<llama_token> prompt_tokens = ::llama_tokenize(ctx, params.prompt, true);
 | 
					        std::vector<llama_token> prompt_tokens = ::llama_tokenize(ctx, params.prompt, true);
 | 
				
			||||||
 | 
					        num_prompt_tokens = prompt_tokens.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (params.n_keep < 0) {
 | 
					        if (params.n_keep < 0) {
 | 
				
			||||||
            params.n_keep = (int)prompt_tokens.size();
 | 
					            params.n_keep = (int)num_prompt_tokens;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        params.n_keep = std::min(params.n_ctx - 4, params.n_keep);
 | 
					        params.n_keep = std::min(params.n_ctx - 4, params.n_keep);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // if input prompt is too big, truncate like normal
 | 
					        // if input prompt is too big, truncate like normal
 | 
				
			||||||
        if (prompt_tokens.size() >= (size_t)params.n_ctx) {
 | 
					        if (num_prompt_tokens>= (size_t)params.n_ctx) {
 | 
				
			||||||
            const int n_left = (params.n_ctx - params.n_keep) / 2;
 | 
					            const int n_left = (params.n_ctx - params.n_keep) / 2;
 | 
				
			||||||
            std::vector<llama_token> new_tokens(prompt_tokens.begin(), prompt_tokens.begin() + params.n_keep);
 | 
					            std::vector<llama_token> new_tokens(prompt_tokens.begin(), prompt_tokens.begin() + params.n_keep);
 | 
				
			||||||
            const int erased_blocks = (prompt_tokens.size() - params.n_keep - n_left - 1) / n_left;
 | 
					            const int erased_blocks = (num_prompt_tokens - params.n_keep - n_left - 1) / n_left;
 | 
				
			||||||
            new_tokens.insert(new_tokens.end(), prompt_tokens.begin() + params.n_keep + erased_blocks * n_left, prompt_tokens.end());
 | 
					            new_tokens.insert(new_tokens.end(), prompt_tokens.begin() + params.n_keep + erased_blocks * n_left, prompt_tokens.end());
 | 
				
			||||||
            std::copy(prompt_tokens.end() - params.n_ctx, prompt_tokens.end(), last_n_tokens.begin());
 | 
					            std::copy(prompt_tokens.end() - params.n_ctx, prompt_tokens.end(), last_n_tokens.begin());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -193,7 +253,7 @@ struct llama_server_context {
 | 
				
			|||||||
            truncated = true;
 | 
					            truncated = true;
 | 
				
			||||||
            prompt_tokens = new_tokens;
 | 
					            prompt_tokens = new_tokens;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            const size_t ps = prompt_tokens.size();
 | 
					            const size_t ps = num_prompt_tokens;
 | 
				
			||||||
            std::fill(last_n_tokens.begin(), last_n_tokens.end() - ps, 0);
 | 
					            std::fill(last_n_tokens.begin(), last_n_tokens.end() - ps, 0);
 | 
				
			||||||
            std::copy(prompt_tokens.begin(), prompt_tokens.end(), last_n_tokens.end() - ps);
 | 
					            std::copy(prompt_tokens.begin(), prompt_tokens.end(), last_n_tokens.end() - ps);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -201,7 +261,7 @@ struct llama_server_context {
 | 
				
			|||||||
        // compare the evaluated prompt with the new prompt
 | 
					        // compare the evaluated prompt with the new prompt
 | 
				
			||||||
        n_past = common_part(embd, prompt_tokens);
 | 
					        n_past = common_part(embd, prompt_tokens);
 | 
				
			||||||
        embd = prompt_tokens;
 | 
					        embd = prompt_tokens;
 | 
				
			||||||
        if (n_past == prompt_tokens.size()) {
 | 
					        if (n_past == num_prompt_tokens) {
 | 
				
			||||||
            // we have to evaluate at least 1 token to generate logits.
 | 
					            // we have to evaluate at least 1 token to generate logits.
 | 
				
			||||||
            n_past--;
 | 
					            n_past--;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -221,8 +281,9 @@ struct llama_server_context {
 | 
				
			|||||||
        llama_set_rng_seed(ctx, params.seed);
 | 
					        llama_set_rng_seed(ctx, params.seed);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    llama_token nextToken() {
 | 
					    completion_token_output nextToken() {
 | 
				
			||||||
        llama_token result = -1;
 | 
					        completion_token_output result;
 | 
				
			||||||
 | 
					        result.tok = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (embd.size() >= (size_t)params.n_ctx) {
 | 
					        if (embd.size() >= (size_t)params.n_ctx) {
 | 
				
			||||||
            // Reset context
 | 
					            // Reset context
 | 
				
			||||||
@@ -261,7 +322,8 @@ struct llama_server_context {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (params.n_predict == 0) {
 | 
					        if (params.n_predict == 0) {
 | 
				
			||||||
            has_next_token = false;
 | 
					            has_next_token = false;
 | 
				
			||||||
            return llama_token_eos();
 | 
					            result.tok = llama_token_eos();
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // out of user input, sample next token
 | 
					        // out of user input, sample next token
 | 
				
			||||||
@@ -278,7 +340,7 @@ struct llama_server_context {
 | 
				
			|||||||
        const float mirostat_tau = params.mirostat_tau;
 | 
					        const float mirostat_tau = params.mirostat_tau;
 | 
				
			||||||
        const float mirostat_eta = params.mirostat_eta;
 | 
					        const float mirostat_eta = params.mirostat_eta;
 | 
				
			||||||
        const bool penalize_nl = params.penalize_nl;
 | 
					        const bool penalize_nl = params.penalize_nl;
 | 
				
			||||||
        llama_token id = 0;
 | 
					        const int32_t n_probs = params.n_probs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            auto * logits = llama_get_logits(ctx);
 | 
					            auto * logits = llama_get_logits(ctx);
 | 
				
			||||||
@@ -312,35 +374,42 @@ struct llama_server_context {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (temp <= 0) {
 | 
					            if (temp <= 0) {
 | 
				
			||||||
                // Greedy sampling
 | 
					                // Greedy sampling
 | 
				
			||||||
                id = llama_sample_token_greedy(ctx, &candidates_p);
 | 
					                result.tok = llama_sample_token_greedy(ctx, &candidates_p);
 | 
				
			||||||
 | 
					                if (n_probs > 0) {
 | 
				
			||||||
 | 
					                    llama_sample_softmax(ctx, &candidates_p);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if (mirostat == 1) {
 | 
					                if (mirostat == 1) {
 | 
				
			||||||
                    static float mirostat_mu = 2.0f * mirostat_tau;
 | 
					                    static float mirostat_mu = 2.0f * mirostat_tau;
 | 
				
			||||||
                    const int mirostat_m = 100;
 | 
					                    const int mirostat_m = 100;
 | 
				
			||||||
                    llama_sample_temperature(ctx, &candidates_p, temp);
 | 
					                    llama_sample_temperature(ctx, &candidates_p, temp);
 | 
				
			||||||
                    id = llama_sample_token_mirostat(ctx, &candidates_p, mirostat_tau, mirostat_eta, mirostat_m, &mirostat_mu);
 | 
					                    result.tok = llama_sample_token_mirostat(ctx, &candidates_p, mirostat_tau, mirostat_eta, mirostat_m, &mirostat_mu);
 | 
				
			||||||
                } else if (mirostat == 2) {
 | 
					                } else if (mirostat == 2) {
 | 
				
			||||||
                    static float mirostat_mu = 2.0f * mirostat_tau;
 | 
					                    static float mirostat_mu = 2.0f * mirostat_tau;
 | 
				
			||||||
                    llama_sample_temperature(ctx, &candidates_p, temp);
 | 
					                    llama_sample_temperature(ctx, &candidates_p, temp);
 | 
				
			||||||
                    id = llama_sample_token_mirostat_v2(ctx, &candidates_p, mirostat_tau, mirostat_eta, &mirostat_mu);
 | 
					                    result.tok = llama_sample_token_mirostat_v2(ctx, &candidates_p, mirostat_tau, mirostat_eta, &mirostat_mu);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    // Temperature sampling
 | 
					                    // Temperature sampling
 | 
				
			||||||
                    llama_sample_top_k(ctx, &candidates_p, top_k, 1);
 | 
					                    size_t min_keep = std::max(1, n_probs);
 | 
				
			||||||
                    llama_sample_tail_free(ctx, &candidates_p, tfs_z, 1);
 | 
					                    llama_sample_top_k(ctx, &candidates_p, top_k, min_keep);
 | 
				
			||||||
                    llama_sample_typical(ctx, &candidates_p, typical_p, 1);
 | 
					                    llama_sample_tail_free(ctx, &candidates_p, tfs_z, min_keep);
 | 
				
			||||||
                    llama_sample_top_p(ctx, &candidates_p, top_p, 1);
 | 
					                    llama_sample_typical(ctx, &candidates_p, typical_p, min_keep);
 | 
				
			||||||
 | 
					                    llama_sample_top_p(ctx, &candidates_p, top_p, min_keep);
 | 
				
			||||||
                    llama_sample_temperature(ctx, &candidates_p, temp);
 | 
					                    llama_sample_temperature(ctx, &candidates_p, temp);
 | 
				
			||||||
                    id = llama_sample_token(ctx, &candidates_p);
 | 
					                    result.tok = llama_sample_token(ctx, &candidates_p);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (size_t i = 0; i < std::min(candidates_p.size, (size_t) n_probs); ++i) {
 | 
				
			||||||
 | 
					                result.probs.push_back({candidates_p.data[i].id, candidates_p.data[i].p});
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            last_n_tokens.erase(last_n_tokens.begin());
 | 
					            last_n_tokens.erase(last_n_tokens.begin());
 | 
				
			||||||
            last_n_tokens.push_back(id);
 | 
					            last_n_tokens.push_back(result.tok);
 | 
				
			||||||
            num_tokens_predicted++;
 | 
					            num_tokens_predicted++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // add it to the context
 | 
					        // add it to the context
 | 
				
			||||||
        embd.push_back(id);
 | 
					        embd.push_back(result.tok);
 | 
				
			||||||
        result = id;
 | 
					 | 
				
			||||||
        // decrement remaining sampling budget
 | 
					        // decrement remaining sampling budget
 | 
				
			||||||
        --n_remain;
 | 
					        --n_remain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -382,12 +451,16 @@ struct llama_server_context {
 | 
				
			|||||||
        return stop_pos;
 | 
					        return stop_pos;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string doCompletion() {
 | 
					    completion_token_output doCompletion() {
 | 
				
			||||||
        const llama_token token = nextToken();
 | 
					        const completion_token_output token_with_probs = nextToken();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const std::string token_text = token == -1 ? "" : llama_token_to_str(ctx, token);
 | 
					        const std::string token_text = token_with_probs.tok == -1 ? "" : llama_token_to_str(ctx, token_with_probs.tok);
 | 
				
			||||||
        generated_text += token_text;
 | 
					        generated_text += token_text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (params.n_probs > 0) {
 | 
				
			||||||
 | 
					            generated_token_probs.push_back(token_with_probs);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (multibyte_pending > 0) {
 | 
					        if (multibyte_pending > 0) {
 | 
				
			||||||
            multibyte_pending -= token_text.size();
 | 
					            multibyte_pending -= token_text.size();
 | 
				
			||||||
        } else if (token_text.size() == 1) {
 | 
					        } else if (token_text.size() == 1) {
 | 
				
			||||||
@@ -416,8 +489,8 @@ struct llama_server_context {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        LOG_VERBOSE("next token", {
 | 
					        LOG_VERBOSE("next token", {
 | 
				
			||||||
            { "token", token },
 | 
					            { "token", token_with_probs.tok },
 | 
				
			||||||
            { "token_text", llama_token_to_str(ctx, token) },
 | 
					            { "token_text", tokens_to_output_formatted_string(ctx, token_with_probs.tok) },
 | 
				
			||||||
            { "has_next_token", has_next_token },
 | 
					            { "has_next_token", has_next_token },
 | 
				
			||||||
            { "n_remain", n_remain },
 | 
					            { "n_remain", n_remain },
 | 
				
			||||||
            { "num_tokens_predicted", num_tokens_predicted },
 | 
					            { "num_tokens_predicted", num_tokens_predicted },
 | 
				
			||||||
@@ -427,7 +500,7 @@ struct llama_server_context {
 | 
				
			|||||||
            { "stopping_word", stopping_word },
 | 
					            { "stopping_word", stopping_word },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return token_text;
 | 
					        return token_with_probs;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::vector<float> getEmbedding() {
 | 
					    std::vector<float> getEmbedding() {
 | 
				
			||||||
@@ -479,6 +552,7 @@ static void server_print_usage(const char * argv0, const gpt_params & params,
 | 
				
			|||||||
    fprintf(stderr, "  --lora-base FNAME     optional model to use as a base for the layers modified by the LoRA adapter\n");
 | 
					    fprintf(stderr, "  --lora-base FNAME     optional model to use as a base for the layers modified by the LoRA adapter\n");
 | 
				
			||||||
    fprintf(stderr, "  --host                ip address to listen (default  (default: %s)\n", sparams.hostname.c_str());
 | 
					    fprintf(stderr, "  --host                ip address to listen (default  (default: %s)\n", sparams.hostname.c_str());
 | 
				
			||||||
    fprintf(stderr, "  --port PORT           port to listen (default  (default: %d)\n", sparams.port);
 | 
					    fprintf(stderr, "  --port PORT           port to listen (default  (default: %d)\n", sparams.port);
 | 
				
			||||||
 | 
					    fprintf(stderr, "  --path PUBLIC_PATH    path from which to serve static files (default %s)\n", sparams.public_path.c_str());
 | 
				
			||||||
    fprintf(stderr, "  -to N, --timeout N    server read/write timeout in seconds (default: %d)\n", sparams.read_timeout);
 | 
					    fprintf(stderr, "  -to N, --timeout N    server read/write timeout in seconds (default: %d)\n", sparams.read_timeout);
 | 
				
			||||||
    fprintf(stderr, "  --embedding           enable embedding vector output (default: %s)\n", params.embedding ? "enabled" : "disabled");
 | 
					    fprintf(stderr, "  --embedding           enable embedding vector output (default: %s)\n", params.embedding ? "enabled" : "disabled");
 | 
				
			||||||
    fprintf(stderr, "\n");
 | 
					    fprintf(stderr, "\n");
 | 
				
			||||||
@@ -505,6 +579,12 @@ static void server_params_parse(int argc, char ** argv, server_params & sparams,
 | 
				
			|||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            sparams.hostname = argv[i];
 | 
					            sparams.hostname = argv[i];
 | 
				
			||||||
 | 
					        } else if (arg == "--path") {
 | 
				
			||||||
 | 
					            if (++i >= argc) {
 | 
				
			||||||
 | 
					                invalid_param = true;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            sparams.public_path = argv[i];
 | 
				
			||||||
        } else if (arg == "--timeout" || arg == "-to") {
 | 
					        } else if (arg == "--timeout" || arg == "-to") {
 | 
				
			||||||
            if (++i >= argc) {
 | 
					            if (++i >= argc) {
 | 
				
			||||||
                invalid_param = true;
 | 
					                invalid_param = true;
 | 
				
			||||||
@@ -669,6 +749,7 @@ static json format_generation_settings(llama_server_context & llama) {
 | 
				
			|||||||
        { "ignore_eos", ignore_eos },
 | 
					        { "ignore_eos", ignore_eos },
 | 
				
			||||||
        { "stream", llama.stream },
 | 
					        { "stream", llama.stream },
 | 
				
			||||||
        { "logit_bias", llama.params.logit_bias },
 | 
					        { "logit_bias", llama.params.logit_bias },
 | 
				
			||||||
 | 
					        { "n_probs", llama.params.n_probs },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -678,12 +759,14 @@ static json format_embedding_response(llama_server_context & llama) {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static json format_final_response(llama_server_context & llama, const std::string & content) {
 | 
					static json format_final_response(llama_server_context & llama, const std::string & content, const std::vector<completion_token_output> & probs) {
 | 
				
			||||||
    return json {
 | 
					
 | 
				
			||||||
 | 
					    json res = json {
 | 
				
			||||||
        { "content", content },
 | 
					        { "content", content },
 | 
				
			||||||
        { "stop", true },
 | 
					        { "stop", true },
 | 
				
			||||||
        { "model", llama.params.model_alias },
 | 
					        { "model", llama.params.model_alias },
 | 
				
			||||||
        { "tokens_predicted", llama.num_tokens_predicted },
 | 
					        { "tokens_predicted", llama.num_tokens_predicted },
 | 
				
			||||||
 | 
					        { "tokens_evaluated", llama.num_prompt_tokens },
 | 
				
			||||||
        { "generation_settings", format_generation_settings(llama) },
 | 
					        { "generation_settings", format_generation_settings(llama) },
 | 
				
			||||||
        { "prompt", llama.params.prompt },
 | 
					        { "prompt", llama.params.prompt },
 | 
				
			||||||
        { "truncated", llama.truncated },
 | 
					        { "truncated", llama.truncated },
 | 
				
			||||||
@@ -692,13 +775,25 @@ static json format_final_response(llama_server_context & llama, const std::strin
 | 
				
			|||||||
        { "stopped_limit", llama.stopped_limit },
 | 
					        { "stopped_limit", llama.stopped_limit },
 | 
				
			||||||
        { "stopping_word", llama.stopping_word },
 | 
					        { "stopping_word", llama.stopping_word },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (llama.params.n_probs > 0) {
 | 
				
			||||||
 | 
					        res["completion_probabilities"] = probs_vector_to_json(llama.ctx, probs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static json format_partial_response(const std::string & content) {
 | 
					static json format_partial_response(llama_server_context & llama, const std::string & content, const std::vector<completion_token_output> & probs) {
 | 
				
			||||||
    return json {
 | 
					    json res = json {
 | 
				
			||||||
        { "content", content },
 | 
					        { "content", content },
 | 
				
			||||||
        { "stop", false },
 | 
					        { "stop", false },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (llama.params.n_probs > 0) {
 | 
				
			||||||
 | 
					        res["completion_probabilities"] = probs_vector_to_json(llama.ctx, probs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static json format_tokenizer_response(const std::vector<llama_token> & tokens) {
 | 
					static json format_tokenizer_response(const std::vector<llama_token> & tokens) {
 | 
				
			||||||
@@ -728,6 +823,7 @@ static void parse_options_completion(const json & body, llama_server_context & l
 | 
				
			|||||||
    llama.params.n_keep = body.value("n_keep", default_params.n_keep);
 | 
					    llama.params.n_keep = body.value("n_keep", default_params.n_keep);
 | 
				
			||||||
    llama.params.seed = body.value("seed", default_params.seed);
 | 
					    llama.params.seed = body.value("seed", default_params.seed);
 | 
				
			||||||
    llama.params.prompt = body.value("prompt", default_params.prompt);
 | 
					    llama.params.prompt = body.value("prompt", default_params.prompt);
 | 
				
			||||||
 | 
					    llama.params.n_probs = body.value("n_probs", default_params.n_probs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    llama.params.logit_bias.clear();
 | 
					    llama.params.logit_bias.clear();
 | 
				
			||||||
    if (body.value("ignore_eos", false)) {
 | 
					    if (body.value("ignore_eos", false)) {
 | 
				
			||||||
@@ -764,17 +860,24 @@ static void parse_options_completion(const json & body, llama_server_context & l
 | 
				
			|||||||
    LOG_VERBOSE("completion parameters parsed", format_generation_settings(llama));
 | 
					    LOG_VERBOSE("completion parameters parsed", format_generation_settings(llama));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void log_server_request(const Request & req, const Response & res) {
 | 
					static void log_server_request(const Request & req, const Response & res) {
 | 
				
			||||||
    LOG_INFO("request", {
 | 
					    LOG_INFO("request", {
 | 
				
			||||||
        { "remote_addr", req.remote_addr },
 | 
					        { "remote_addr", req.remote_addr },
 | 
				
			||||||
        { "remote_port", req.remote_port },
 | 
					        { "remote_port", req.remote_port },
 | 
				
			||||||
        { "status", res.status },
 | 
					        { "status", res.status },
 | 
				
			||||||
 | 
					        { "method", req.method },
 | 
				
			||||||
        { "path", req.path },
 | 
					        { "path", req.path },
 | 
				
			||||||
 | 
					        { "params", req.params },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LOG_VERBOSE("request", {
 | 
				
			||||||
        { "request", req.body },
 | 
					        { "request", req.body },
 | 
				
			||||||
        { "response", res.body },
 | 
					        { "response", res.body },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char ** argv) {
 | 
					int main(int argc, char ** argv) {
 | 
				
			||||||
    // own arguments required by this example
 | 
					    // own arguments required by this example
 | 
				
			||||||
    gpt_params params;
 | 
					    gpt_params params;
 | 
				
			||||||
@@ -809,16 +912,34 @@ int main(int argc, char ** argv) {
 | 
				
			|||||||
    Server svr;
 | 
					    Server svr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    svr.set_default_headers({
 | 
					    svr.set_default_headers({
 | 
				
			||||||
 | 
					        { "Server", "llama.cpp" },
 | 
				
			||||||
        { "Access-Control-Allow-Origin", "*" },
 | 
					        { "Access-Control-Allow-Origin", "*" },
 | 
				
			||||||
        { "Access-Control-Allow-Headers", "content-type" }
 | 
					        { "Access-Control-Allow-Headers", "content-type" }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // this is only called if no index.js is found in the public --path
 | 
				
			||||||
 | 
					    svr.Get("/index.js", [](const Request &, Response & res) {
 | 
				
			||||||
 | 
					        res.set_content(reinterpret_cast<const char *>(&index_js), index_js_len, "text/javascript");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // this is only called if no index.html is found in the public --path
 | 
				
			||||||
    svr.Get("/", [](const Request &, Response & res) {
 | 
					    svr.Get("/", [](const Request &, Response & res) {
 | 
				
			||||||
        res.set_content("<h1>llama.cpp server works</h1>", "text/html");
 | 
					        res.set_content(reinterpret_cast<const char*>(&index_html), index_html_len, "text/html");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // this is only called if no index.html is found in the public --path
 | 
				
			||||||
 | 
					    svr.Get("/completion.js", [](const Request &, Response & res) {
 | 
				
			||||||
 | 
					        res.set_content(reinterpret_cast<const char*>(&completion_js), completion_js_len, "application/javascript");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    svr.Post("/completion", [&llama](const Request & req, Response & res) {
 | 
					    svr.Post("/completion", [&llama](const Request & req, Response & res) {
 | 
				
			||||||
 | 
					        auto lock = llama.lock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        llama.rewind();
 | 
					        llama.rewind();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        llama_reset_timings(llama.ctx);
 | 
					        llama_reset_timings(llama.ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        parse_options_completion(json::parse(req.body), llama);
 | 
					        parse_options_completion(json::parse(req.body), llama);
 | 
				
			||||||
@@ -830,7 +951,8 @@ int main(int argc, char ** argv) {
 | 
				
			|||||||
            size_t stop_pos = std::string::npos;
 | 
					            size_t stop_pos = std::string::npos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            while (llama.has_next_token) {
 | 
					            while (llama.has_next_token) {
 | 
				
			||||||
                const std::string token_text = llama.doCompletion();
 | 
					                const completion_token_output token_with_probs = llama.doCompletion();
 | 
				
			||||||
 | 
					                const std::string token_text = token_with_probs.tok == -1 ? "" : llama_token_to_str(llama.ctx, token_with_probs.tok);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                stop_pos = llama.findStoppingStrings(llama.generated_text,
 | 
					                stop_pos = llama.findStoppingStrings(llama.generated_text,
 | 
				
			||||||
                    token_text.size(), STOP_FULL);
 | 
					                    token_text.size(), STOP_FULL);
 | 
				
			||||||
@@ -844,7 +966,7 @@ int main(int argc, char ** argv) {
 | 
				
			|||||||
                    llama.generated_text.end());
 | 
					                    llama.generated_text.end());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const json data = format_final_response(llama, llama.generated_text);
 | 
					            const json data = format_final_response(llama, llama.generated_text, llama.generated_token_probs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            llama_print_timings(llama.ctx);
 | 
					            llama_print_timings(llama.ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -853,9 +975,11 @@ int main(int argc, char ** argv) {
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            const auto chunked_content_provider = [&](size_t, DataSink & sink) {
 | 
					            const auto chunked_content_provider = [&](size_t, DataSink & sink) {
 | 
				
			||||||
                size_t sent_count = 0;
 | 
					                size_t sent_count = 0;
 | 
				
			||||||
 | 
					                size_t sent_token_probs_index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                while (llama.has_next_token) {
 | 
					                while (llama.has_next_token) {
 | 
				
			||||||
                    const std::string token_text = llama.doCompletion();
 | 
					                    const completion_token_output token_with_probs = llama.doCompletion();
 | 
				
			||||||
 | 
					                    const std::string token_text = token_with_probs.tok == -1 ? "" : llama_token_to_str(llama.ctx, token_with_probs.tok);
 | 
				
			||||||
                    if (llama.multibyte_pending > 0) {
 | 
					                    if (llama.multibyte_pending > 0) {
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -878,10 +1002,22 @@ int main(int argc, char ** argv) {
 | 
				
			|||||||
                    const std::string to_send = llama.generated_text.substr(pos, stop_pos);
 | 
					                    const std::string to_send = llama.generated_text.substr(pos, stop_pos);
 | 
				
			||||||
                    sent_count += to_send.size();
 | 
					                    sent_count += to_send.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    std::vector<completion_token_output> probs_output = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (llama.params.n_probs > 0) {
 | 
				
			||||||
 | 
					                        const std::vector<llama_token> to_send_toks = llama_tokenize(llama.ctx, to_send, false);
 | 
				
			||||||
 | 
					                        size_t probs_pos = std::min(sent_token_probs_index, llama.generated_token_probs.size());
 | 
				
			||||||
 | 
					                        size_t probs_stop_pos = std::min(sent_token_probs_index + to_send_toks.size(), llama.generated_token_probs.size());
 | 
				
			||||||
 | 
					                        if (probs_pos < probs_stop_pos) {
 | 
				
			||||||
 | 
					                            probs_output = std::vector<completion_token_output>(llama.generated_token_probs.begin() + probs_pos, llama.generated_token_probs.begin() + probs_stop_pos);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        sent_token_probs_index = probs_stop_pos;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const json data = llama.has_next_token
 | 
					                    const json data = llama.has_next_token
 | 
				
			||||||
                                          ? format_partial_response(to_send)
 | 
					                                          ? format_partial_response(llama, to_send, probs_output)
 | 
				
			||||||
                                          // Generation is done, send extra information.
 | 
					                                          // Generation is done, send extra information.
 | 
				
			||||||
                                          : format_final_response(llama, to_send);
 | 
					                                          : format_final_response(llama, to_send, llama.generated_token_probs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const std::string str =
 | 
					                    const std::string str =
 | 
				
			||||||
                        "data: " +
 | 
					                        "data: " +
 | 
				
			||||||
@@ -912,6 +1048,8 @@ int main(int argc, char ** argv) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    svr.Post("/tokenize", [&llama](const Request & req, Response & res) {
 | 
					    svr.Post("/tokenize", [&llama](const Request & req, Response & res) {
 | 
				
			||||||
 | 
					        auto lock = llama.lock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const json body = json::parse(req.body);
 | 
					        const json body = json::parse(req.body);
 | 
				
			||||||
        const std::string content = body.value("content", "");
 | 
					        const std::string content = body.value("content", "");
 | 
				
			||||||
        const std::vector<llama_token> tokens = llama_tokenize(llama.ctx, content, false);
 | 
					        const std::vector<llama_token> tokens = llama_tokenize(llama.ctx, content, false);
 | 
				
			||||||
@@ -920,6 +1058,8 @@ int main(int argc, char ** argv) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    svr.Post("/embedding", [&llama](const Request & req, Response & res) {
 | 
					    svr.Post("/embedding", [&llama](const Request & req, Response & res) {
 | 
				
			||||||
 | 
					        auto lock = llama.lock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const json body = json::parse(req.body);
 | 
					        const json body = json::parse(req.body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        llama.rewind();
 | 
					        llama.rewind();
 | 
				
			||||||
@@ -950,18 +1090,27 @@ int main(int argc, char ** argv) {
 | 
				
			|||||||
        res.status = 500;
 | 
					        res.status = 500;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    svr.set_error_handler([](const Request &, Response & res) {
 | 
				
			||||||
 | 
					        res.set_content("File Not Found", "text/plain");
 | 
				
			||||||
 | 
					        res.status = 404;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // set timeouts and change hostname and port
 | 
					    // set timeouts and change hostname and port
 | 
				
			||||||
    svr.set_read_timeout(sparams.read_timeout);
 | 
					    svr.set_read_timeout(sparams.read_timeout);
 | 
				
			||||||
    svr.set_write_timeout(sparams.write_timeout);
 | 
					    svr.set_write_timeout(sparams.write_timeout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!svr.bind_to_port(sparams.hostname, sparams.port)) {
 | 
					    if (!svr.bind_to_port(sparams.hostname, sparams.port)) {
 | 
				
			||||||
        LOG_ERROR("couldn't bind to server socket", {
 | 
					        fprintf(stderr, "\ncouldn't bind to server socket: hostname=%s port=%d\n\n", sparams.hostname.c_str(), sparams.port);
 | 
				
			||||||
            { "hostname", sparams.hostname },
 | 
					 | 
				
			||||||
            { "port", sparams.port },
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set the base directory for serving static files
 | 
				
			||||||
 | 
					    svr.set_base_dir(sparams.public_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // to make it ctrl+clickable:
 | 
				
			||||||
 | 
					    fprintf(stdout, "\nllama server listening at http://%s:%d\n\n", sparams.hostname.c_str(), sparams.port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_INFO("HTTP server listening", {
 | 
					    LOG_INFO("HTTP server listening", {
 | 
				
			||||||
        { "hostname", sparams.hostname },
 | 
					        { "hostname", sparams.hostname },
 | 
				
			||||||
        { "port", sparams.port },
 | 
					        { "port", sparams.port },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2835,7 +2835,7 @@ void ggml_cuda_transform_tensor(void * data, struct ggml_tensor * tensor) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ggml_cuda_free_data(struct ggml_tensor * tensor) {
 | 
					void ggml_cuda_free_data(struct ggml_tensor * tensor) {
 | 
				
			||||||
    if (tensor->backend != GGML_BACKEND_GPU && tensor->backend != GGML_BACKEND_GPU_SPLIT) {
 | 
					    if (!tensor || (tensor->backend != GGML_BACKEND_GPU && tensor->backend != GGML_BACKEND_GPU_SPLIT) ) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1376,7 +1376,7 @@ static void ggml_cl_mul_f32(const ggml_tensor * src0, const ggml_tensor * src1,
 | 
				
			|||||||
    const int64_t ne00 = src0->ne[0];
 | 
					    const int64_t ne00 = src0->ne[0];
 | 
				
			||||||
    const int64_t ne01 = src0->ne[1];
 | 
					    const int64_t ne01 = src0->ne[1];
 | 
				
			||||||
    const int64_t ne02 = src0->ne[2];
 | 
					    const int64_t ne02 = src0->ne[2];
 | 
				
			||||||
    const int64_t ne03 = src0->ne[2];
 | 
					    const int64_t ne03 = src0->ne[3];
 | 
				
			||||||
    const int64_t ne0 = ne00 * ne01 * ne02 * ne03;
 | 
					    const int64_t ne0 = ne00 * ne01 * ne02 * ne03;
 | 
				
			||||||
    const int64_t ne10 = src1->ne[0];
 | 
					    const int64_t ne10 = src1->ne[0];
 | 
				
			||||||
    const int64_t ne11 = src1->ne[1];
 | 
					    const int64_t ne11 = src1->ne[1];
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										118
									
								
								ggml.h
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								ggml.h
									
									
									
									
									
								
							@@ -201,6 +201,8 @@
 | 
				
			|||||||
#define GGML_MAX_NAME          48
 | 
					#define GGML_MAX_NAME          48
 | 
				
			||||||
#define GGML_DEFAULT_N_THREADS 4
 | 
					#define GGML_DEFAULT_N_THREADS 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GGML_UNUSED(x) (void)(x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GGML_ASSERT(x) \
 | 
					#define GGML_ASSERT(x) \
 | 
				
			||||||
    do { \
 | 
					    do { \
 | 
				
			||||||
        if (!(x)) { \
 | 
					        if (!(x)) { \
 | 
				
			||||||
@@ -209,6 +211,30 @@
 | 
				
			|||||||
        } \
 | 
					        } \
 | 
				
			||||||
    } while (0)
 | 
					    } while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// used to copy the number of elements and stride in bytes of tensors into local variables.
 | 
				
			||||||
 | 
					// main purpose is to reduce code duplication and improve readability.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// example:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    GGML_TENSOR_LOCALS(int64_t, ne1, src1, ne);
 | 
				
			||||||
 | 
					//    GGML_TENSOR_LOCALS(size_t,  nb1, src1, nb);
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					#define GGML_TENSOR_LOCALS_1(type, prefix, pointer, array) \
 | 
				
			||||||
 | 
					    const type prefix##0 = (pointer)->array[0]; \
 | 
				
			||||||
 | 
					    GGML_UNUSED(prefix##0);
 | 
				
			||||||
 | 
					#define GGML_TENSOR_LOCALS_2(type, prefix, pointer, array) \
 | 
				
			||||||
 | 
					    GGML_TENSOR_LOCALS_1    (type, prefix, pointer, array) \
 | 
				
			||||||
 | 
					    const type prefix##1 = (pointer)->array[1]; \
 | 
				
			||||||
 | 
					    GGML_UNUSED(prefix##1);
 | 
				
			||||||
 | 
					#define GGML_TENSOR_LOCALS_3(type, prefix, pointer, array) \
 | 
				
			||||||
 | 
					    GGML_TENSOR_LOCALS_2    (type, prefix, pointer, array) \
 | 
				
			||||||
 | 
					    const type prefix##2 = (pointer)->array[2]; \
 | 
				
			||||||
 | 
					    GGML_UNUSED(prefix##2);
 | 
				
			||||||
 | 
					#define GGML_TENSOR_LOCALS(type, prefix, pointer, array) \
 | 
				
			||||||
 | 
					    GGML_TENSOR_LOCALS_3  (type, prefix, pointer, array) \
 | 
				
			||||||
 | 
					    const type prefix##3 = (pointer)->array[3]; \
 | 
				
			||||||
 | 
					    GGML_UNUSED(prefix##3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef  __cplusplus
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -295,12 +321,15 @@ extern "C" {
 | 
				
			|||||||
        GGML_OP_SUM,
 | 
					        GGML_OP_SUM,
 | 
				
			||||||
        GGML_OP_SUM_ROWS,
 | 
					        GGML_OP_SUM_ROWS,
 | 
				
			||||||
        GGML_OP_MEAN,
 | 
					        GGML_OP_MEAN,
 | 
				
			||||||
 | 
					        GGML_OP_ARGMAX,
 | 
				
			||||||
        GGML_OP_REPEAT,
 | 
					        GGML_OP_REPEAT,
 | 
				
			||||||
        GGML_OP_REPEAT_BACK,
 | 
					        GGML_OP_REPEAT_BACK,
 | 
				
			||||||
        GGML_OP_ABS,
 | 
					        GGML_OP_ABS,
 | 
				
			||||||
        GGML_OP_SGN,
 | 
					        GGML_OP_SGN,
 | 
				
			||||||
        GGML_OP_NEG,
 | 
					        GGML_OP_NEG,
 | 
				
			||||||
        GGML_OP_STEP,
 | 
					        GGML_OP_STEP,
 | 
				
			||||||
 | 
					        GGML_OP_TANH,
 | 
				
			||||||
 | 
					        GGML_OP_ELU,
 | 
				
			||||||
        GGML_OP_RELU,
 | 
					        GGML_OP_RELU,
 | 
				
			||||||
        GGML_OP_GELU,
 | 
					        GGML_OP_GELU,
 | 
				
			||||||
        GGML_OP_GELU_QUICK,
 | 
					        GGML_OP_GELU_QUICK,
 | 
				
			||||||
@@ -332,9 +361,8 @@ extern "C" {
 | 
				
			|||||||
        GGML_OP_ROPE_BACK,
 | 
					        GGML_OP_ROPE_BACK,
 | 
				
			||||||
        GGML_OP_ALIBI,
 | 
					        GGML_OP_ALIBI,
 | 
				
			||||||
        GGML_OP_CLAMP,
 | 
					        GGML_OP_CLAMP,
 | 
				
			||||||
        GGML_OP_CONV_1D_S1_PH,
 | 
					        GGML_OP_CONV_1D,
 | 
				
			||||||
        GGML_OP_CONV_1D_S2_PH,
 | 
					        GGML_OP_CONV_2D,
 | 
				
			||||||
        GGML_OP_CONV_2D_SK_P0,
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        GGML_OP_FLASH_ATTN,
 | 
					        GGML_OP_FLASH_ATTN,
 | 
				
			||||||
        GGML_OP_FLASH_FF,
 | 
					        GGML_OP_FLASH_FF,
 | 
				
			||||||
@@ -690,6 +718,11 @@ extern "C" {
 | 
				
			|||||||
            struct ggml_context * ctx,
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
            struct ggml_tensor  * a);
 | 
					            struct ggml_tensor  * a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // argmax along rows
 | 
				
			||||||
 | 
					    GGML_API struct ggml_tensor * ggml_argmax(
 | 
				
			||||||
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
 | 
					            struct ggml_tensor  * a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // if a is the same shape as b, and a is not parameter, return a
 | 
					    // if a is the same shape as b, and a is not parameter, return a
 | 
				
			||||||
    // otherwise, return a new tensor: repeat(a) to fit in b
 | 
					    // otherwise, return a new tensor: repeat(a) to fit in b
 | 
				
			||||||
    GGML_API struct ggml_tensor * ggml_repeat(
 | 
					    GGML_API struct ggml_tensor * ggml_repeat(
 | 
				
			||||||
@@ -734,6 +767,22 @@ extern "C" {
 | 
				
			|||||||
            struct ggml_context * ctx,
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
            struct ggml_tensor  * a);
 | 
					            struct ggml_tensor  * a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GGML_API struct ggml_tensor * ggml_tanh(
 | 
				
			||||||
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
 | 
					            struct ggml_tensor  * a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GGML_API struct ggml_tensor * ggml_tanh_inplace(
 | 
				
			||||||
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
 | 
					            struct ggml_tensor  * a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GGML_API struct ggml_tensor * ggml_elu(
 | 
				
			||||||
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
 | 
					            struct ggml_tensor  * a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GGML_API struct ggml_tensor * ggml_elu_inplace(
 | 
				
			||||||
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
 | 
					            struct ggml_tensor  * a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GGML_API struct ggml_tensor * ggml_relu(
 | 
					    GGML_API struct ggml_tensor * ggml_relu(
 | 
				
			||||||
            struct ggml_context * ctx,
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
            struct ggml_tensor  * a);
 | 
					            struct ggml_tensor  * a);
 | 
				
			||||||
@@ -1084,58 +1133,33 @@ extern "C" {
 | 
				
			|||||||
            float                 min,
 | 
					            float                 min,
 | 
				
			||||||
            float                 max);
 | 
					            float                 max);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO: implement general-purpose convolutions
 | 
					    GGML_API struct ggml_tensor * ggml_conv_1d(
 | 
				
			||||||
    // GGML_API struct ggml_tensor * ggml_conv_1d(
 | 
					 | 
				
			||||||
    //        struct ggml_context * ctx,
 | 
					 | 
				
			||||||
    //        struct ggml_tensor  * a,
 | 
					 | 
				
			||||||
    //        struct ggml_tensor  * b,
 | 
					 | 
				
			||||||
    //        int                   s0
 | 
					 | 
				
			||||||
    //        int                   p0,
 | 
					 | 
				
			||||||
    //        int                   d0);
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    // GGML_API struct ggml_tensor * ggml_conv_2d(
 | 
					 | 
				
			||||||
    //        struct ggml_context * ctx,
 | 
					 | 
				
			||||||
    //        struct ggml_tensor  * a,
 | 
					 | 
				
			||||||
    //        struct ggml_tensor  * b,
 | 
					 | 
				
			||||||
    //        int                   s0,
 | 
					 | 
				
			||||||
    //        int                   s1,
 | 
					 | 
				
			||||||
    //        int                   p0,
 | 
					 | 
				
			||||||
    //        int                   p1,
 | 
					 | 
				
			||||||
    //        int                   d0,
 | 
					 | 
				
			||||||
    //        int                   d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // padding = half
 | 
					 | 
				
			||||||
    // TODO: we don't support extra parameters for now
 | 
					 | 
				
			||||||
    //       that's why we are hard-coding the stride, padding, and dilation
 | 
					 | 
				
			||||||
    //       not great ..
 | 
					 | 
				
			||||||
    // example:
 | 
					 | 
				
			||||||
    // a:      3   80  768    1
 | 
					 | 
				
			||||||
    // b:   3000   80    1    1
 | 
					 | 
				
			||||||
    // res: 3000  768    1    1
 | 
					 | 
				
			||||||
    // used in whisper
 | 
					 | 
				
			||||||
    GGML_API struct ggml_tensor * ggml_conv_1d_s1_ph(
 | 
					 | 
				
			||||||
            struct ggml_context * ctx,
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
            struct ggml_tensor  * a,
 | 
					            struct ggml_tensor  * a,
 | 
				
			||||||
            struct ggml_tensor  * b);
 | 
					            struct ggml_tensor  * b,
 | 
				
			||||||
 | 
					            int                   s0,  // stride
 | 
				
			||||||
 | 
					            int                   p0,  // padding
 | 
				
			||||||
 | 
					            int                   d0); // dilation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // used in whisper
 | 
					    GGML_API struct ggml_tensor * ggml_conv_2d(
 | 
				
			||||||
    GGML_API struct ggml_tensor * ggml_conv_1d_s2_ph(
 | 
					 | 
				
			||||||
            struct ggml_context * ctx,
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
            struct ggml_tensor  * a,
 | 
					            struct ggml_tensor  * a,
 | 
				
			||||||
            struct ggml_tensor  * b);
 | 
					            struct ggml_tensor  * b,
 | 
				
			||||||
 | 
					            int                   s0,
 | 
				
			||||||
 | 
					            int                   s1,
 | 
				
			||||||
 | 
					            int                   p0,
 | 
				
			||||||
 | 
					            int                   p1,
 | 
				
			||||||
 | 
					            int                   d0,
 | 
				
			||||||
 | 
					            int                   d1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // kernel size is a->ne[0] x a->ne[1]
 | 
					    // conv_1d with padding = half
 | 
				
			||||||
    // stride is equal to kernel size
 | 
					    // alias for ggml_conv_1d(a, b, s, a->ne[0]/2, d)
 | 
				
			||||||
    // padding is zero
 | 
					    GGML_API struct ggml_tensor* ggml_conv_1d_ph(
 | 
				
			||||||
    // example:
 | 
					 | 
				
			||||||
    // a:     16   16    3  768
 | 
					 | 
				
			||||||
    // b:   1024 1024    3    1
 | 
					 | 
				
			||||||
    // res:   64   64  768    1
 | 
					 | 
				
			||||||
    // used in sam
 | 
					 | 
				
			||||||
    GGML_API struct ggml_tensor * ggml_conv_2d_sk_p0(
 | 
					 | 
				
			||||||
            struct ggml_context * ctx,
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
            struct ggml_tensor  * a,
 | 
					            struct ggml_tensor  * a,
 | 
				
			||||||
            struct ggml_tensor  * b);
 | 
					            struct ggml_tensor  * b,
 | 
				
			||||||
 | 
					            int                   s,
 | 
				
			||||||
 | 
					            int                   d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GGML_API struct ggml_tensor * ggml_flash_attn(
 | 
					    GGML_API struct ggml_tensor * ggml_flash_attn(
 | 
				
			||||||
            struct ggml_context * ctx,
 | 
					            struct ggml_context * ctx,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -194,8 +194,8 @@ struct llama_layer {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct llama_kv_cache {
 | 
					struct llama_kv_cache {
 | 
				
			||||||
    struct ggml_tensor * k;
 | 
					    struct ggml_tensor * k = NULL;
 | 
				
			||||||
    struct ggml_tensor * v;
 | 
					    struct ggml_tensor * v = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct ggml_context * ctx = NULL;
 | 
					    struct ggml_context * ctx = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -481,9 +481,7 @@ struct llama_file_loader {
 | 
				
			|||||||
            std::string word = file.read_string(len);
 | 
					            std::string word = file.read_string(len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            float score = 0.0f;
 | 
					            float score = 0.0f;
 | 
				
			||||||
            if (file_version >= LLAMA_FILE_VERSION_GGMF_V1) {
 | 
					            file.read_raw(&score, sizeof(score));
 | 
				
			||||||
                file.read_raw(&score, sizeof(score));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            vocab.token_to_id[word] = i;
 | 
					            vocab.token_to_id[word] = i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,11 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cp -rpv ../ggml/src/ggml.c          ./ggml.c
 | 
					cp -rpv ../ggml/src/ggml.c           ./ggml.c
 | 
				
			||||||
cp -rpv ../ggml/src/ggml-cuda.cu    ./ggml-cuda.cu
 | 
					cp -rpv ../ggml/src/ggml-cuda.h      ./ggml-cuda.h
 | 
				
			||||||
cp -rpv ../ggml/src/ggml-cuda.h     ./ggml-cuda.h
 | 
					cp -rpv ../ggml/src/ggml-cuda.cu     ./ggml-cuda.cu
 | 
				
			||||||
 | 
					cp -rpv ../ggml/src/ggml-opencl.h    ./ggml-opencl.h
 | 
				
			||||||
 | 
					cp -rpv ../ggml/src/ggml-opencl.cpp  ./ggml-opencl.cpp
 | 
				
			||||||
 | 
					cp -rpv ../ggml/src/ggml-metal.h     ./ggml-metal.h
 | 
				
			||||||
 | 
					cp -rpv ../ggml/src/ggml-metal.m     ./ggml-metal.m
 | 
				
			||||||
 | 
					cp -rpv ../ggml/src/ggml-metal.metal ./ggml-metal.metal
 | 
				
			||||||
cp -rpv ../ggml/include/ggml/ggml.h ./ggml.h
 | 
					cp -rpv ../ggml/include/ggml/ggml.h ./ggml.h
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user