diff --git a/src/third_party/QR-Code-generator/Readme.markdown b/src/third_party/QR-Code-generator/Readme.markdown
new file mode 100644
index 0000000..7b1e7cc
--- /dev/null
+++ b/src/third_party/QR-Code-generator/Readme.markdown
@@ -0,0 +1,195 @@
+QR Code generator library
+=========================
+
+
+Introduction
+------------
+
+This project aims to be the best, clearest QR Code generator library in multiple languages. The primary goals are flexible options and absolute correctness. Secondary goals are compact implementation size and good documentation comments.
+
+Home page with live JavaScript demo, extensive descriptions, and competitor comparisons: [https://www.nayuki.io/page/qr-code-generator-library](https://www.nayuki.io/page/qr-code-generator-library)
+
+
+Features
+--------
+
+Core features:
+
+* Available in 6 programming languages, all with nearly equal functionality: Java, JavaScript, Python, C++, C, Rust
+* Significantly shorter code but more documentation comments compared to competing libraries
+* Supports encoding all 40 versions (sizes) and all 4 error correction levels, as per the QR Code Model 2 standard
+* Output formats: Raw modules/pixels of the QR symbol (all languages), SVG XML string (all languages except C), `BufferedImage` raster bitmap (Java only), HTML5 canvas (JavaScript only)
+* Encodes numeric and special-alphanumeric text in less space than general text
+* Open source code under the permissive MIT License
+
+Manual parameters:
+
+* User can specify minimum and maximum version numbers allowed, then library will automatically choose smallest version in the range that fits the data
+* User can specify mask pattern manually, otherwise library will automatically evaluate all 8 masks and select the optimal one
+* User can specify absolute error correction level, or allow the library to boost it if it doesn't increase the version number
+* User can create a list of data segments manually and add ECI segments (all languages except C)
+
+Optional advanced features (Java only):
+
+* Encodes Japanese Unicode text in kanji mode to save a lot of space compared to UTF-8 bytes
+* Computes optimal segment mode switching for text with mixed numeric/alphanumeric/general parts
+
+
+Examples
+--------
+
+Java language:
+
+    import java.awt.image.BufferedImage;
+    import java.io.File;
+    import javax.imageio.ImageIO;
+    import io.nayuki.qrcodegen.*;
+    
+    // Simple operation
+    QrCode qr0 = QrCode.encodeText("Hello, world!", QrCode.Ecc.MEDIUM);
+    BufferedImage img = qr0.toImage(4, 10);
+    ImageIO.write(img, "png", new File("qr-code.png"));
+    
+    // Manual operation
+    List<QrSegment> segs = QrSegment.makeSegments("3141592653589793238462643383");
+    QrCode qr1 = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, 5, 5, 2, false);
+    for (int y = 0; y < qr1.size; y++) {
+        for (int x = 0; x < qr1.size; x++) {
+            (... paint qr1.getModule(x, y) ...)
+        }
+    }
+
+JavaScript language:
+
+    // Name abbreviated for the sake of these examples here
+    var QRC = qrcodegen.QrCode;
+    
+    // Simple operation
+    var qr0 = QRC.encodeText("Hello, world!", QRC.Ecc.MEDIUM);
+    var svg = qr0.toSvgString(4);
+    
+    // Manual operation
+    var segs = qrcodegen.QrSegment.makeSegments("3141592653589793238462643383");
+    var qr1 = QRC.encodeSegments(segs, QRC.Ecc.HIGH, 5, 5, 2, false);
+    for (var y = 0; y < qr1.size; y++) {
+        for (var x = 0; x < qr1.size; x++) {
+            (... paint qr1.getModule(x, y) ...)
+        }
+    }
+
+Python language:
+
+    from qrcodegen import *
+    
+    # Simple operation
+    qr0 = QrCode.encode_text("Hello, world!", QrCode.Ecc.MEDIUM)
+    svg = qr0.to_svg_str(4)
+    
+    # Manual operation
+    segs = QrSegment.make_segments("3141592653589793238462643383")
+    qr1 = QrCode.encode_segments(segs, QrCode.Ecc.HIGH, 5, 5, 2, False)
+    for y in range(qr1.get_size()):
+        for x in range(qr1.get_size()):
+            (... paint qr1.get_module(x, y) ...)
+
+C++ language:
+
+    #include <string>
+    #include <vector>
+    #include "QrCode.hpp"
+    using namespace qrcodegen;
+    
+    // Simple operation
+    QrCode qr0 = QrCode::encodeText("Hello, world!", QrCode::Ecc::MEDIUM);
+    std::string svg = qr0.toSvgString(4);
+    
+    // Manual operation
+    std::vector<QrSegment> segs =
+        QrSegment::makeSegments("3141592653589793238462643383");
+    QrCode qr1 = QrCode::encodeSegments(
+        segs, QrCode::Ecc::HIGH, 5, 5, 2, false);
+    for (int y = 0; y < qr1.getSize(); y++) {
+        for (int x = 0; x < qr1.getSize(); x++) {
+            (... paint qr1.getModule(x, y) ...)
+        }
+    }
+
+C language:
+
+    #include <stdbool.h>
+    #include <stdint.h>
+    #include "qrcodegen.h"
+    
+    // Text data
+    uint8_t qr0[qrcodegen_BUFFER_LEN_MAX];
+    uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+    bool ok = qrcodegen_encodeText("Hello, world!",
+        tempBuffer, qr0, qrcodegen_Ecc_MEDIUM,
+        qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX,
+        qrcodegen_Mask_AUTO, true);
+    if (!ok)
+        return;
+    
+    int size = qrcodegen_getSize(qr0);
+    for (int y = 0; y < size; y++) {
+        for (int x = 0; x < size; x++) {
+            (... paint qrcodegen_getModule(qr0, x, y) ...)
+        }
+    }
+    
+    // Binary data
+    uint8_t dataAndTemp[qrcodegen_BUFFER_LEN_FOR_VERSION(7)]
+        = {0xE3, 0x81, 0x82};
+    uint8_t qr1[qrcodegen_BUFFER_LEN_FOR_VERSION(7)];
+    ok = qrcodegen_encodeBinary(dataAndTemp, 3, qr1,
+        qrcodegen_Ecc_HIGH, 2, 7, qrcodegen_Mask_4, false);
+
+Rust language:
+
+    extern crate qrcodegen;
+    use qrcodegen::QrCode;
+    use qrcodegen::QrCodeEcc;
+    use qrcodegen::QrSegment;
+    
+    // Simple operation
+    let qr0 = QrCode::encode_text("Hello, world!",
+        QrCodeEcc::Medium).unwrap();
+    let svg = qr0.to_svg_string(4);
+    
+    // Manual operation
+    let chrs: Vec<char> = "3141592653589793238462643383".chars().collect();
+    let segs = QrSegment::make_segments(&chrs);
+    let qr1 = QrCode::encode_segments_advanced(
+        &segs, QrCodeEcc::High, 5, 5, Some(2), false).unwrap();
+    for y in 0 .. qr1.size() {
+        for x in 0 .. qr1.size() {
+            (... paint qr1.get_module(x, y) ...)
+        }
+    }
+
+More information about QR Code technology and this library's design can be found on the project home page.
+
+
+License
+-------
+
+Copyright © 2017 Project Nayuki. (MIT License)  
+[https://www.nayuki.io/page/qr-code-generator-library](https://www.nayuki.io/page/qr-code-generator-library)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+* The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+* The Software is provided "as is", without warranty of any kind, express or
+  implied, including but not limited to the warranties of merchantability,
+  fitness for a particular purpose and noninfringement. In no event shall the
+  authors or copyright holders be liable for any claim, damages or other
+  liability, whether in an action of contract, tort or otherwise, arising from,
+  out of or in connection with the Software or the use or other dealings in the
+  Software.
diff --git a/src/third_party/QR-Code-generator/c/Makefile b/src/third_party/QR-Code-generator/c/Makefile
new file mode 100644
index 0000000..a33f8d2
--- /dev/null
+++ b/src/third_party/QR-Code-generator/c/Makefile
@@ -0,0 +1,75 @@
+# 
+# Makefile for QR Code generator (C)
+# 
+# Copyright (c) Project Nayuki. (MIT License)
+# https://www.nayuki.io/page/qr-code-generator-library
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+# - The above copyright notice and this permission notice shall be included in
+#   all copies or substantial portions of the Software.
+# - The Software is provided "as is", without warranty of any kind, express or
+#   implied, including but not limited to the warranties of merchantability,
+#   fitness for a particular purpose and noninfringement. In no event shall the
+#   authors or copyright holders be liable for any claim, damages or other
+#   liability, whether in an action of contract, tort or otherwise, arising from,
+#   out of or in connection with the Software or the use or other dealings in the
+#   Software.
+# 
+
+
+# ---- Configuration options ----
+
+# External/implicit variables:
+# - CC: The C compiler, such as gcc or clang.
+# - CFLAGS: Any extra user-specified compiler flags (can be blank).
+
+# Mandatory compiler flags
+CFLAGS += -std=c99
+# Diagnostics. Adding '-fsanitize=address' is helpful for most versions of Clang and newer versions of GCC.
+CFLAGS += -Wall -fsanitize=undefined
+# Optimization level
+CFLAGS += -O1
+
+
+# ---- Controlling make ----
+
+# Clear default suffix rules
+.SUFFIXES:
+
+# Don't delete object files
+.SECONDARY:
+
+# Stuff concerning goals
+.DEFAULT_GOAL = all
+.PHONY: all clean
+
+
+# ---- Targets to build ----
+
+LIBSRC = qrcodegen
+LIBFILE = libqrcodegen.so
+MAINS = qrcodegen-demo qrcodegen-test qrcodegen-worker
+
+# Build all binaries
+all: $(LIBFILE) $(MAINS)
+
+# Delete build output
+clean:
+	rm -f -- $(LIBFILE) $(MAINS)
+
+# Shared library
+$(LIBFILE): $(LIBSRC:=.c) $(LIBSRC:=.h)
+	$(CC) $(CFLAGS) -fPIC -shared -o $@ $(LIBSRC:=.c)
+
+# Executable files
+%: %.c $(LIBFILE)
+	$(CC) $(CFLAGS) -o $@ $^
+
+# Special executable
+qrcodegen-test: qrcodegen-test.c $(LIBSRC:=.c) $(LIBSRC:=.h)
+	$(CC) $(CFLAGS) -DQRCODEGEN_TEST -o $@ $< $(LIBSRC:=.c)
diff --git a/src/third_party/QR-Code-generator/c/qrcodegen-demo.c b/src/third_party/QR-Code-generator/c/qrcodegen-demo.c
new file mode 100644
index 0000000..c06e2f7
--- /dev/null
+++ b/src/third_party/QR-Code-generator/c/qrcodegen-demo.c
@@ -0,0 +1,310 @@
+/* 
+ * QR Code generator demo (C)
+ * 
+ * Run this command-line program with no arguments. The program
+ * computes a demonstration QR Codes and print it to the console.
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "qrcodegen.h"
+
+
+// Function prototypes
+static void doBasicDemo(void);
+static void doVarietyDemo(void);
+static void doSegmentDemo(void);
+static void doMaskDemo(void);
+static void printQr(const uint8_t qrcode[]);
+
+
+// The main application program.
+int main(void) {
+	doBasicDemo();
+	doVarietyDemo();
+	doSegmentDemo();
+	doMaskDemo();
+	return EXIT_SUCCESS;
+}
+
+
+
+/*---- Demo suite ----*/
+
+// Creates a single QR Code, then prints it to the console.
+static void doBasicDemo(void) {
+	const char *text = "Hello, world!";  // User-supplied text
+	enum qrcodegen_Ecc errCorLvl = qrcodegen_Ecc_LOW;  // Error correction level
+	
+	// Make and print the QR Code symbol
+	uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+	uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+	bool ok = qrcodegen_encodeText(text, tempBuffer, qrcode, errCorLvl,
+		qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
+	if (ok)
+		printQr(qrcode);
+}
+
+
+// Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console.
+static void doVarietyDemo(void) {
+	{  // Numeric mode encoding (3.33 bits per digit)
+		uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+		uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+		bool ok = qrcodegen_encodeText("314159265358979323846264338327950288419716939937510", tempBuffer, qrcode,
+			qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
+		if (ok)
+			printQr(qrcode);
+	}
+	
+	{  // Alphanumeric mode encoding (5.5 bits per character)
+		uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+		uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+		bool ok = qrcodegen_encodeText("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", tempBuffer, qrcode,
+			qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
+		if (ok)
+			printQr(qrcode);
+	}
+	
+	{  // Unicode text as UTF-8
+		const char *text = "\xE3\x81\x93\xE3\x82\x93\xE3\x81\xAB\xE3\x81\xA1wa\xE3\x80\x81\xE4\xB8\x96\xE7\x95\x8C\xEF\xBC\x81\x20\xCE\xB1\xCE\xB2\xCE\xB3\xCE\xB4";
+		uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+		uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+		bool ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
+			qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
+		if (ok)
+			printQr(qrcode);
+	}
+	
+	{  // Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
+		const char *text =
+			"Alice was beginning to get very tired of sitting by her sister on the bank, "
+			"and of having nothing to do: once or twice she had peeped into the book her sister was reading, "
+			"but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice "
+			"'without pictures or conversations?' So she was considering in her own mind (as well as she could, "
+			"for the hot day made her feel very sleepy and stupid), whether the pleasure of making a "
+			"daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly "
+			"a White Rabbit with pink eyes ran close by her.";
+		uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+		uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+		bool ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
+			qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
+		if (ok)
+			printQr(qrcode);
+	}
+}
+
+
+// Creates QR Codes with manually specified segments for better compactness.
+static void doSegmentDemo(void) {
+	{  // Illustration "silver"
+		const char *silver0 = "THE SQUARE ROOT OF 2 IS 1.";
+		const char *silver1 = "41421356237309504880168872420969807856967187537694807317667973799";
+		uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+		uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+		bool ok;
+		{
+			char *concat = calloc(strlen(silver0) + strlen(silver1) + 1, sizeof(char));
+			strcat(concat, silver0);
+			strcat(concat, silver1);
+			ok = qrcodegen_encodeText(concat, tempBuffer, qrcode, qrcodegen_Ecc_LOW,
+				qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
+			if (ok)
+				printQr(qrcode);
+			free(concat);
+		}
+		{
+			uint8_t *segBuf0 = malloc(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, strlen(silver0)) * sizeof(uint8_t));
+			uint8_t *segBuf1 = malloc(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, strlen(silver1)) * sizeof(uint8_t));
+			struct qrcodegen_Segment segs[] = {
+				qrcodegen_makeAlphanumeric(silver0, segBuf0),
+				qrcodegen_makeNumeric(silver1, segBuf1),
+			};
+			ok = qrcodegen_encodeSegments(segs, sizeof(segs) / sizeof(segs[0]), qrcodegen_Ecc_LOW, tempBuffer, qrcode);
+			free(segBuf0);
+			free(segBuf1);
+			if (ok)
+				printQr(qrcode);
+		}
+	}
+	
+	{  // Illustration "golden"
+		const char *golden0 = "Golden ratio \xCF\x86 = 1.";
+		const char *golden1 = "6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374";
+		const char *golden2 = "......";
+		uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+		uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+		bool ok;
+		{
+			char *concat = calloc(strlen(golden0) + strlen(golden1) + strlen(golden2) + 1, sizeof(char));
+			strcat(concat, golden0);
+			strcat(concat, golden1);
+			strcat(concat, golden2);
+			ok = qrcodegen_encodeText(concat, tempBuffer, qrcode, qrcodegen_Ecc_LOW,
+				qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
+			if (ok)
+				printQr(qrcode);
+			free(concat);
+		}
+		{
+			uint8_t *bytes = malloc(strlen(golden0) * sizeof(uint8_t));
+			for (size_t i = 0, len = strlen(golden0); i < len; i++)
+				bytes[i] = (uint8_t)golden0[i];
+			uint8_t *segBuf0 = malloc(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_BYTE, strlen(golden0)) * sizeof(uint8_t));
+			uint8_t *segBuf1 = malloc(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, strlen(golden1)) * sizeof(uint8_t));
+			uint8_t *segBuf2 = malloc(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, strlen(golden2)) * sizeof(uint8_t));
+			struct qrcodegen_Segment segs[] = {
+				qrcodegen_makeBytes(bytes, strlen(golden0), segBuf0),
+				qrcodegen_makeNumeric(golden1, segBuf1),
+				qrcodegen_makeAlphanumeric(golden2, segBuf2),
+			};
+			free(bytes);
+			ok = qrcodegen_encodeSegments(segs, sizeof(segs) / sizeof(segs[0]), qrcodegen_Ecc_LOW, tempBuffer, qrcode);
+			free(segBuf0);
+			free(segBuf1);
+			free(segBuf2);
+			if (ok)
+				printQr(qrcode);
+		}
+	}
+	
+	{  // Illustration "Madoka": kanji, kana, Greek, Cyrillic, full-width Latin characters
+		uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+		uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+		bool ok;
+		{
+			const char *madoka =  // Encoded in UTF-8
+				"\xE3\x80\x8C\xE9\xAD\x94\xE6\xB3\x95\xE5"
+				"\xB0\x91\xE5\xA5\xB3\xE3\x81\xBE\xE3\x81"
+				"\xA9\xE3\x81\x8B\xE2\x98\x86\xE3\x83\x9E"
+				"\xE3\x82\xAE\xE3\x82\xAB\xE3\x80\x8D\xE3"
+				"\x81\xA3\xE3\x81\xA6\xE3\x80\x81\xE3\x80"
+				"\x80\xD0\x98\xD0\x90\xD0\x98\xE3\x80\x80"
+				"\xEF\xBD\x84\xEF\xBD\x85\xEF\xBD\x93\xEF"
+				"\xBD\x95\xE3\x80\x80\xCE\xBA\xCE\xB1\xEF"
+				"\xBC\x9F";
+			ok = qrcodegen_encodeText(madoka, tempBuffer, qrcode, qrcodegen_Ecc_LOW,
+				qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
+			if (ok)
+				printQr(qrcode);
+		}
+		{
+			const int kanjiChars[] = {  // Kanji mode encoding (13 bits per character)
+				0x0035, 0x1002, 0x0FC0, 0x0AED, 0x0AD7,
+				0x015C, 0x0147, 0x0129, 0x0059, 0x01BD,
+				0x018D, 0x018A, 0x0036, 0x0141, 0x0144,
+				0x0001, 0x0000, 0x0249, 0x0240, 0x0249,
+				0x0000, 0x0104, 0x0105, 0x0113, 0x0115,
+				0x0000, 0x0208, 0x01FF, 0x0008,
+			};
+			size_t len = sizeof(kanjiChars) / sizeof(kanjiChars[0]);
+			uint8_t *segBuf = calloc(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_KANJI, len), sizeof(uint8_t));
+			struct qrcodegen_Segment seg;
+			seg.mode = qrcodegen_Mode_KANJI;
+			seg.numChars = len;
+			seg.bitLength = 0;
+			for (size_t i = 0; i < len; i++) {
+				for (int j = 12; j >= 0; j--, seg.bitLength++)
+					segBuf[seg.bitLength >> 3] |= ((kanjiChars[i] >> j) & 1) << (7 - (seg.bitLength & 7));
+			}
+			seg.data = segBuf;
+			ok = qrcodegen_encodeSegments(&seg, 1, qrcodegen_Ecc_LOW, tempBuffer, qrcode);
+			free(segBuf);
+			if (ok)
+				printQr(qrcode);
+		}
+	}
+}
+
+
+// Creates QR Codes with the same size and contents but different mask patterns.
+static void doMaskDemo(void) {
+	{  // Project Nayuki URL
+		uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+		uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+		bool ok;
+		
+		ok = qrcodegen_encodeText("https://www.nayuki.io/", tempBuffer, qrcode,
+			qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
+		if (ok)
+			printQr(qrcode);
+		
+		ok = qrcodegen_encodeText("https://www.nayuki.io/", tempBuffer, qrcode,
+			qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_3, true);
+		if (ok)
+			printQr(qrcode);
+	}
+	
+	{  // Chinese text as UTF-8
+		const char *text =
+			"\xE7\xB6\xAD\xE5\x9F\xBA\xE7\x99\xBE\xE7\xA7\x91\xEF\xBC\x88\x57\x69\x6B\x69\x70"
+			"\x65\x64\x69\x61\xEF\xBC\x8C\xE8\x81\x86\xE8\x81\xBD\x69\x2F\xCB\x8C\x77\xC9\xAA"
+			"\x6B\xE1\xB5\xBB\xCB\x88\x70\x69\xCB\x90\x64\x69\x2E\xC9\x99\x2F\xEF\xBC\x89\xE6"
+			"\x98\xAF\xE4\xB8\x80\xE5\x80\x8B\xE8\x87\xAA\xE7\x94\xB1\xE5\x85\xA7\xE5\xAE\xB9"
+			"\xE3\x80\x81\xE5\x85\xAC\xE9\x96\x8B\xE7\xB7\xA8\xE8\xBC\xAF\xE4\xB8\x94\xE5\xA4"
+			"\x9A\xE8\xAA\x9E\xE8\xA8\x80\xE7\x9A\x84\xE7\xB6\xB2\xE8\xB7\xAF\xE7\x99\xBE\xE7"
+			"\xA7\x91\xE5\x85\xA8\xE6\x9B\xB8\xE5\x8D\x94\xE4\xBD\x9C\xE8\xA8\x88\xE7\x95\xAB";
+		uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
+		uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
+		bool ok;
+		
+		ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
+			qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_0, true);
+		if (ok)
+			printQr(qrcode);
+		
+		ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
+			qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_1, true);
+		if (ok)
+			printQr(qrcode);
+		
+		ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
+			qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_5, true);
+		if (ok)
+			printQr(qrcode);
+		
+		ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
+			qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_7, true);
+		if (ok)
+			printQr(qrcode);
+	}
+}
+
+
+
+/*---- Utilities ----*/
+
+// Prints the given QR Code to the console.
+static void printQr(const uint8_t qrcode[]) {
+	int size = qrcodegen_getSize(qrcode);
+	int border = 4;
+	for (int y = -border; y < size + border; y++) {
+		for (int x = -border; x < size + border; x++) {
+			fputs((qrcodegen_getModule(qrcode, x, y) ? "##" : "  "), stdout);
+		}
+		fputs("\n", stdout);
+	}
+	fputs("\n", stdout);
+}
diff --git a/src/third_party/QR-Code-generator/c/qrcodegen-test.c b/src/third_party/QR-Code-generator/c/qrcodegen-test.c
new file mode 100644
index 0000000..4f9c5c0
--- /dev/null
+++ b/src/third_party/QR-Code-generator/c/qrcodegen-test.c
@@ -0,0 +1,1081 @@
+/* 
+ * QR Code generator test suite (C)
+ * 
+ * When compiling this program, the library qrcodegen.c needs QRCODEGEN_TEST
+ * to be defined. Run this command line program with no arguments.
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "qrcodegen.h"
+
+#define ARRAY_LENGTH(name)  (sizeof(name) / sizeof(name[0]))
+
+#ifndef __cplusplus
+	#define MALLOC(num, type)  malloc((num) * sizeof(type))
+#else
+	#define MALLOC(num, type)  static_cast<type*>(malloc((num) * sizeof(type)))
+#endif
+
+
+// Global variables
+static int numTestCases = 0;
+
+
+// Prototypes of private functions under test
+extern const int8_t ECC_CODEWORDS_PER_BLOCK[4][41];
+extern const int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41];
+void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen);
+void appendErrorCorrection(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]);
+int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl);
+int getNumRawDataModules(int version);
+void calcReedSolomonGenerator(int degree, uint8_t result[]);
+void calcReedSolomonRemainder(const uint8_t data[], int dataLen, const uint8_t generator[], int degree, uint8_t result[]);
+uint8_t finiteFieldMultiply(uint8_t x, uint8_t y);
+void initializeFunctionModules(int version, uint8_t qrcode[]);
+int getAlignmentPatternPositions(int version, uint8_t result[7]);
+bool getModule(const uint8_t qrcode[], int x, int y);
+void setModule(uint8_t qrcode[], int x, int y, bool isBlack);
+void setModuleBounded(uint8_t qrcode[], int x, int y, bool isBlack);
+int calcSegmentBitLength(enum qrcodegen_Mode mode, size_t numChars);
+int getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int version);
+
+
+/*---- Test cases ----*/
+
+static void testAppendBitsToBuffer(void) {
+	{
+		uint8_t buf[1] = {0};
+		int bitLen = 0;
+		appendBitsToBuffer(0, 0, buf, &bitLen);
+		assert(bitLen == 0);
+		assert(buf[0] == 0);
+		appendBitsToBuffer(1, 1, buf, &bitLen);
+		assert(bitLen == 1);
+		assert(buf[0] == 0x80);
+		appendBitsToBuffer(0, 1, buf, &bitLen);
+		assert(bitLen == 2);
+		assert(buf[0] == 0x80);
+		appendBitsToBuffer(5, 3, buf, &bitLen);
+		assert(bitLen == 5);
+		assert(buf[0] == 0xA8);
+		appendBitsToBuffer(6, 3, buf, &bitLen);
+		assert(bitLen == 8);
+		assert(buf[0] == 0xAE);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[6] = {0};
+		int bitLen = 0;
+		appendBitsToBuffer(16942, 16, buf, &bitLen);
+		assert(bitLen == 16);
+		assert(buf[0] == 0x42 && buf[1] == 0x2E && buf[2] == 0x00 && buf[3] == 0x00 && buf[4] == 0x00 && buf[5] == 0x00);
+		appendBitsToBuffer(10, 7, buf, &bitLen);
+		assert(bitLen == 23);
+		assert(buf[0] == 0x42 && buf[1] == 0x2E && buf[2] == 0x14 && buf[3] == 0x00 && buf[4] == 0x00 && buf[5] == 0x00);
+		appendBitsToBuffer(15, 4, buf, &bitLen);
+		assert(bitLen == 27);
+		assert(buf[0] == 0x42 && buf[1] == 0x2E && buf[2] == 0x15 && buf[3] == 0xE0 && buf[4] == 0x00 && buf[5] == 0x00);
+		appendBitsToBuffer(26664, 15, buf, &bitLen);
+		assert(bitLen == 42);
+		assert(buf[0] == 0x42 && buf[1] == 0x2E && buf[2] == 0x15 && buf[3] == 0xFA && buf[4] == 0x0A && buf[5] == 0x00);
+		numTestCases++;
+	}
+}
+
+
+// Ported from the Java version of the code.
+static uint8_t *appendErrorCorrectionReference(const uint8_t *data, int version, enum qrcodegen_Ecc ecl) {
+	// Calculate parameter numbers
+	int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[(int)ecl][version];
+	int blockEccLen = ECC_CODEWORDS_PER_BLOCK[(int)ecl][version];
+	int rawCodewords = getNumRawDataModules(version) / 8;
+	int numShortBlocks = numBlocks - rawCodewords % numBlocks;
+	int shortBlockLen = rawCodewords / numBlocks;
+	
+	// Split data into blocks and append ECC to each block
+	uint8_t **blocks = MALLOC(numBlocks, uint8_t*);
+	uint8_t *generator = MALLOC(blockEccLen, uint8_t);
+	calcReedSolomonGenerator(blockEccLen, generator);
+	for (int i = 0, k = 0; i < numBlocks; i++) {
+		uint8_t *block = MALLOC(shortBlockLen + 1, uint8_t);
+		int blockDataLen = shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1);
+		memcpy(block, &data[k], blockDataLen * sizeof(uint8_t));
+		calcReedSolomonRemainder(&data[k], blockDataLen, generator, blockEccLen, &block[shortBlockLen + 1 - blockEccLen]);
+		k += blockDataLen;
+		blocks[i] = block;
+	}
+	free(generator);
+	
+	// Interleave (not concatenate) the bytes from every block into a single sequence
+	uint8_t *result = MALLOC(rawCodewords, uint8_t);
+	for (int i = 0, k = 0; i < shortBlockLen + 1; i++) {
+		for (int j = 0; j < numBlocks; j++) {
+			// Skip the padding byte in short blocks
+			if (i != shortBlockLen - blockEccLen || j >= numShortBlocks) {
+				result[k] = blocks[j][i];
+				k++;
+			}
+		}
+	}
+	for (int i = 0; i < numBlocks; i++)
+		free(blocks[i]);
+	free(blocks);
+	return result;
+}
+
+
+static void testAppendErrorCorrection(void) {
+	for (int version = 1; version <= 40; version++) {
+		for (int ecl = 0; ecl < 4; ecl++) {
+			int dataLen = getNumDataCodewords(version, (enum qrcodegen_Ecc)ecl);
+			uint8_t *pureData = MALLOC(dataLen, uint8_t);
+			for (int i = 0; i < dataLen; i++)
+				pureData[i] = rand() % 256;
+			uint8_t *expectOutput = appendErrorCorrectionReference(pureData, version, (enum qrcodegen_Ecc)ecl);
+			
+			int dataAndEccLen = getNumRawDataModules(version) / 8;
+			uint8_t *paddedData = MALLOC(dataAndEccLen, uint8_t);
+			memcpy(paddedData, pureData, dataLen * sizeof(uint8_t));
+			uint8_t *actualOutput = MALLOC(dataAndEccLen, uint8_t);
+			appendErrorCorrection(paddedData, version, (enum qrcodegen_Ecc)ecl, actualOutput);
+			
+			assert(memcmp(actualOutput, expectOutput, dataAndEccLen * sizeof(uint8_t)) == 0);
+			free(pureData);
+			free(expectOutput);
+			free(paddedData);
+			free(actualOutput);
+			numTestCases++;
+		}
+	}
+}
+
+
+static void testGetNumDataCodewords(void) {
+	const int cases[][3] = {
+		{ 3, 1,   44},
+		{ 3, 2,   34},
+		{ 3, 3,   26},
+		{ 6, 0,  136},
+		{ 7, 0,  156},
+		{ 9, 0,  232},
+		{ 9, 1,  182},
+		{12, 3,  158},
+		{15, 0,  523},
+		{16, 2,  325},
+		{19, 3,  341},
+		{21, 0,  932},
+		{22, 0, 1006},
+		{22, 1,  782},
+		{22, 3,  442},
+		{24, 0, 1174},
+		{24, 3,  514},
+		{28, 0, 1531},
+		{30, 3,  745},
+		{32, 3,  845},
+		{33, 0, 2071},
+		{33, 3,  901},
+		{35, 0, 2306},
+		{35, 1, 1812},
+		{35, 2, 1286},
+		{36, 3, 1054},
+		{37, 3, 1096},
+		{39, 1, 2216},
+		{40, 1, 2334},
+	};
+	for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+		const int *tc = cases[i];
+		assert(getNumDataCodewords(tc[0], (enum qrcodegen_Ecc)tc[1]) == tc[2]);
+		numTestCases++;
+	}
+}
+
+
+static void testGetNumRawDataModules(void) {
+	const int cases[][2] = {
+		{ 1,   208},
+		{ 2,   359},
+		{ 3,   567},
+		{ 6,  1383},
+		{ 7,  1568},
+		{12,  3728},
+		{15,  5243},
+		{18,  7211},
+		{22, 10068},
+		{26, 13652},
+		{32, 19723},
+		{37, 25568},
+		{40, 29648},
+	};
+	for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+		const int *tc = cases[i];
+		assert(getNumRawDataModules(tc[0]) == tc[1]);
+		numTestCases++;
+	}
+}
+
+
+static void testCalcReedSolomonGenerator(void) {
+	uint8_t generator[30];
+	
+	calcReedSolomonGenerator(1, generator);
+	assert(generator[0] == 0x01);
+	numTestCases++;
+	
+	calcReedSolomonGenerator(2, generator);
+	assert(generator[0] == 0x03);
+	assert(generator[1] == 0x02);
+	numTestCases++;
+	
+	calcReedSolomonGenerator(5, generator);
+	assert(generator[0] == 0x1F);
+	assert(generator[1] == 0xC6);
+	assert(generator[2] == 0x3F);
+	assert(generator[3] == 0x93);
+	assert(generator[4] == 0x74);
+	numTestCases++;
+	
+	calcReedSolomonGenerator(30, generator);
+	assert(generator[ 0] == 0xD4);
+	assert(generator[ 1] == 0xF6);
+	assert(generator[ 5] == 0xC0);
+	assert(generator[12] == 0x16);
+	assert(generator[13] == 0xD9);
+	assert(generator[20] == 0x12);
+	assert(generator[27] == 0x6A);
+	assert(generator[29] == 0x96);
+	numTestCases++;
+}
+
+
+static void testCalcReedSolomonRemainder(void) {
+	{
+		uint8_t data[1];
+		uint8_t generator[3];
+		uint8_t remainder[ARRAY_LENGTH(generator)];
+		calcReedSolomonGenerator(ARRAY_LENGTH(generator), generator);
+		calcReedSolomonRemainder(data, 0, generator, ARRAY_LENGTH(generator), remainder);
+		assert(remainder[0] == 0);
+		assert(remainder[1] == 0);
+		assert(remainder[2] == 0);
+		numTestCases++;
+	}
+	{
+		uint8_t data[2] = {0, 1};
+		uint8_t generator[4];
+		uint8_t remainder[ARRAY_LENGTH(generator)];
+		calcReedSolomonGenerator(ARRAY_LENGTH(generator), generator);
+		calcReedSolomonRemainder(data, ARRAY_LENGTH(data), generator, ARRAY_LENGTH(generator), remainder);
+		assert(remainder[0] == generator[0]);
+		assert(remainder[1] == generator[1]);
+		assert(remainder[2] == generator[2]);
+		assert(remainder[3] == generator[3]);
+		numTestCases++;
+	}
+	{
+		uint8_t data[5] = {0x03, 0x3A, 0x60, 0x12, 0xC7};
+		uint8_t generator[5];
+		uint8_t remainder[ARRAY_LENGTH(generator)];
+		calcReedSolomonGenerator(ARRAY_LENGTH(generator), generator);
+		calcReedSolomonRemainder(data, ARRAY_LENGTH(data), generator, ARRAY_LENGTH(generator), remainder);
+		assert(remainder[0] == 0xCB);
+		assert(remainder[1] == 0x36);
+		assert(remainder[2] == 0x16);
+		assert(remainder[3] == 0xFA);
+		assert(remainder[4] == 0x9D);
+		numTestCases++;
+	}
+	{
+		uint8_t data[43] = {
+			0x38, 0x71, 0xDB, 0xF9, 0xD7, 0x28, 0xF6, 0x8E, 0xFE, 0x5E,
+			0xE6, 0x7D, 0x7D, 0xB2, 0xA5, 0x58, 0xBC, 0x28, 0x23, 0x53,
+			0x14, 0xD5, 0x61, 0xC0, 0x20, 0x6C, 0xDE, 0xDE, 0xFC, 0x79,
+			0xB0, 0x8B, 0x78, 0x6B, 0x49, 0xD0, 0x1A, 0xAD, 0xF3, 0xEF,
+			0x52, 0x7D, 0x9A,
+		};
+		uint8_t generator[30];
+		uint8_t remainder[ARRAY_LENGTH(generator)];
+		calcReedSolomonGenerator(ARRAY_LENGTH(generator), generator);
+		calcReedSolomonRemainder(data, ARRAY_LENGTH(data), generator, ARRAY_LENGTH(generator), remainder);
+		assert(remainder[ 0] == 0xCE);
+		assert(remainder[ 1] == 0xF0);
+		assert(remainder[ 2] == 0x31);
+		assert(remainder[ 3] == 0xDE);
+		assert(remainder[ 8] == 0xE1);
+		assert(remainder[12] == 0xCA);
+		assert(remainder[17] == 0xE3);
+		assert(remainder[19] == 0x85);
+		assert(remainder[20] == 0x50);
+		assert(remainder[24] == 0xBE);
+		assert(remainder[29] == 0xB3);
+		numTestCases++;
+	}
+}
+
+
+static void testFiniteFieldMultiply(void) {
+	const uint8_t cases[][3] = {
+		{0x00, 0x00, 0x00},
+		{0x01, 0x01, 0x01},
+		{0x02, 0x02, 0x04},
+		{0x00, 0x6E, 0x00},
+		{0xB2, 0xDD, 0xE6},
+		{0x41, 0x11, 0x25},
+		{0xB0, 0x1F, 0x11},
+		{0x05, 0x75, 0xBC},
+		{0x52, 0xB5, 0xAE},
+		{0xA8, 0x20, 0xA4},
+		{0x0E, 0x44, 0x9F},
+		{0xD4, 0x13, 0xA0},
+		{0x31, 0x10, 0x37},
+		{0x6C, 0x58, 0xCB},
+		{0xB6, 0x75, 0x3E},
+		{0xFF, 0xFF, 0xE2},
+	};
+	for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+		const uint8_t *tc = cases[i];
+		assert(finiteFieldMultiply(tc[0], tc[1]) == tc[2]);
+		numTestCases++;
+	}
+}
+
+
+static void testInitializeFunctionModulesEtc(void) {
+	for (int ver = 1; ver <= 40; ver++) {
+		uint8_t *qrcode = MALLOC(qrcodegen_BUFFER_LEN_FOR_VERSION(ver), uint8_t);
+		assert(qrcode != NULL);
+		initializeFunctionModules(ver, qrcode);
+		
+		int size = qrcodegen_getSize(qrcode);
+		if (ver == 1)
+			assert(size == 21);
+		else if (ver == 40)
+			assert(size == 177);
+		else
+			assert(size == ver * 4 + 17);
+		
+		bool hasWhite = false;
+		bool hasBlack = false;
+		for (int y = 0; y < size; y++) {
+			for (int x = 0; x < size; x++) {
+				bool color = qrcodegen_getModule(qrcode, x, y);
+				if (color)
+					hasBlack = true;
+				else
+					hasWhite = true;
+			}
+		}
+		assert(hasWhite && hasBlack);
+		free(qrcode);
+		numTestCases++;
+	}
+}
+
+
+static void testGetAlignmentPatternPositions(void) {
+	const int cases[][9] = {
+		{ 1, 0,  -1,  -1,  -1,  -1,  -1,  -1,  -1},
+		{ 2, 2,   6,  18,  -1,  -1,  -1,  -1,  -1},
+		{ 3, 2,   6,  22,  -1,  -1,  -1,  -1,  -1},
+		{ 6, 2,   6,  34,  -1,  -1,  -1,  -1,  -1},
+		{ 7, 3,   6,  22,  38,  -1,  -1,  -1,  -1},
+		{ 8, 3,   6,  24,  42,  -1,  -1,  -1,  -1},
+		{16, 4,   6,  26,  50,  74,  -1,  -1,  -1},
+		{25, 5,   6,  32,  58,  84, 110,  -1,  -1},
+		{32, 6,   6,  34,  60,  86, 112, 138,  -1},
+		{33, 6,   6,  30,  58,  86, 114, 142,  -1},
+		{39, 7,   6,  26,  54,  82, 110, 138, 166},
+		{40, 7,   6,  30,  58,  86, 114, 142, 170},
+	};
+	for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+		const int *tc = cases[i];
+		uint8_t pos[7];
+		int num = getAlignmentPatternPositions(tc[0], pos);
+		assert(num == tc[1]);
+		for (int j = 0; j < num; j++)
+			assert(pos[j] == tc[2 + j]);
+		numTestCases++;
+	}
+}
+
+
+static void testGetSetModule(void) {
+	uint8_t qrcode[qrcodegen_BUFFER_LEN_FOR_VERSION(23)];
+	initializeFunctionModules(23, qrcode);
+	int size = qrcodegen_getSize(qrcode);
+	
+	for (int y = 0; y < size; y++) {  // Clear all to white
+		for (int x = 0; x < size; x++)
+			setModule(qrcode, x, y, false);
+	}
+	for (int y = 0; y < size; y++) {  // Check all white
+		for (int x = 0; x < size; x++)
+			assert(qrcodegen_getModule(qrcode, x, y) == false);
+	}
+	for (int y = 0; y < size; y++) {  // Set all to black
+		for (int x = 0; x < size; x++)
+			setModule(qrcode, x, y, true);
+	}
+	for (int y = 0; y < size; y++) {  // Check all black
+		for (int x = 0; x < size; x++)
+			assert(qrcodegen_getModule(qrcode, x, y) == true);
+	}
+	
+	// Set some out of bounds modules to white
+	setModuleBounded(qrcode, -1, -1, false);
+	setModuleBounded(qrcode, -1, 0, false);
+	setModuleBounded(qrcode, 0, -1, false);
+	setModuleBounded(qrcode, size, 5, false);
+	setModuleBounded(qrcode, 72, size, false);
+	setModuleBounded(qrcode, size, size, false);
+	for (int y = 0; y < size; y++) {  // Check all black
+		for (int x = 0; x < size; x++)
+			assert(qrcodegen_getModule(qrcode, x, y) == true);
+	}
+	
+	// Set some modules to white
+	setModule(qrcode, 3, 8, false);
+	setModule(qrcode, 61, 49, false);
+	for (int y = 0; y < size; y++) {  // Check most black
+		for (int x = 0; x < size; x++) {
+			bool white = (x == 3 && y == 8) || (x == 61 && y == 49);
+			assert(qrcodegen_getModule(qrcode, x, y) != white);
+		}
+	}
+	numTestCases++;
+}
+
+
+static void testGetSetModuleRandomly(void) {
+	uint8_t qrcode[qrcodegen_BUFFER_LEN_FOR_VERSION(1)];
+	initializeFunctionModules(1, qrcode);
+	int size = qrcodegen_getSize(qrcode);
+	
+	bool modules[21][21];
+	for (int y = 0; y < size; y++) {
+		for (int x = 0; x < size; x++)
+			modules[y][x] = qrcodegen_getModule(qrcode, x, y);
+	}
+	
+	long trials = 100000;
+	for (long i = 0; i < trials; i++) {
+		int x = rand() % (size * 2) - size / 2;
+		int y = rand() % (size * 2) - size / 2;
+		bool isInBounds = 0 <= x && x < size && 0 <= y && y < size;
+		bool oldColor = isInBounds && modules[y][x];
+		if (isInBounds)
+			assert(getModule(qrcode, x, y) == oldColor);
+		assert(qrcodegen_getModule(qrcode, x, y) == oldColor);
+		
+		bool newColor = rand() % 2 == 0;
+		if (isInBounds)
+			modules[y][x] = newColor;
+		if (isInBounds && rand() % 2 == 0)
+			setModule(qrcode, x, y, newColor);
+		else
+			setModuleBounded(qrcode, x, y, newColor);
+	}
+	numTestCases++;
+}
+
+
+static void testIsAlphanumeric(void) {
+	struct TestCase {
+		bool answer;
+		const char *text;
+	};
+	const struct TestCase cases[] = {
+		{true, ""},
+		{true, "0"},
+		{true, "A"},
+		{false, "a"},
+		{true, " "},
+		{true, "."},
+		{true, "*"},
+		{false, ","},
+		{false, "|"},
+		{false, "@"},
+		{true, "XYZ"},
+		{false, "XYZ!"},
+		{true, "79068"},
+		{true, "+123 ABC$"},
+		{false, "\x01"},
+		{false, "\x7F"},
+		{false, "\x80"},
+		{false, "\xC0"},
+		{false, "\xFF"},
+	};
+	for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+		assert(qrcodegen_isAlphanumeric(cases[i].text) == cases[i].answer);
+		numTestCases++;
+	}
+}
+
+
+static void testIsNumeric(void) {
+	struct TestCase {
+		bool answer;
+		const char *text;
+	};
+	const struct TestCase cases[] = {
+		{true, ""},
+		{true, "0"},
+		{false, "A"},
+		{false, "a"},
+		{false, " "},
+		{false, "."},
+		{false, "*"},
+		{false, ","},
+		{false, "|"},
+		{false, "@"},
+		{false, "XYZ"},
+		{false, "XYZ!"},
+		{true, "79068"},
+		{false, "+123 ABC$"},
+		{false, "\x01"},
+		{false, "\x7F"},
+		{false, "\x80"},
+		{false, "\xC0"},
+		{false, "\xFF"},
+	};
+	for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+		assert(qrcodegen_isNumeric(cases[i].text) == cases[i].answer);
+		numTestCases++;
+	}
+}
+
+
+static void testCalcSegmentBufferSize(void) {
+	{
+		const size_t cases[][2] = {
+			{0, 0},
+			{1, 1},
+			{2, 1},
+			{3, 2},
+			{4, 2},
+			{5, 3},
+			{6, 3},
+			{1472, 614},
+			{2097, 874},
+			{5326, 2220},
+			{9828, 4095},
+			{9829, 4096},
+			{9830, 4096},
+			{9831, SIZE_MAX},
+			{9832, SIZE_MAX},
+			{12000, SIZE_MAX},
+			{28453, SIZE_MAX},
+			{55555, SIZE_MAX},
+			{SIZE_MAX / 6, SIZE_MAX},
+			{SIZE_MAX / 4, SIZE_MAX},
+			{SIZE_MAX / 2, SIZE_MAX},
+			{SIZE_MAX / 1, SIZE_MAX},
+		};
+		for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+			assert(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, cases[i][0]) == cases[i][1]);
+			numTestCases++;
+		}
+	}
+	{
+		const size_t cases[][2] = {
+			{0, 0},
+			{1, 1},
+			{2, 2},
+			{3, 3},
+			{4, 3},
+			{5, 4},
+			{6, 5},
+			{1472, 1012},
+			{2097, 1442},
+			{5326, 3662},
+			{5955, 4095},
+			{5956, 4095},
+			{5957, 4096},
+			{5958, SIZE_MAX},
+			{5959, SIZE_MAX},
+			{12000, SIZE_MAX},
+			{28453, SIZE_MAX},
+			{55555, SIZE_MAX},
+			{SIZE_MAX / 10, SIZE_MAX},
+			{SIZE_MAX / 8, SIZE_MAX},
+			{SIZE_MAX / 5, SIZE_MAX},
+			{SIZE_MAX / 2, SIZE_MAX},
+			{SIZE_MAX / 1, SIZE_MAX},
+		};
+		for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+			assert(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, cases[i][0]) == cases[i][1]);
+			numTestCases++;
+		}
+	}
+	{
+		const size_t cases[][2] = {
+			{0, 0},
+			{1, 1},
+			{2, 2},
+			{3, 3},
+			{1472, 1472},
+			{2097, 2097},
+			{4094, 4094},
+			{4095, 4095},
+			{4096, SIZE_MAX},
+			{4097, SIZE_MAX},
+			{5957, SIZE_MAX},
+			{12000, SIZE_MAX},
+			{28453, SIZE_MAX},
+			{55555, SIZE_MAX},
+			{SIZE_MAX / 16 + 1, SIZE_MAX},
+			{SIZE_MAX / 14, SIZE_MAX},
+			{SIZE_MAX / 9, SIZE_MAX},
+			{SIZE_MAX / 7, SIZE_MAX},
+			{SIZE_MAX / 4, SIZE_MAX},
+			{SIZE_MAX / 3, SIZE_MAX},
+			{SIZE_MAX / 2, SIZE_MAX},
+			{SIZE_MAX / 1, SIZE_MAX},
+		};
+		for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+			assert(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_BYTE, cases[i][0]) == cases[i][1]);
+			numTestCases++;
+		}
+	}
+	{
+		const size_t cases[][2] = {
+			{0, 0},
+			{1, 2},
+			{2, 4},
+			{3, 5},
+			{1472, 2392},
+			{2097, 3408},
+			{2519, 4094},
+			{2520, 4095},
+			{2521, SIZE_MAX},
+			{5957, SIZE_MAX},
+			{2522, SIZE_MAX},
+			{12000, SIZE_MAX},
+			{28453, SIZE_MAX},
+			{55555, SIZE_MAX},
+			{SIZE_MAX / 13 + 1, SIZE_MAX},
+			{SIZE_MAX / 12, SIZE_MAX},
+			{SIZE_MAX / 9, SIZE_MAX},
+			{SIZE_MAX / 4, SIZE_MAX},
+			{SIZE_MAX / 3, SIZE_MAX},
+			{SIZE_MAX / 2, SIZE_MAX},
+			{SIZE_MAX / 1, SIZE_MAX},
+		};
+		for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+			assert(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_KANJI, cases[i][0]) == cases[i][1]);
+			numTestCases++;
+		}
+	}
+	{
+		assert(qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ECI, 0) == 3);
+		numTestCases++;
+	}
+}
+
+
+static void testCalcSegmentBitLength(void) {
+	{
+		const int cases[][2] = {
+			{0, 0},
+			{1, 4},
+			{2, 7},
+			{3, 10},
+			{4, 14},
+			{5, 17},
+			{6, 20},
+			{1472, 4907},
+			{2097, 6990},
+			{5326, 17754},
+			{9828, 32760},
+			{9829, 32764},
+			{9830, 32767},
+			{9831, -1},
+			{9832, -1},
+			{12000, -1},
+			{28453, -1},
+			{INT_MAX / 3, -1},
+			{INT_MAX / 2, -1},
+			{INT_MAX / 1, -1},
+		};
+		for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+			assert(calcSegmentBitLength(qrcodegen_Mode_NUMERIC, cases[i][0]) == cases[i][1]);
+			numTestCases++;
+		}
+	}
+	{
+		const int cases[][2] = {
+			{0, 0},
+			{1, 6},
+			{2, 11},
+			{3, 17},
+			{4, 22},
+			{5, 28},
+			{6, 33},
+			{1472, 8096},
+			{2097, 11534},
+			{5326, 29293},
+			{5955, 32753},
+			{5956, 32758},
+			{5957, 32764},
+			{5958, -1},
+			{5959, -1},
+			{12000, -1},
+			{28453, -1},
+			{INT_MAX / 5, -1},
+			{INT_MAX / 4, -1},
+			{INT_MAX / 3, -1},
+			{INT_MAX / 2, -1},
+			{INT_MAX / 1, -1},
+		};
+		for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+			assert(calcSegmentBitLength(qrcodegen_Mode_ALPHANUMERIC, cases[i][0]) == cases[i][1]);
+			numTestCases++;
+		}
+	}
+	{
+		const int cases[][2] = {
+			{0, 0},
+			{1, 8},
+			{2, 16},
+			{3, 24},
+			{1472, 11776},
+			{2097, 16776},
+			{4094, 32752},
+			{4095, 32760},
+			{4096, -1},
+			{4097, -1},
+			{5957, -1},
+			{12000, -1},
+			{28453, -1},
+			{INT_MAX / 8 + 1, -1},
+			{INT_MAX / 7, -1},
+			{INT_MAX / 6, -1},
+			{INT_MAX / 5, -1},
+			{INT_MAX / 4, -1},
+			{INT_MAX / 3, -1},
+			{INT_MAX / 2, -1},
+			{INT_MAX / 1, -1},
+		};
+		for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+			assert(calcSegmentBitLength(qrcodegen_Mode_BYTE, cases[i][0]) == cases[i][1]);
+			numTestCases++;
+		}
+	}
+	{
+		const int cases[][2] = {
+			{0, 0},
+			{1, 13},
+			{2, 26},
+			{3, 39},
+			{1472, 19136},
+			{2097, 27261},
+			{2519, 32747},
+			{2520, 32760},
+			{2521, -1},
+			{5957, -1},
+			{2522, -1},
+			{12000, -1},
+			{28453, -1},
+			{INT_MAX / 13 + 1, -1},
+			{INT_MAX / 12, -1},
+			{INT_MAX / 9, -1},
+			{INT_MAX / 4, -1},
+			{INT_MAX / 3, -1},
+			{INT_MAX / 2, -1},
+			{INT_MAX / 1, -1},
+		};
+		for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
+			assert(calcSegmentBitLength(qrcodegen_Mode_KANJI, cases[i][0]) == cases[i][1]);
+			numTestCases++;
+		}
+	}
+	{
+		assert(calcSegmentBitLength(qrcodegen_Mode_ECI, 0) == 24);
+		numTestCases++;
+	}
+}
+
+
+static void testMakeBytes(void) {
+	{
+		struct qrcodegen_Segment seg = qrcodegen_makeBytes(NULL, 0, NULL);
+		assert(seg.mode == qrcodegen_Mode_BYTE);
+		assert(seg.numChars == 0);
+		assert(seg.bitLength == 0);
+		numTestCases++;
+	}
+	{
+		const uint8_t data[] = {0x00};
+		uint8_t buf[1];
+		struct qrcodegen_Segment seg = qrcodegen_makeBytes(data, 1, buf);
+		assert(seg.numChars == 1);
+		assert(seg.bitLength == 8);
+		assert(seg.data[0] == 0x00);
+		numTestCases++;
+	}
+	{
+		const uint8_t data[] = {0xEF, 0xBB, 0xBF};
+		uint8_t buf[3];
+		struct qrcodegen_Segment seg = qrcodegen_makeBytes(data, 3, buf);
+		assert(seg.numChars == 3);
+		assert(seg.bitLength == 24);
+		assert(seg.data[0] == 0xEF);
+		assert(seg.data[1] == 0xBB);
+		assert(seg.data[2] == 0xBF);
+		numTestCases++;
+	}
+}
+
+
+static void testMakeNumeric(void) {
+	{
+		struct qrcodegen_Segment seg = qrcodegen_makeNumeric("", NULL);
+		assert(seg.mode == qrcodegen_Mode_NUMERIC);
+		assert(seg.numChars == 0);
+		assert(seg.bitLength == 0);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[1];
+		struct qrcodegen_Segment seg = qrcodegen_makeNumeric("9", buf);
+		assert(seg.numChars == 1);
+		assert(seg.bitLength == 4);
+		assert(seg.data[0] == 0x90);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[1];
+		struct qrcodegen_Segment seg = qrcodegen_makeNumeric("81", buf);
+		assert(seg.numChars == 2);
+		assert(seg.bitLength == 7);
+		assert(seg.data[0] == 0xA2);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[2];
+		struct qrcodegen_Segment seg = qrcodegen_makeNumeric("673", buf);
+		assert(seg.numChars == 3);
+		assert(seg.bitLength == 10);
+		assert(seg.data[0] == 0xA8);
+		assert(seg.data[1] == 0x40);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[5];
+		struct qrcodegen_Segment seg = qrcodegen_makeNumeric("3141592653", buf);
+		assert(seg.numChars == 10);
+		assert(seg.bitLength == 34);
+		assert(seg.data[0] == 0x4E);
+		assert(seg.data[1] == 0x89);
+		assert(seg.data[2] == 0xF4);
+		assert(seg.data[3] == 0x24);
+		assert(seg.data[4] == 0xC0);
+		numTestCases++;
+	}
+}
+
+
+static void testMakeAlphanumeric(void) {
+	{
+		struct qrcodegen_Segment seg = qrcodegen_makeAlphanumeric("", NULL);
+		assert(seg.mode == qrcodegen_Mode_ALPHANUMERIC);
+		assert(seg.numChars == 0);
+		assert(seg.bitLength == 0);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[1];
+		struct qrcodegen_Segment seg = qrcodegen_makeAlphanumeric("A", buf);
+		assert(seg.numChars == 1);
+		assert(seg.bitLength == 6);
+		assert(seg.data[0] == 0x28);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[2];
+		struct qrcodegen_Segment seg = qrcodegen_makeAlphanumeric("%:", buf);
+		assert(seg.numChars == 2);
+		assert(seg.bitLength == 11);
+		assert(seg.data[0] == 0xDB);
+		assert(seg.data[1] == 0x40);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[3];
+		struct qrcodegen_Segment seg = qrcodegen_makeAlphanumeric("Q R", buf);
+		assert(seg.numChars == 3);
+		assert(seg.bitLength == 17);
+		assert(seg.data[0] == 0x96);
+		assert(seg.data[1] == 0xCD);
+		assert(seg.data[2] == 0x80);
+		numTestCases++;
+	}
+}
+
+
+static void testMakeEci(void) {
+	{
+		uint8_t buf[1];
+		struct qrcodegen_Segment seg = qrcodegen_makeEci(127, buf);
+		assert(seg.mode == qrcodegen_Mode_ECI);
+		assert(seg.numChars == 0);
+		assert(seg.bitLength == 8);
+		assert(seg.data[0] == 0x7F);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[2];
+		struct qrcodegen_Segment seg = qrcodegen_makeEci(10345, buf);
+		assert(seg.numChars == 0);
+		assert(seg.bitLength == 16);
+		assert(seg.data[0] == 0xA8);
+		assert(seg.data[1] == 0x69);
+		numTestCases++;
+	}
+	{
+		uint8_t buf[3];
+		struct qrcodegen_Segment seg = qrcodegen_makeEci(999999, buf);
+		assert(seg.numChars == 0);
+		assert(seg.bitLength == 24);
+		assert(seg.data[0] == 0xCF);
+		assert(seg.data[1] == 0x42);
+		assert(seg.data[2] == 0x3F);
+		numTestCases++;
+	}
+}
+
+
+static void testGetTotalBits(void) {
+	{
+		assert(getTotalBits(NULL, 0, 1) == 0);
+		numTestCases++;
+		assert(getTotalBits(NULL, 0, 40) == 0);
+		numTestCases++;
+	}
+	{
+		struct qrcodegen_Segment segs[] = {
+			{qrcodegen_Mode_BYTE, 3, NULL, 24},
+		};
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 2) == 36);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 10) == 44);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 39) == 44);
+		numTestCases++;
+	}
+	{
+		struct qrcodegen_Segment segs[] = {
+			{qrcodegen_Mode_ECI, 0, NULL, 8},
+			{qrcodegen_Mode_NUMERIC, 7, NULL, 24},
+			{qrcodegen_Mode_ALPHANUMERIC, 1, NULL, 6},
+			{qrcodegen_Mode_KANJI, 4, NULL, 52},
+		};
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 9) == 133);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 21) == 139);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 27) == 145);
+		numTestCases++;
+	}
+	{
+		struct qrcodegen_Segment segs[] = {
+			{qrcodegen_Mode_BYTE, 4093, NULL, 32744},
+		};
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 1) == -1);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 10) == 32764);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 27) == 32764);
+		numTestCases++;
+	}
+	{
+		struct qrcodegen_Segment segs[] = {
+			{qrcodegen_Mode_NUMERIC, 2047, NULL, 6824},
+			{qrcodegen_Mode_NUMERIC, 2047, NULL, 6824},
+			{qrcodegen_Mode_NUMERIC, 2047, NULL, 6824},
+			{qrcodegen_Mode_NUMERIC, 2047, NULL, 6824},
+			{qrcodegen_Mode_NUMERIC, 1617, NULL, 5390},
+		};
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 1) == -1);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 10) == 32766);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 27) == -1);
+		numTestCases++;
+	}
+	{
+		struct qrcodegen_Segment segs[] = {
+			{qrcodegen_Mode_KANJI, 255, NULL, 3315},
+			{qrcodegen_Mode_KANJI, 255, NULL, 3315},
+			{qrcodegen_Mode_KANJI, 255, NULL, 3315},
+			{qrcodegen_Mode_KANJI, 255, NULL, 3315},
+			{qrcodegen_Mode_KANJI, 255, NULL, 3315},
+			{qrcodegen_Mode_KANJI, 255, NULL, 3315},
+			{qrcodegen_Mode_KANJI, 255, NULL, 3315},
+			{qrcodegen_Mode_KANJI, 255, NULL, 3315},
+			{qrcodegen_Mode_KANJI, 255, NULL, 3315},
+			{qrcodegen_Mode_ALPHANUMERIC, 511, NULL, 2811},
+		};
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 9) == 32767);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 26) == -1);
+		numTestCases++;
+		assert(getTotalBits(segs, ARRAY_LENGTH(segs), 40) == -1);
+		numTestCases++;
+	}
+}
+
+
+/*---- Main runner ----*/
+
+int main(void) {
+	srand(time(NULL));
+	testAppendBitsToBuffer();
+	testAppendErrorCorrection();
+	testGetNumDataCodewords();
+	testGetNumRawDataModules();
+	testCalcReedSolomonGenerator();
+	testCalcReedSolomonRemainder();
+	testFiniteFieldMultiply();
+	testInitializeFunctionModulesEtc();
+	testGetAlignmentPatternPositions();
+	testGetSetModule();
+	testGetSetModuleRandomly();
+	testIsAlphanumeric();
+	testIsNumeric();
+	testCalcSegmentBufferSize();
+	testCalcSegmentBitLength();
+	testMakeBytes();
+	testMakeNumeric();
+	testMakeAlphanumeric();
+	testMakeEci();
+	testGetTotalBits();
+	printf("All %d test cases passed\n", numTestCases);
+	return EXIT_SUCCESS;
+}
diff --git a/src/third_party/QR-Code-generator/c/qrcodegen-worker.c b/src/third_party/QR-Code-generator/c/qrcodegen-worker.c
new file mode 100644
index 0000000..9fa6433
--- /dev/null
+++ b/src/third_party/QR-Code-generator/c/qrcodegen-worker.c
@@ -0,0 +1,116 @@
+/* 
+ * QR Code generator test worker (C)
+ * 
+ * This program reads data and encoding parameters from standard input and writes
+ * QR Code bitmaps to standard output. The I/O format is one integer per line.
+ * Run with no command line arguments. The program is intended for automated
+ * batch testing of end-to-end functionality of this QR Code generator library.
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "qrcodegen.h"
+
+#ifndef __cplusplus
+	#define MALLOC(num, type)  malloc((num) * sizeof(type))
+#else
+	#define MALLOC(num, type)  static_cast<type*>(malloc((num) * sizeof(type)))
+#endif
+
+
+int main(void) {
+	while (true) {
+		
+		// Read data length or exit
+		int length;
+		if (scanf("%d", &length) != 1)
+			return EXIT_FAILURE;
+		if (length == -1)
+			break;
+		
+		// Read data bytes
+		bool isAscii = true;
+		uint8_t *data = MALLOC(length, uint8_t);
+		if (data == NULL) {
+			perror("malloc");
+			return EXIT_FAILURE;
+		}
+		for (int i = 0; i < length; i++) {
+			int b;
+			if (scanf("%d", &b) != 1)
+			return EXIT_FAILURE;
+			data[i] = (uint8_t)b;
+			isAscii &= 0 < b && b < 128;
+		}
+		
+		// Read encoding parameters
+		int errCorLvl, minVersion, maxVersion, mask, boostEcl;
+		if (scanf("%d %d %d %d %d", &errCorLvl, &minVersion, &maxVersion, &mask, &boostEcl) != 5)
+			return EXIT_FAILURE;
+		
+		// Allocate memory for QR Code
+		int bufferLen = qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion);
+		uint8_t *qrcode     = MALLOC(bufferLen, uint8_t);
+		uint8_t *tempBuffer = MALLOC(bufferLen, uint8_t);
+		if (qrcode == NULL || tempBuffer == NULL) {
+			perror("malloc");
+			return EXIT_FAILURE;
+		}
+		
+		// Try to make QR Code symbol
+		bool ok;
+		if (isAscii) {
+			char *text = MALLOC(length + 1, char);
+			for (int i = 0; i < length; i++)
+				text[i] = (char)data[i];
+			text[length] = '\0';
+			ok = qrcodegen_encodeText(text, tempBuffer, qrcode, (enum qrcodegen_Ecc)errCorLvl,
+				minVersion, maxVersion, (enum qrcodegen_Mask)mask, boostEcl == 1);
+			free(text);
+		} else if (length <= bufferLen) {
+			memcpy(tempBuffer, data, length * sizeof(data[0]));
+			ok = qrcodegen_encodeBinary(tempBuffer, (size_t)length, qrcode, (enum qrcodegen_Ecc)errCorLvl,
+				minVersion, maxVersion, (enum qrcodegen_Mask)mask, boostEcl == 1);
+		} else
+			ok = false;
+		free(data);
+		free(tempBuffer);
+		
+		if (ok) {
+			// Print grid of modules
+			int size = qrcodegen_getSize(qrcode);
+			printf("%d\n", (size - 17) / 4);
+			for (int y = 0; y < size; y++) {
+				for (int x = 0; x < size; x++)
+					printf("%d\n", qrcodegen_getModule(qrcode, x, y) ? 1 : 0);
+			}
+		} else
+			printf("-1\n");
+		free(qrcode);
+		fflush(stdout);
+	}
+	return EXIT_SUCCESS;
+}
diff --git a/src/third_party/QR-Code-generator/c/qrcodegen.c b/src/third_party/QR-Code-generator/c/qrcodegen.c
new file mode 100644
index 0000000..d448f91
--- /dev/null
+++ b/src/third_party/QR-Code-generator/c/qrcodegen.c
@@ -0,0 +1,1024 @@
+/* 
+ * QR Code generator library (C)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include "qrcodegen.h"
+
+#ifndef QRCODEGEN_TEST
+	#define testable static  // Keep functions private
+#else
+	// Expose private functions
+	#ifndef __cplusplus
+		#define testable
+	#else
+		// Needed for const variables because they are treated as implicitly 'static' in C++
+		#define testable extern
+	#endif
+#endif
+
+
+/*---- Forward declarations for private functions ----*/
+
+// Regarding all public and private functions defined in this source file:
+// - They require all pointer/array arguments to be not null.
+// - They only read input scalar/array arguments, write to output pointer/array
+//   arguments, and return scalar values; they are "pure" functions.
+// - They don't read mutable global variables or write to any global variables.
+// - They don't perform I/O, read the clock, print to console, etc.
+// - They allocate a small and constant amount of stack memory.
+// - They don't allocate or free any memory on the heap.
+// - They don't recurse or mutually recurse. All the code
+//   could be inlined into the top-level public functions.
+// - They run in at most quadratic time with respect to input arguments.
+//   Most functions run in linear time, and some in constant time.
+//   There are no unbounded loops or non-obvious termination conditions.
+// - They are completely thread-safe if the caller does not give the
+//   same writable buffer to concurrent calls to these functions.
+
+testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen);
+
+testable void appendErrorCorrection(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]);
+testable int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl);
+testable int getNumRawDataModules(int version);
+
+testable void calcReedSolomonGenerator(int degree, uint8_t result[]);
+testable void calcReedSolomonRemainder(const uint8_t data[], int dataLen,
+	const uint8_t generator[], int degree, uint8_t result[]);
+testable uint8_t finiteFieldMultiply(uint8_t x, uint8_t y);
+
+testable void initializeFunctionModules(int version, uint8_t qrcode[]);
+static void drawWhiteFunctionModules(uint8_t qrcode[], int version);
+static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[]);
+testable int getAlignmentPatternPositions(int version, uint8_t result[7]);
+static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[]);
+
+static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[]);
+static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], enum qrcodegen_Mask mask);
+static long getPenaltyScore(const uint8_t qrcode[]);
+
+testable bool getModule(const uint8_t qrcode[], int x, int y);
+testable void setModule(uint8_t qrcode[], int x, int y, bool isBlack);
+testable void setModuleBounded(uint8_t qrcode[], int x, int y, bool isBlack);
+
+testable int calcSegmentBitLength(enum qrcodegen_Mode mode, size_t numChars);
+testable int getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int version);
+static int numCharCountBits(enum qrcodegen_Mode mode, int version);
+
+
+
+/*---- Private tables of constants ----*/
+
+// For checking text and encoding segments.
+static const char *ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
+
+// For generating error correction codes.
+testable const int8_t ECC_CODEWORDS_PER_BLOCK[4][41] = {
+	// Version: (note that index 0 is for padding, and is set to an illegal value)
+	//0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+	{-1,  7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},  // Low
+	{-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28},  // Medium
+	{-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},  // Quartile
+	{-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},  // High
+};
+
+// For generating error correction codes.
+testable const int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41] = {
+	// Version: (note that index 0 is for padding, and is set to an illegal value)
+	//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+	{-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25},  // Low
+	{-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49},  // Medium
+	{-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68},  // Quartile
+	{-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81},  // High
+};
+
+// For automatic mask pattern selection.
+static const int PENALTY_N1 = 3;
+static const int PENALTY_N2 = 3;
+static const int PENALTY_N3 = 40;
+static const int PENALTY_N4 = 10;
+
+
+
+/*---- High-level QR Code encoding functions ----*/
+
+// Public function - see documentation comment in header file.
+bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
+		enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) {
+	
+	size_t textLen = strlen(text);
+	if (textLen == 0)
+		return qrcodegen_encodeSegmentsAdvanced(NULL, 0, ecl, minVersion, maxVersion, mask, boostEcl, tempBuffer, qrcode);
+	size_t bufLen = qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion);
+	
+	struct qrcodegen_Segment seg;
+	if (qrcodegen_isNumeric(text)) {
+		if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, textLen) > bufLen)
+			goto fail;
+		seg = qrcodegen_makeNumeric(text, tempBuffer);
+	} else if (qrcodegen_isAlphanumeric(text)) {
+		if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, textLen) > bufLen)
+			goto fail;
+		seg = qrcodegen_makeAlphanumeric(text, tempBuffer);
+	} else {
+		if (textLen > bufLen)
+			goto fail;
+		for (size_t i = 0; i < textLen; i++)
+			tempBuffer[i] = (uint8_t)text[i];
+		seg.mode = qrcodegen_Mode_BYTE;
+		seg.bitLength = calcSegmentBitLength(seg.mode, textLen);
+		if (seg.bitLength == -1)
+			goto fail;
+		seg.numChars = (int)textLen;
+		seg.data = tempBuffer;
+	}
+	return qrcodegen_encodeSegmentsAdvanced(&seg, 1, ecl, minVersion, maxVersion, mask, boostEcl, tempBuffer, qrcode);
+	
+fail:
+	qrcode[0] = 0;  // Set size to invalid value for safety
+	return false;
+}
+
+
+// Public function - see documentation comment in header file.
+bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[],
+		enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) {
+	
+	struct qrcodegen_Segment seg;
+	seg.mode = qrcodegen_Mode_BYTE;
+	seg.bitLength = calcSegmentBitLength(seg.mode, dataLen);
+	if (seg.bitLength == -1) {
+		qrcode[0] = 0;  // Set size to invalid value for safety
+		return false;
+	}
+	seg.numChars = (int)dataLen;
+	seg.data = dataAndTemp;
+	return qrcodegen_encodeSegmentsAdvanced(&seg, 1, ecl, minVersion, maxVersion, mask, boostEcl, dataAndTemp, qrcode);
+}
+
+
+// Appends the given sequence of bits to the given byte-based bit buffer, increasing the bit length.
+testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen) {
+	assert(0 <= numBits && numBits <= 16 && (unsigned long)val >> numBits == 0);
+	for (int i = numBits - 1; i >= 0; i--, (*bitLen)++)
+		buffer[*bitLen >> 3] |= ((val >> i) & 1) << (7 - (*bitLen & 7));
+}
+
+
+
+/*---- Error correction code generation functions ----*/
+
+// Appends error correction bytes to each block of the given data array, then interleaves bytes
+// from the blocks and stores them in the result array. data[0 : rawCodewords - totalEcc] contains
+// the input data. data[rawCodewords - totalEcc : rawCodewords] is used as a temporary work area
+// and will be clobbered by this function. The final answer is stored in result[0 : rawCodewords].
+testable void appendErrorCorrection(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]) {
+	// Calculate parameter numbers
+	assert(0 <= (int)ecl && (int)ecl < 4 && qrcodegen_VERSION_MIN <= version && version <= qrcodegen_VERSION_MAX);
+	int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[(int)ecl][version];
+	int blockEccLen = ECC_CODEWORDS_PER_BLOCK[(int)ecl][version];
+	int rawCodewords = getNumRawDataModules(version) / 8;
+	int dataLen = rawCodewords - blockEccLen * numBlocks;
+	int numShortBlocks = numBlocks - rawCodewords % numBlocks;
+	int shortBlockDataLen = rawCodewords / numBlocks - blockEccLen;
+	
+	// Split data into blocks and append ECC after all data
+	uint8_t generator[30];
+	calcReedSolomonGenerator(blockEccLen, generator);
+	for (int i = 0, j = dataLen, k = 0; i < numBlocks; i++) {
+		int blockLen = shortBlockDataLen;
+		if (i >= numShortBlocks)
+			blockLen++;
+		calcReedSolomonRemainder(&data[k], blockLen, generator, blockEccLen, &data[j]);
+		j += blockEccLen;
+		k += blockLen;
+	}
+	
+	// Interleave (not concatenate) the bytes from every block into a single sequence
+	for (int i = 0, k = 0; i < numBlocks; i++) {
+		for (int j = 0, l = i; j < shortBlockDataLen; j++, k++, l += numBlocks)
+			result[l] = data[k];
+		if (i >= numShortBlocks)
+			k++;
+	}
+	for (int i = numShortBlocks, k = (numShortBlocks + 1) * shortBlockDataLen, l = numBlocks * shortBlockDataLen;
+			i < numBlocks; i++, k += shortBlockDataLen + 1, l++)
+		result[l] = data[k];
+	for (int i = 0, k = dataLen; i < numBlocks; i++) {
+		for (int j = 0, l = dataLen + i; j < blockEccLen; j++, k++, l += numBlocks)
+			result[l] = data[k];
+	}
+}
+
+
+// Returns the number of 8-bit codewords that can be used for storing data (not ECC),
+// for the given version number and error correction level. The result is in the range [9, 2956].
+testable int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl) {
+	int v = version, e = (int)ecl;
+	assert(0 <= e && e < 4 && qrcodegen_VERSION_MIN <= v && v <= qrcodegen_VERSION_MAX);
+	return getNumRawDataModules(v) / 8 - ECC_CODEWORDS_PER_BLOCK[e][v] * NUM_ERROR_CORRECTION_BLOCKS[e][v];
+}
+
+
+// Returns the number of data bits that can be stored in a QR Code of the given version number, after
+// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
+// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
+testable int getNumRawDataModules(int version) {
+	assert(qrcodegen_VERSION_MIN <= version && version <= qrcodegen_VERSION_MAX);
+	int result = (16 * version + 128) * version + 64;
+	if (version >= 2) {
+		int numAlign = version / 7 + 2;
+		result -= (25 * numAlign - 10) * numAlign - 55;
+		if (version >= 7)
+			result -= 18 * 2;  // Subtract version information
+	}
+	return result;
+}
+
+
+
+/*---- Reed-Solomon ECC generator functions ----*/
+
+// Calculates the Reed-Solomon generator polynomial of the given degree, storing in result[0 : degree].
+testable void calcReedSolomonGenerator(int degree, uint8_t result[]) {
+	// Start with the monomial x^0
+	assert(1 <= degree && degree <= 30);
+	memset(result, 0, degree * sizeof(result[0]));
+	result[degree - 1] = 1;
+	
+	// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
+	// drop the highest term, and store the rest of the coefficients in order of descending powers.
+	// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
+	uint8_t root = 1;
+	for (int i = 0; i < degree; i++) {
+		// Multiply the current product by (x - r^i)
+		for (int j = 0; j < degree; j++) {
+			result[j] = finiteFieldMultiply(result[j], root);
+			if (j + 1 < degree)
+				result[j] ^= result[j + 1];
+		}
+		root = finiteFieldMultiply(root, 0x02);
+	}
+}
+
+
+// Calculates the remainder of the polynomial data[0 : dataLen] when divided by the generator[0 : degree], where all
+// polynomials are in big endian and the generator has an implicit leading 1 term, storing the result in result[0 : degree].
+testable void calcReedSolomonRemainder(const uint8_t data[], int dataLen,
+		const uint8_t generator[], int degree, uint8_t result[]) {
+	
+	// Perform polynomial division
+	assert(1 <= degree && degree <= 30);
+	memset(result, 0, degree * sizeof(result[0]));
+	for (int i = 0; i < dataLen; i++) {
+		uint8_t factor = data[i] ^ result[0];
+		memmove(&result[0], &result[1], (degree - 1) * sizeof(result[0]));
+		result[degree - 1] = 0;
+		for (int j = 0; j < degree; j++)
+			result[j] ^= finiteFieldMultiply(generator[j], factor);
+	}
+}
+
+
+// Returns the product of the two given field elements modulo GF(2^8/0x11D).
+// All inputs are valid. This could be implemented as a 256*256 lookup table.
+testable uint8_t finiteFieldMultiply(uint8_t x, uint8_t y) {
+	// Russian peasant multiplication
+	uint8_t z = 0;
+	for (int i = 7; i >= 0; i--) {
+		z = (z << 1) ^ ((z >> 7) * 0x11D);
+		z ^= ((y >> i) & 1) * x;
+	}
+	return z;
+}
+
+
+
+/*---- Drawing function modules ----*/
+
+// Clears the given QR Code grid with white modules for the given
+// version's size, then marks every function module as black.
+testable void initializeFunctionModules(int version, uint8_t qrcode[]) {
+	// Initialize QR Code
+	int qrsize = version * 4 + 17;
+	memset(qrcode, 0, ((qrsize * qrsize + 7) / 8 + 1) * sizeof(qrcode[0]));
+	qrcode[0] = (uint8_t)qrsize;
+	
+	// Fill horizontal and vertical timing patterns
+	fillRectangle(6, 0, 1, qrsize, qrcode);
+	fillRectangle(0, 6, qrsize, 1, qrcode);
+	
+	// Fill 3 finder patterns (all corners except bottom right) and format bits
+	fillRectangle(0, 0, 9, 9, qrcode);
+	fillRectangle(qrsize - 8, 0, 8, 9, qrcode);
+	fillRectangle(0, qrsize - 8, 9, 8, qrcode);
+	
+	// Fill numerous alignment patterns
+	uint8_t alignPatPos[7] = {0};
+	int numAlign = getAlignmentPatternPositions(version, alignPatPos);
+	for (int i = 0; i < numAlign; i++) {
+		for (int j = 0; j < numAlign; j++) {
+			if ((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0))
+				continue;  // Skip the three finder corners
+			else
+				fillRectangle(alignPatPos[i] - 2, alignPatPos[j] - 2, 5, 5, qrcode);
+		}
+	}
+	
+	// Fill version blocks
+	if (version >= 7) {
+		fillRectangle(qrsize - 11, 0, 3, 6, qrcode);
+		fillRectangle(0, qrsize - 11, 6, 3, qrcode);
+	}
+}
+
+
+// Draws white function modules and possibly some black modules onto the given QR Code, without changing
+// non-function modules. This does not draw the format bits. This requires all function modules to be previously
+// marked black (namely by initializeFunctionModules()), because this may skip redrawing black function modules.
+static void drawWhiteFunctionModules(uint8_t qrcode[], int version) {
+	// Draw horizontal and vertical timing patterns
+	int qrsize = qrcodegen_getSize(qrcode);
+	for (int i = 7; i < qrsize - 7; i += 2) {
+		setModule(qrcode, 6, i, false);
+		setModule(qrcode, i, 6, false);
+	}
+	
+	// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
+	for (int i = -4; i <= 4; i++) {
+		for (int j = -4; j <= 4; j++) {
+			int dist = abs(i);
+			if (abs(j) > dist)
+				dist = abs(j);
+			if (dist == 2 || dist == 4) {
+				setModuleBounded(qrcode, 3 + j, 3 + i, false);
+				setModuleBounded(qrcode, qrsize - 4 + j, 3 + i, false);
+				setModuleBounded(qrcode, 3 + j, qrsize - 4 + i, false);
+			}
+		}
+	}
+	
+	// Draw numerous alignment patterns
+	uint8_t alignPatPos[7] = {0};
+	int numAlign = getAlignmentPatternPositions(version, alignPatPos);
+	for (int i = 0; i < numAlign; i++) {
+		for (int j = 0; j < numAlign; j++) {
+			if ((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0))
+				continue;  // Skip the three finder corners
+			else {
+				for (int k = -1; k <= 1; k++) {
+					for (int l = -1; l <= 1; l++)
+						setModule(qrcode, alignPatPos[i] + l, alignPatPos[j] + k, k == 0 && l == 0);
+				}
+			}
+		}
+	}
+	
+	// Draw version blocks
+	if (version >= 7) {
+		// Calculate error correction code and pack bits
+		int rem = version;  // version is uint6, in the range [7, 40]
+		for (int i = 0; i < 12; i++)
+			rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
+		long data = (long)version << 12 | rem;  // uint18
+		assert(data >> 18 == 0);
+		
+		// Draw two copies
+		for (int i = 0; i < 6; i++) {
+			for (int j = 0; j < 3; j++) {
+				int k = qrsize - 11 + j;
+				setModule(qrcode, k, i, (data & 1) != 0);
+				setModule(qrcode, i, k, (data & 1) != 0);
+				data >>= 1;
+			}
+		}
+	}
+}
+
+
+// Draws two copies of the format bits (with its own error correction code) based
+// on the given mask and error correction level. This always draws all modules of
+// the format bits, unlike drawWhiteFunctionModules() which might skip black modules.
+static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[]) {
+	// Calculate error correction code and pack bits
+	assert(0 <= (int)mask && (int)mask <= 7);
+	int data = -1;  // Dummy value
+	switch (ecl) {
+		case qrcodegen_Ecc_LOW     :  data = 1;  break;
+		case qrcodegen_Ecc_MEDIUM  :  data = 0;  break;
+		case qrcodegen_Ecc_QUARTILE:  data = 3;  break;
+		case qrcodegen_Ecc_HIGH    :  data = 2;  break;
+		default:  assert(false);
+	}
+	data = data << 3 | (int)mask;  // ecl-derived value is uint2, mask is uint3
+	int rem = data;
+	for (int i = 0; i < 10; i++)
+		rem = (rem << 1) ^ ((rem >> 9) * 0x537);
+	data = data << 10 | rem;
+	data ^= 0x5412;  // uint15
+	assert(data >> 15 == 0);
+	
+	// Draw first copy
+	for (int i = 0; i <= 5; i++)
+		setModule(qrcode, 8, i, ((data >> i) & 1) != 0);
+	setModule(qrcode, 8, 7, ((data >> 6) & 1) != 0);
+	setModule(qrcode, 8, 8, ((data >> 7) & 1) != 0);
+	setModule(qrcode, 7, 8, ((data >> 8) & 1) != 0);
+	for (int i = 9; i < 15; i++)
+		setModule(qrcode, 14 - i, 8, ((data >> i) & 1) != 0);
+	
+	// Draw second copy
+	int qrsize = qrcodegen_getSize(qrcode);
+	for (int i = 0; i <= 7; i++)
+		setModule(qrcode, qrsize - 1 - i, 8, ((data >> i) & 1) != 0);
+	for (int i = 8; i < 15; i++)
+		setModule(qrcode, 8, qrsize - 15 + i, ((data >> i) & 1) != 0);
+	setModule(qrcode, 8, qrsize - 8, true);
+}
+
+
+// Calculates the positions of alignment patterns in ascending order for the given version number,
+// storing them to the given array and returning an array length in the range [0, 7].
+testable int getAlignmentPatternPositions(int version, uint8_t result[7]) {
+	if (version == 1)
+		return 0;
+	int numAlign = version / 7 + 2;
+	int step;
+	if (version != 32) {
+		// ceil((size - 13) / (2*numAlign - 2)) * 2
+		step = (version * 4 + numAlign * 2 + 1) / (2 * numAlign - 2) * 2;
+	} else  // C-C-C-Combo breaker!
+		step = 26;
+	for (int i = numAlign - 1, pos = version * 4 + 10; i >= 1; i--, pos -= step)
+		result[i] = pos;
+	result[0] = 6;
+	return numAlign;
+}
+
+
+// Sets every pixel in the range [left : left + width] * [top : top + height] to black.
+static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[]) {
+	for (int dy = 0; dy < height; dy++) {
+		for (int dx = 0; dx < width; dx++)
+			setModule(qrcode, left + dx, top + dy, true);
+	}
+}
+
+
+
+/*---- Drawing data modules and masking ----*/
+
+// Draws the raw codewords (including data and ECC) onto the given QR Code. This requires the initial state of
+// the QR Code to be black at function modules and white at codeword modules (including unused remainder bits).
+static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[]) {
+	int qrsize = qrcodegen_getSize(qrcode);
+	int i = 0;  // Bit index into the data
+	// Do the funny zigzag scan
+	for (int right = qrsize - 1; right >= 1; right -= 2) {  // Index of right column in each column pair
+		if (right == 6)
+			right = 5;
+		for (int vert = 0; vert < qrsize; vert++) {  // Vertical counter
+			for (int j = 0; j < 2; j++) {
+				int x = right - j;  // Actual x coordinate
+				bool upward = ((right + 1) & 2) == 0;
+				int y = upward ? qrsize - 1 - vert : vert;  // Actual y coordinate
+				if (!getModule(qrcode, x, y) && i < dataLen * 8) {
+					bool black = ((data[i >> 3] >> (7 - (i & 7))) & 1) != 0;
+					setModule(qrcode, x, y, black);
+					i++;
+				}
+				// If there are any remainder bits (0 to 7), they are already
+				// set to 0/false/white when the grid of modules was initialized
+			}
+		}
+	}
+	assert(i == dataLen * 8);
+}
+
+
+// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
+// properties, calling applyMask(..., m) twice with the same value is equivalent to no change at all.
+// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
+// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
+static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], enum qrcodegen_Mask mask) {
+	assert(0 <= (int)mask && (int)mask <= 7);  // Disallows qrcodegen_Mask_AUTO
+	int qrsize = qrcodegen_getSize(qrcode);
+	for (int y = 0; y < qrsize; y++) {
+		for (int x = 0; x < qrsize; x++) {
+			if (getModule(functionModules, x, y))
+				continue;
+			bool invert = false;  // Dummy value
+			switch ((int)mask) {
+				case 0:  invert = (x + y) % 2 == 0;                    break;
+				case 1:  invert = y % 2 == 0;                          break;
+				case 2:  invert = x % 3 == 0;                          break;
+				case 3:  invert = (x + y) % 3 == 0;                    break;
+				case 4:  invert = (x / 3 + y / 2) % 2 == 0;            break;
+				case 5:  invert = x * y % 2 + x * y % 3 == 0;          break;
+				case 6:  invert = (x * y % 2 + x * y % 3) % 2 == 0;    break;
+				case 7:  invert = ((x + y) % 2 + x * y % 3) % 2 == 0;  break;
+				default:  assert(false);
+			}
+			bool val = getModule(qrcode, x, y);
+			setModule(qrcode, x, y, val ^ invert);
+		}
+	}
+}
+
+
+// Calculates and returns the penalty score based on state of the given QR Code's current modules.
+// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
+static long getPenaltyScore(const uint8_t qrcode[]) {
+	int qrsize = qrcodegen_getSize(qrcode);
+	long result = 0;
+	
+	// Adjacent modules in row having same color
+	for (int y = 0; y < qrsize; y++) {
+		bool colorX = false;
+		for (int x = 0, runX = -1; x < qrsize; x++) {
+			if (x == 0 || getModule(qrcode, x, y) != colorX) {
+				colorX = getModule(qrcode, x, y);
+				runX = 1;
+			} else {
+				runX++;
+				if (runX == 5)
+					result += PENALTY_N1;
+				else if (runX > 5)
+					result++;
+			}
+		}
+	}
+	// Adjacent modules in column having same color
+	for (int x = 0; x < qrsize; x++) {
+		bool colorY = false;
+		for (int y = 0, runY = -1; y < qrsize; y++) {
+			if (y == 0 || getModule(qrcode, x, y) != colorY) {
+				colorY = getModule(qrcode, x, y);
+				runY = 1;
+			} else {
+				runY++;
+				if (runY == 5)
+					result += PENALTY_N1;
+				else if (runY > 5)
+					result++;
+			}
+		}
+	}
+	
+	// 2*2 blocks of modules having same color
+	for (int y = 0; y < qrsize - 1; y++) {
+		for (int x = 0; x < qrsize - 1; x++) {
+			bool  color = getModule(qrcode, x, y);
+			if (  color == getModule(qrcode, x + 1, y) &&
+			      color == getModule(qrcode, x, y + 1) &&
+			      color == getModule(qrcode, x + 1, y + 1))
+				result += PENALTY_N2;
+		}
+	}
+	
+	// Finder-like pattern in rows
+	for (int y = 0; y < qrsize; y++) {
+		for (int x = 0, bits = 0; x < qrsize; x++) {
+			bits = ((bits << 1) & 0x7FF) | (getModule(qrcode, x, y) ? 1 : 0);
+			if (x >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
+				result += PENALTY_N3;
+		}
+	}
+	// Finder-like pattern in columns
+	for (int x = 0; x < qrsize; x++) {
+		for (int y = 0, bits = 0; y < qrsize; y++) {
+			bits = ((bits << 1) & 0x7FF) | (getModule(qrcode, x, y) ? 1 : 0);
+			if (y >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
+				result += PENALTY_N3;
+		}
+	}
+	
+	// Balance of black and white modules
+	int black = 0;
+	for (int y = 0; y < qrsize; y++) {
+		for (int x = 0; x < qrsize; x++) {
+			if (getModule(qrcode, x, y))
+				black++;
+		}
+	}
+	int total = qrsize * qrsize;
+	// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
+	for (int k = 0; black*20L < (9L-k)*total || black*20L > (11L+k)*total; k++)
+		result += PENALTY_N4;
+	return result;
+}
+
+
+
+/*---- Basic QR Code information ----*/
+
+// Public function - see documentation comment in header file.
+int qrcodegen_getSize(const uint8_t qrcode[]) {
+	assert(qrcode != NULL);
+	int result = qrcode[0];
+	assert((qrcodegen_VERSION_MIN * 4 + 17) <= result
+		&& result <= (qrcodegen_VERSION_MAX * 4 + 17));
+	return result;
+}
+
+
+// Public function - see documentation comment in header file.
+bool qrcodegen_getModule(const uint8_t qrcode[], int x, int y) {
+	assert(qrcode != NULL);
+	int qrsize = qrcode[0];
+	return (0 <= x && x < qrsize && 0 <= y && y < qrsize) && getModule(qrcode, x, y);
+}
+
+
+// Gets the module at the given coordinates, which must be in bounds.
+testable bool getModule(const uint8_t qrcode[], int x, int y) {
+	int qrsize = qrcode[0];
+	assert(21 <= qrsize && qrsize <= 177 && 0 <= x && x < qrsize && 0 <= y && y < qrsize);
+	int index = y * qrsize + x;
+	int bitIndex = index & 7;
+	int byteIndex = (index >> 3) + 1;
+	return ((qrcode[byteIndex] >> bitIndex) & 1) != 0;
+}
+
+
+// Sets the module at the given coordinates, which must be in bounds.
+testable void setModule(uint8_t qrcode[], int x, int y, bool isBlack) {
+	int qrsize = qrcode[0];
+	assert(21 <= qrsize && qrsize <= 177 && 0 <= x && x < qrsize && 0 <= y && y < qrsize);
+	int index = y * qrsize + x;
+	int bitIndex = index & 7;
+	int byteIndex = (index >> 3) + 1;
+	if (isBlack)
+		qrcode[byteIndex] |= 1 << bitIndex;
+	else
+		qrcode[byteIndex] &= (1 << bitIndex) ^ 0xFF;
+}
+
+
+// Sets the module at the given coordinates, doing nothing if out of bounds.
+testable void setModuleBounded(uint8_t qrcode[], int x, int y, bool isBlack) {
+	int qrsize = qrcode[0];
+	if (0 <= x && x < qrsize && 0 <= y && y < qrsize)
+		setModule(qrcode, x, y, isBlack);
+}
+
+
+
+/*---- Segment handling ----*/
+
+// Public function - see documentation comment in header file.
+bool qrcodegen_isAlphanumeric(const char *text) {
+	assert(text != NULL);
+	for (; *text != '\0'; text++) {
+		if (strchr(ALPHANUMERIC_CHARSET, *text) == NULL)
+			return false;
+	}
+	return true;
+}
+
+
+// Public function - see documentation comment in header file.
+bool qrcodegen_isNumeric(const char *text) {
+	assert(text != NULL);
+	for (; *text != '\0'; text++) {
+		if (*text < '0' || *text > '9')
+			return false;
+	}
+	return true;
+}
+
+
+// Public function - see documentation comment in header file.
+size_t qrcodegen_calcSegmentBufferSize(enum qrcodegen_Mode mode, size_t numChars) {
+	int temp = calcSegmentBitLength(mode, numChars);
+	if (temp == -1)
+		return SIZE_MAX;
+	assert(0 <= temp && temp <= INT16_MAX);
+	return ((size_t)temp + 7) / 8;
+}
+
+
+// Returns the number of data bits needed to represent a segment
+// containing the given number of characters using the given mode. Notes:
+// - Returns -1 on failure, i.e. numChars > INT16_MAX or
+//   the number of needed bits exceeds INT16_MAX (i.e. 32767).
+// - Otherwise, all valid results are in the range [0, INT16_MAX].
+// - For byte mode, numChars measures the number of bytes, not Unicode code points.
+// - For ECI mode, numChars must be 0, and the worst-case number of bits is returned.
+//   An actual ECI segment can have shorter data. For non-ECI modes, the result is exact.
+testable int calcSegmentBitLength(enum qrcodegen_Mode mode, size_t numChars) {
+	const int LIMIT = INT16_MAX;  // Can be configured as high as INT_MAX
+	if (numChars > (unsigned int)LIMIT)
+		return -1;
+	int n = (int)numChars;
+	
+	int result = -2;
+	if (mode == qrcodegen_Mode_NUMERIC) {
+		// n * 3 + ceil(n / 3)
+		if (n > LIMIT / 3)
+			goto overflow;
+		result = n * 3;
+		int temp = n / 3 + (n % 3 == 0 ? 0 : 1);
+		if (temp > LIMIT - result)
+			goto overflow;
+		result += temp;
+	} else if (mode == qrcodegen_Mode_ALPHANUMERIC) {
+		// n * 5 + ceil(n / 2)
+		if (n > LIMIT / 5)
+			goto overflow;
+		result = n * 5;
+		int temp = n / 2 + n % 2;
+		if (temp > LIMIT - result)
+			goto overflow;
+		result += temp;
+	} else if (mode == qrcodegen_Mode_BYTE) {
+		if (n > LIMIT / 8)
+			goto overflow;
+		result = n * 8;
+	} else if (mode == qrcodegen_Mode_KANJI) {
+		if (n > LIMIT / 13)
+			goto overflow;
+		result = n * 13;
+	} else if (mode == qrcodegen_Mode_ECI && numChars == 0)
+		result = 3 * 8;
+	assert(0 <= result && result <= LIMIT);
+	return result;
+overflow:
+	return -1;
+}
+
+
+// Public function - see documentation comment in header file.
+struct qrcodegen_Segment qrcodegen_makeBytes(const uint8_t data[], size_t len, uint8_t buf[]) {
+	assert(data != NULL || len == 0);
+	struct qrcodegen_Segment result;
+	result.mode = qrcodegen_Mode_BYTE;
+	result.bitLength = calcSegmentBitLength(result.mode, len);
+	assert(result.bitLength != -1);
+	result.numChars = (int)len;
+	if (len > 0)
+		memcpy(buf, data, len * sizeof(buf[0]));
+	result.data = buf;
+	return result;
+}
+
+
+// Public function - see documentation comment in header file.
+struct qrcodegen_Segment qrcodegen_makeNumeric(const char *digits, uint8_t buf[]) {
+	assert(digits != NULL);
+	struct qrcodegen_Segment result;
+	size_t len = strlen(digits);
+	result.mode = qrcodegen_Mode_NUMERIC;
+	int bitLen = calcSegmentBitLength(result.mode, len);
+	assert(bitLen != -1);
+	result.numChars = (int)len;
+	if (bitLen > 0)
+		memset(buf, 0, ((size_t)bitLen + 7) / 8 * sizeof(buf[0]));
+	result.bitLength = 0;
+	
+	unsigned int accumData = 0;
+	int accumCount = 0;
+	for (; *digits != '\0'; digits++) {
+		char c = *digits;
+		assert('0' <= c && c <= '9');
+		accumData = accumData * 10 + (c - '0');
+		accumCount++;
+		if (accumCount == 3) {
+			appendBitsToBuffer(accumData, 10, buf, &result.bitLength);
+			accumData = 0;
+			accumCount = 0;
+		}
+	}
+	if (accumCount > 0)  // 1 or 2 digits remaining
+		appendBitsToBuffer(accumData, accumCount * 3 + 1, buf, &result.bitLength);
+	assert(result.bitLength == bitLen);
+	result.data = buf;
+	return result;
+}
+
+
+// Public function - see documentation comment in header file.
+struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char *text, uint8_t buf[]) {
+	assert(text != NULL);
+	struct qrcodegen_Segment result;
+	size_t len = strlen(text);
+	result.mode = qrcodegen_Mode_ALPHANUMERIC;
+	int bitLen = calcSegmentBitLength(result.mode, len);
+	assert(bitLen != -1);
+	result.numChars = (int)len;
+	if (bitLen > 0)
+		memset(buf, 0, ((size_t)bitLen + 7) / 8 * sizeof(buf[0]));
+	result.bitLength = 0;
+	
+	unsigned int accumData = 0;
+	int accumCount = 0;
+	for (; *text != '\0'; text++) {
+		const char *temp = strchr(ALPHANUMERIC_CHARSET, *text);
+		assert(temp != NULL);
+		accumData = accumData * 45 + (temp - ALPHANUMERIC_CHARSET);
+		accumCount++;
+		if (accumCount == 2) {
+			appendBitsToBuffer(accumData, 11, buf, &result.bitLength);
+			accumData = 0;
+			accumCount = 0;
+		}
+	}
+	if (accumCount > 0)  // 1 character remaining
+		appendBitsToBuffer(accumData, 6, buf, &result.bitLength);
+	assert(result.bitLength == bitLen);
+	result.data = buf;
+	return result;
+}
+
+
+// Public function - see documentation comment in header file.
+struct qrcodegen_Segment qrcodegen_makeEci(long assignVal, uint8_t buf[]) {
+	struct qrcodegen_Segment result;
+	result.mode = qrcodegen_Mode_ECI;
+	result.numChars = 0;
+	result.bitLength = 0;
+	if (0 <= assignVal && assignVal < (1 << 7)) {
+		memset(buf, 0, 1 * sizeof(buf[0]));
+		appendBitsToBuffer(assignVal, 8, buf, &result.bitLength);
+	} else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) {
+		memset(buf, 0, 2 * sizeof(buf[0]));
+		appendBitsToBuffer(2, 2, buf, &result.bitLength);
+		appendBitsToBuffer(assignVal, 14, buf, &result.bitLength);
+	} else if ((1 << 14) <= assignVal && assignVal < 1000000L) {
+		memset(buf, 0, 3 * sizeof(buf[0]));
+		appendBitsToBuffer(6, 3, buf, &result.bitLength);
+		appendBitsToBuffer(assignVal >> 10, 11, buf, &result.bitLength);
+		appendBitsToBuffer(assignVal & 0x3FF, 10, buf, &result.bitLength);
+	} else
+		assert(false);
+	result.data = buf;
+	return result;
+}
+
+
+// Public function - see documentation comment in header file.
+bool qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], size_t len,
+		enum qrcodegen_Ecc ecl, uint8_t tempBuffer[], uint8_t qrcode[]) {
+	return qrcodegen_encodeSegmentsAdvanced(segs, len, ecl,
+		qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, -1, true, tempBuffer, qrcode);
+}
+
+
+// Public function - see documentation comment in header file.
+bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], size_t len, enum qrcodegen_Ecc ecl,
+		int minVersion, int maxVersion, int mask, bool boostEcl, uint8_t tempBuffer[], uint8_t qrcode[]) {
+	assert(segs != NULL || len == 0);
+	assert(qrcodegen_VERSION_MIN <= minVersion && minVersion <= maxVersion && maxVersion <= qrcodegen_VERSION_MAX);
+	assert(0 <= (int)ecl && (int)ecl <= 3 && -1 <= (int)mask && (int)mask <= 7);
+	
+	// Find the minimal version number to use
+	int version, dataUsedBits;
+	for (version = minVersion; ; version++) {
+		int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;  // Number of data bits available
+		dataUsedBits = getTotalBits(segs, len, version);
+		if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits)
+			break;  // This version number is found to be suitable
+		if (version >= maxVersion) {  // All versions in the range could not fit the given data
+			qrcode[0] = 0;  // Set size to invalid value for safety
+			return false;
+		}
+	}
+	assert(dataUsedBits != -1);
+	
+	// Increase the error correction level while the data still fits in the current version number
+	for (int i = (int)qrcodegen_Ecc_MEDIUM; i <= (int)qrcodegen_Ecc_HIGH; i++) {
+		if (boostEcl && dataUsedBits <= getNumDataCodewords(version, (enum qrcodegen_Ecc)i) * 8)
+			ecl = (enum qrcodegen_Ecc)i;
+	}
+	
+	// Create the data bit string by concatenating all segments
+	int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
+	memset(qrcode, 0, qrcodegen_BUFFER_LEN_FOR_VERSION(version) * sizeof(qrcode[0]));
+	int bitLen = 0;
+	for (size_t i = 0; i < len; i++) {
+		const struct qrcodegen_Segment *seg = &segs[i];
+		unsigned int modeBits = 0;  // Dummy value
+		switch (seg->mode) {
+			case qrcodegen_Mode_NUMERIC     :  modeBits = 0x1;  break;
+			case qrcodegen_Mode_ALPHANUMERIC:  modeBits = 0x2;  break;
+			case qrcodegen_Mode_BYTE        :  modeBits = 0x4;  break;
+			case qrcodegen_Mode_KANJI       :  modeBits = 0x8;  break;
+			case qrcodegen_Mode_ECI         :  modeBits = 0x7;  break;
+			default:  assert(false);
+		}
+		appendBitsToBuffer(modeBits, 4, qrcode, &bitLen);
+		appendBitsToBuffer(seg->numChars, numCharCountBits(seg->mode, version), qrcode, &bitLen);
+		for (int j = 0; j < seg->bitLength; j++)
+			appendBitsToBuffer((seg->data[j >> 3] >> (7 - (j & 7))) & 1, 1, qrcode, &bitLen);
+	}
+	
+	// Add terminator and pad up to a byte if applicable
+	int terminatorBits = dataCapacityBits - bitLen;
+	if (terminatorBits > 4)
+		terminatorBits = 4;
+	appendBitsToBuffer(0, terminatorBits, qrcode, &bitLen);
+	appendBitsToBuffer(0, (8 - bitLen % 8) % 8, qrcode, &bitLen);
+	
+	// Pad with alternate bytes until data capacity is reached
+	for (uint8_t padByte = 0xEC; bitLen < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
+		appendBitsToBuffer(padByte, 8, qrcode, &bitLen);
+	assert(bitLen % 8 == 0);
+	
+	// Draw function and data codeword modules
+	appendErrorCorrection(qrcode, version, ecl, tempBuffer);
+	initializeFunctionModules(version, qrcode);
+	drawCodewords(tempBuffer, getNumRawDataModules(version) / 8, qrcode);
+	drawWhiteFunctionModules(qrcode, version);
+	initializeFunctionModules(version, tempBuffer);
+	
+	// Handle masking
+	if (mask == qrcodegen_Mask_AUTO) {  // Automatically choose best mask
+		long minPenalty = LONG_MAX;
+		for (int i = 0; i < 8; i++) {
+			drawFormatBits(ecl, (enum qrcodegen_Mask)i, qrcode);
+			applyMask(tempBuffer, qrcode, (enum qrcodegen_Mask)i);
+			long penalty = getPenaltyScore(qrcode);
+			if (penalty < minPenalty) {
+				mask = (enum qrcodegen_Mask)i;
+				minPenalty = penalty;
+			}
+			applyMask(tempBuffer, qrcode, (enum qrcodegen_Mask)i);  // Undoes the mask due to XOR
+		}
+	}
+	assert(0 <= (int)mask && (int)mask <= 7);
+	drawFormatBits(ecl, mask, qrcode);
+	applyMask(tempBuffer, qrcode, mask);
+	return true;
+}
+
+
+// Returns the number of bits needed to encode the given list of segments at the given version.
+// The result is in the range [0, 32767] if successful. Otherwise, -1 is returned if any segment
+// has more characters than allowed by that segment's mode's character count field at the version,
+// or if the actual answer exceeds INT16_MAX.
+testable int getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int version) {
+	assert(segs != NULL || len == 0);
+	assert(qrcodegen_VERSION_MIN <= version && version <= qrcodegen_VERSION_MAX);
+	int result = 0;
+	for (size_t i = 0; i < len; i++) {
+		int numChars = segs[i].numChars;
+		int bitLength = segs[i].bitLength;
+		assert(0 <= numChars && numChars <= INT16_MAX);
+		assert(0 <= bitLength && bitLength <= INT16_MAX);
+		int ccbits = numCharCountBits(segs[i].mode, version);
+		assert(0 <= ccbits && ccbits <= 16);
+		// Fail if segment length value doesn't fit in the length field's bit-width
+		if (numChars >= (1L << ccbits))
+			return -1;
+		long temp = 4L + ccbits + bitLength;
+		if (temp > INT16_MAX - result)
+			return -1;
+		result += temp;
+	}
+	assert(0 <= result && result <= INT16_MAX);
+	return result;
+}
+
+
+// Returns the bit width of the segment character count field for the
+// given mode at the given version number. The result is in the range [0, 16].
+static int numCharCountBits(enum qrcodegen_Mode mode, int version) {
+	assert(qrcodegen_VERSION_MIN <= version && version <= qrcodegen_VERSION_MAX);
+	int i = -1;  // Dummy value
+	if      ( 1 <= version && version <=  9)  i = 0;
+	else if (10 <= version && version <= 26)  i = 1;
+	else if (27 <= version && version <= 40)  i = 2;
+	else  assert(false);
+	
+	switch (mode) {
+		case qrcodegen_Mode_NUMERIC     : { static const int temp[] = {10, 12, 14}; return temp[i]; }
+		case qrcodegen_Mode_ALPHANUMERIC: { static const int temp[] = { 9, 11, 13}; return temp[i]; }
+		case qrcodegen_Mode_BYTE        : { static const int temp[] = { 8, 16, 16}; return temp[i]; }
+		case qrcodegen_Mode_KANJI       : { static const int temp[] = { 8, 10, 12}; return temp[i]; }
+		case qrcodegen_Mode_ECI         : return 0;
+		default:  assert(false);
+	}
+	return -1;  // Dummy value
+}
diff --git a/src/third_party/QR-Code-generator/c/qrcodegen.h b/src/third_party/QR-Code-generator/c/qrcodegen.h
new file mode 100644
index 0000000..899feae
--- /dev/null
+++ b/src/third_party/QR-Code-generator/c/qrcodegen.h
@@ -0,0 +1,267 @@
+/* 
+ * QR Code generator library (C)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+
+/*---- Enum and struct types----*/
+
+/* 
+ * The error correction level used in a QR Code symbol.
+ */
+enum qrcodegen_Ecc {
+	qrcodegen_Ecc_LOW = 0,
+	qrcodegen_Ecc_MEDIUM,
+	qrcodegen_Ecc_QUARTILE,
+	qrcodegen_Ecc_HIGH,
+};
+
+
+/* 
+ * The mask pattern used in a QR Code symbol.
+ */
+enum qrcodegen_Mask {
+	// A special value to tell the QR Code encoder to
+	// automatically select an appropriate mask pattern
+	qrcodegen_Mask_AUTO = -1,
+	// The eight actual mask patterns
+	qrcodegen_Mask_0 = 0,
+	qrcodegen_Mask_1,
+	qrcodegen_Mask_2,
+	qrcodegen_Mask_3,
+	qrcodegen_Mask_4,
+	qrcodegen_Mask_5,
+	qrcodegen_Mask_6,
+	qrcodegen_Mask_7,
+};
+
+
+/* 
+ * The mode field of a segment.
+ */
+enum qrcodegen_Mode {
+	qrcodegen_Mode_NUMERIC,
+	qrcodegen_Mode_ALPHANUMERIC,
+	qrcodegen_Mode_BYTE,
+	qrcodegen_Mode_KANJI,
+	qrcodegen_Mode_ECI,
+};
+
+
+/* 
+ * A segment of user/application data that a QR Code symbol can convey.
+ * Each segment has a mode, a character count, and character/general data that is
+ * already encoded as a sequence of bits. The maximum allowed bit length is 32767,
+ * because even the largest QR Code (version 40) has only 31329 modules.
+ */
+struct qrcodegen_Segment {
+	// The mode indicator for this segment.
+	enum qrcodegen_Mode mode;
+	
+	// The length of this segment's unencoded data. Always in the range [0, 32767].
+	// For numeric, alphanumeric, and kanji modes, this measures in Unicode code points.
+	// For byte mode, this measures in bytes (raw binary data, text in UTF-8, or other encodings).
+	// For ECI mode, this is always zero.
+	int numChars;
+	
+	// The data bits of this segment, packed in bitwise big endian.
+	// Can be null if the bit length is zero.
+	uint8_t *data;
+	
+	// The number of valid data bits used in the buffer. Requires
+	// 0 <= bitLength <= 32767, and bitLength <= (capacity of data array) * 8.
+	int bitLength;
+};
+
+
+
+/*---- Macro constants and functions ----*/
+
+// The minimum and maximum defined QR Code version numbers for Model 2.
+#define qrcodegen_VERSION_MIN  1
+#define qrcodegen_VERSION_MAX  40
+
+// Calculates the number of bytes needed to store any QR Code up to and including the given version number,
+// as a compile-time constant. For example, 'uint8_t buffer[qrcodegen_BUFFER_LEN_FOR_VERSION(25)];'
+// can store any single QR Code from version 1 to 25, inclusive.
+// Requires qrcodegen_VERSION_MIN <= n <= qrcodegen_VERSION_MAX.
+#define qrcodegen_BUFFER_LEN_FOR_VERSION(n)  ((((n) * 4 + 17) * ((n) * 4 + 17) + 7) / 8 + 1)
+
+// The worst-case number of bytes needed to store one QR Code, up to and including
+// version 40. This value equals 3918, which is just under 4 kilobytes.
+// Use this more convenient value to avoid calculating tighter memory bounds for buffers.
+#define qrcodegen_BUFFER_LEN_MAX  qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX)
+
+
+
+/*---- Functions to generate QR Codes ----*/
+
+/* 
+ * Encodes the given text string to a QR Code symbol, returning true if encoding succeeded.
+ * If the data is too long to fit in any version in the given range
+ * at the given ECC level, then false is returned.
+ * - The input text must be encoded in UTF-8 and contain no NULs.
+ * - The variables ecl and mask must correspond to enum constant values.
+ * - Requires 1 <= minVersion <= maxVersion <= 40.
+ * - The arrays tempBuffer and qrcode must each have a length
+ *   of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion).
+ * - After the function returns, tempBuffer contains no useful data.
+ * - If successful, the resulting QR Code may use numeric,
+ *   alphanumeric, or byte mode to encode the text.
+ * - In the most optimistic case, a QR Code at version 40 with low ECC
+ *   can hold any UTF-8 string up to 2953 bytes, or any alphanumeric string
+ *   up to 4296 characters, or any digit string up to 7089 characters.
+ *   These numbers represent the hard upper limit of the QR Code standard.
+ * - Please consult the QR Code specification for information on
+ *   data capacities per version, ECC level, and text encoding mode.
+ */
+bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
+	enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl);
+
+
+/* 
+ * Encodes the given binary data to a QR Code symbol, returning true if encoding succeeded.
+ * If the data is too long to fit in any version in the given range
+ * at the given ECC level, then false is returned.
+ * - The input array range dataAndTemp[0 : dataLen] should normally be
+ *   valid UTF-8 text, but is not required by the QR Code standard.
+ * - The variables ecl and mask must correspond to enum constant values.
+ * - Requires 1 <= minVersion <= maxVersion <= 40.
+ * - The arrays dataAndTemp and qrcode must each have a length
+ *   of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion).
+ * - After the function returns, the contents of dataAndTemp may have changed,
+ *   and does not represent useful data anymore.
+ * - If successful, the resulting QR Code will use byte mode to encode the data.
+ * - In the most optimistic case, a QR Code at version 40 with low ECC can hold any byte
+ *   sequence up to length 2953. This is the hard upper limit of the QR Code standard.
+ * - Please consult the QR Code specification for information on
+ *   data capacities per version, ECC level, and text encoding mode.
+ */
+bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[],
+	enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl);
+
+
+/* 
+ * Tests whether the given string can be encoded as a segment in alphanumeric mode.
+ */
+bool qrcodegen_isAlphanumeric(const char *text);
+
+
+/* 
+ * Tests whether the given string can be encoded as a segment in numeric mode.
+ */
+bool qrcodegen_isNumeric(const char *text);
+
+
+/* 
+ * Returns the number of bytes (uint8_t) needed for the data buffer of a segment
+ * containing the given number of characters using the given mode. Notes:
+ * - Returns SIZE_MAX on failure, i.e. numChars > INT16_MAX or
+ *   the number of needed bits exceeds INT16_MAX (i.e. 32767).
+ * - Otherwise, all valid results are in the range [0, ceil(INT16_MAX / 8)], i.e. at most 4096.
+ * - It is okay for the user to allocate more bytes for the buffer than needed.
+ * - For byte mode, numChars measures the number of bytes, not Unicode code points.
+ * - For ECI mode, numChars must be 0, and the worst-case number of bytes is returned.
+ *   An actual ECI segment can have shorter data. For non-ECI modes, the result is exact.
+ */
+size_t qrcodegen_calcSegmentBufferSize(enum qrcodegen_Mode mode, size_t numChars);
+
+
+/* 
+ * Returns a segment representing the given binary data encoded in byte mode.
+ */
+struct qrcodegen_Segment qrcodegen_makeBytes(const uint8_t data[], size_t len, uint8_t buf[]);
+
+
+/* 
+ * Returns a segment representing the given string of decimal digits encoded in numeric mode.
+ */
+struct qrcodegen_Segment qrcodegen_makeNumeric(const char *digits, uint8_t buf[]);
+
+
+/* 
+ * Returns a segment representing the given text string encoded in alphanumeric mode.
+ * The characters allowed are: 0 to 9, A to Z (uppercase only), space,
+ * dollar, percent, asterisk, plus, hyphen, period, slash, colon.
+ */
+struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char *text, uint8_t buf[]);
+
+
+/* 
+ * Returns a segment representing an Extended Channel Interpretation
+ * (ECI) designator with the given assignment value.
+ */
+struct qrcodegen_Segment qrcodegen_makeEci(long assignVal, uint8_t buf[]);
+
+
+/* 
+ * Renders a QR Code symbol representing the given data segments at the given error correction
+ * level or higher. The smallest possible QR Code version is automatically chosen for the output.
+ * Returns true if QR Code creation succeeded, or false if the data is too long to fit in any version.
+ * This function allows the user to create a custom sequence of segments that switches
+ * between modes (such as alphanumeric and binary) to encode text more efficiently.
+ * This function is considered to be lower level than simply encoding text or binary data.
+ * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will
+ * result in them being clobbered, but the QR Code output will still be correct.
+ * But the qrcode array must not overlap tempBuffer or any segment's data buffer.
+ */
+bool qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], size_t len,
+	enum qrcodegen_Ecc ecl, uint8_t tempBuffer[], uint8_t qrcode[]);
+
+
+/* 
+ * Renders a QR Code symbol representing the given data segments with the given encoding parameters.
+ * Returns true if QR Code creation succeeded, or false if the data is too long to fit in the range of versions.
+ * The smallest possible QR Code version within the given range is automatically chosen for the output.
+ * This function allows the user to create a custom sequence of segments that switches
+ * between modes (such as alphanumeric and binary) to encode text more efficiently.
+ * This function is considered to be lower level than simply encoding text or binary data.
+ * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will
+ * result in them being clobbered, but the QR Code output will still be correct.
+ * But the qrcode array must not overlap tempBuffer or any segment's data buffer.
+ */
+bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], size_t len, enum qrcodegen_Ecc ecl,
+	int minVersion, int maxVersion, int mask, bool boostEcl, uint8_t tempBuffer[], uint8_t qrcode[]);
+
+
+/*---- Functions to extract raw data from QR Codes ----*/
+
+/* 
+ * Returns the side length of the given QR Code, assuming that encoding succeeded.
+ * The result is in the range [21, 177]. Note that the length of the array buffer
+ * is related to the side length - every 'uint8_t qrcode[]' must have length at least
+ * qrcodegen_BUFFER_LEN_FOR_VERSION(version), which equals ceil(size^2 / 8 + 1).
+ */
+int qrcodegen_getSize(const uint8_t qrcode[]);
+
+
+/* 
+ * Returns the color of the module (pixel) at the given coordinates, which is either
+ * false for white or true for black. The top left corner has the coordinates (x=0, y=0).
+ * If the given coordinates are out of bounds, then false (white) is returned.
+ */
+bool qrcodegen_getModule(const uint8_t qrcode[], int x, int y);
diff --git a/src/third_party/QR-Code-generator/cpp/BitBuffer.cpp b/src/third_party/QR-Code-generator/cpp/BitBuffer.cpp
new file mode 100644
index 0000000..d6e8cb2
--- /dev/null
+++ b/src/third_party/QR-Code-generator/cpp/BitBuffer.cpp
@@ -0,0 +1,48 @@
+/* 
+ * QR Code generator library (C++)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#include "BitBuffer.hpp"
+
+
+namespace qrcodegen {
+
+BitBuffer::BitBuffer()
+	: std::vector<bool>() {}
+
+
+std::vector<std::uint8_t> BitBuffer::getBytes() const {
+	std::vector<std::uint8_t> result(size() / 8 + (size() % 8 == 0 ? 0 : 1));
+	for (std::size_t i = 0; i < size(); i++)
+		result[i >> 3] |= (*this)[i] ? 1 << (7 - (i & 7)) : 0;
+	return result;
+}
+
+
+void BitBuffer::appendBits(std::uint32_t val, int len) {
+	if (len < 0 || len > 31 || val >> len != 0)
+		throw "Value out of range";
+	for (int i = len - 1; i >= 0; i--)  // Append bit by bit
+		this->push_back(((val >> i) & 1) != 0);
+}
+
+}
diff --git a/src/third_party/QR-Code-generator/cpp/BitBuffer.hpp b/src/third_party/QR-Code-generator/cpp/BitBuffer.hpp
new file mode 100644
index 0000000..be00ee4
--- /dev/null
+++ b/src/third_party/QR-Code-generator/cpp/BitBuffer.hpp
@@ -0,0 +1,57 @@
+/* 
+ * QR Code generator library (C++)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <vector>
+
+
+namespace qrcodegen {
+
+/* 
+ * An appendable sequence of bits (0's and 1's).
+ */
+class BitBuffer final : public std::vector<bool> {
+	
+	/*---- Constructor ----*/
+	
+	// Creates an empty bit buffer (length 0).
+	public: BitBuffer();
+	
+	
+	
+	/*---- Methods ----*/
+	
+	// Packs this buffer's bits into bytes in big endian,
+	// padding with '0' bit values, and returns the new vector.
+	public: std::vector<std::uint8_t> getBytes() const;
+	
+	
+	// Appends the given number of low bits of the given value
+	// to this sequence. Requires 0 <= val < 2^len.
+	public: void appendBits(std::uint32_t val, int len);
+	
+};
+
+}
diff --git a/src/third_party/QR-Code-generator/cpp/Makefile b/src/third_party/QR-Code-generator/cpp/Makefile
new file mode 100644
index 0000000..151a4da
--- /dev/null
+++ b/src/third_party/QR-Code-generator/cpp/Makefile
@@ -0,0 +1,66 @@
+# 
+# Makefile for QR Code generator (C++)
+# 
+# Copyright (c) Project Nayuki. (MIT License)
+# https://www.nayuki.io/page/qr-code-generator-library
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+# - The above copyright notice and this permission notice shall be included in
+#   all copies or substantial portions of the Software.
+# - The Software is provided "as is", without warranty of any kind, express or
+#   implied, including but not limited to the warranties of merchantability,
+#   fitness for a particular purpose and noninfringement. In no event shall the
+#   authors or copyright holders be liable for any claim, damages or other
+#   liability, whether in an action of contract, tort or otherwise, arising from,
+#   out of or in connection with the Software or the use or other dealings in the
+#   Software.
+# 
+
+
+# ---- Configuration options ----
+
+# External/implicit variables:
+# - CXX: The C++ compiler, such as g++ or clang++.
+# - CXXFLAGS: Any extra user-specified compiler flags (can be blank).
+
+# Mandatory compiler flags
+CXXFLAGS += -std=c++11
+# Diagnostics. Adding '-fsanitize=address' is helpful for most versions of Clang and newer versions of GCC.
+CXXFLAGS += -Wall -fsanitize=undefined
+# Optimization level
+CXXFLAGS += -O1
+
+
+# ---- Controlling make ----
+
+# Clear default suffix rules
+.SUFFIXES:
+
+# Don't delete object files
+.SECONDARY:
+
+# Stuff concerning goals
+.DEFAULT_GOAL = all
+.PHONY: all clean
+
+
+# ---- Targets to build ----
+
+LIBSRC = BitBuffer QrCode QrSegment
+MAINS = QrCodeGeneratorDemo QrCodeGeneratorWorker
+
+# Build all binaries
+all: $(MAINS)
+
+# Delete build output
+clean:
+	rm -f -- $(MAINS)
+
+# Executable files
+%: %.cpp $(LIBSRC:=.cpp) $(LIBSRC:=.hpp)
+	$(CXX) $(CXXFLAGS) -o $@ $< $(LIBSRC:=.cpp)
diff --git a/src/third_party/QR-Code-generator/cpp/QrCode.cpp b/src/third_party/QR-Code-generator/cpp/QrCode.cpp
new file mode 100644
index 0000000..75a5473
--- /dev/null
+++ b/src/third_party/QR-Code-generator/cpp/QrCode.cpp
@@ -0,0 +1,616 @@
+/* 
+ * QR Code generator library (C++)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#include <algorithm>
+#include <climits>
+#include <cstddef>
+#include <cstdlib>
+#include <sstream>
+#include <utility>
+#include "BitBuffer.hpp"
+#include "QrCode.hpp"
+
+using std::int8_t;
+using std::uint8_t;
+using std::size_t;
+using std::vector;
+
+
+namespace qrcodegen {
+
+int QrCode::getFormatBits(Ecc ecl) {
+	switch (ecl) {
+		case Ecc::LOW     :  return 1;
+		case Ecc::MEDIUM  :  return 0;
+		case Ecc::QUARTILE:  return 3;
+		case Ecc::HIGH    :  return 2;
+		default:  throw "Assertion error";
+	}
+}
+
+
+QrCode QrCode::encodeText(const char *text, Ecc ecl) {
+	vector<QrSegment> segs = QrSegment::makeSegments(text);
+	return encodeSegments(segs, ecl);
+}
+
+
+QrCode QrCode::encodeBinary(const vector<uint8_t> &data, Ecc ecl) {
+	vector<QrSegment> segs{QrSegment::makeBytes(data)};
+	return encodeSegments(segs, ecl);
+}
+
+
+QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
+		int minVersion, int maxVersion, int mask, bool boostEcl) {
+	if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
+		throw "Invalid value";
+	
+	// Find the minimal version number to use
+	int version, dataUsedBits;
+	for (version = minVersion; ; version++) {
+		int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;  // Number of data bits available
+		dataUsedBits = QrSegment::getTotalBits(segs, version);
+		if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits)
+			break;  // This version number is found to be suitable
+		if (version >= maxVersion)  // All versions in the range could not fit the given data
+			throw "Data too long";
+	}
+	if (dataUsedBits == -1)
+		throw "Assertion error";
+	
+	// Increase the error correction level while the data still fits in the current version number
+	for (Ecc newEcl : vector<Ecc>{Ecc::MEDIUM, Ecc::QUARTILE, Ecc::HIGH}) {
+		if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8)
+			ecl = newEcl;
+	}
+	
+	// Create the data bit string by concatenating all segments
+	size_t dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
+	BitBuffer bb;
+	for (const QrSegment &seg : segs) {
+		bb.appendBits(seg.getMode().getModeBits(), 4);
+		bb.appendBits(seg.getNumChars(), seg.getMode().numCharCountBits(version));
+		bb.insert(bb.end(), seg.getData().begin(), seg.getData().end());
+	}
+	
+	// Add terminator and pad up to a byte if applicable
+	bb.appendBits(0, std::min<size_t>(4, dataCapacityBits - bb.size()));
+	bb.appendBits(0, (8 - bb.size() % 8) % 8);
+	
+	// Pad with alternate bytes until data capacity is reached
+	for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
+		bb.appendBits(padByte, 8);
+	if (bb.size() % 8 != 0)
+		throw "Assertion error";
+	
+	// Create the QR Code symbol
+	return QrCode(version, ecl, bb.getBytes(), mask);
+}
+
+
+QrCode::QrCode(int ver, Ecc ecl, const vector<uint8_t> &dataCodewords, int mask) :
+		// Initialize fields
+		version(ver),
+		size(MIN_VERSION <= ver && ver <= MAX_VERSION ? ver * 4 + 17 : -1),  // Avoid signed overflow undefined behavior
+		errorCorrectionLevel(ecl),
+		modules(size, vector<bool>(size)),  // Entirely white grid
+		isFunction(size, vector<bool>(size)) {
+	
+	// Check arguments
+	if (ver < MIN_VERSION || ver > MAX_VERSION || mask < -1 || mask > 7)
+		throw "Value out of range";
+	
+	// Draw function patterns, draw all codewords, do masking
+	drawFunctionPatterns();
+	const vector<uint8_t> allCodewords = appendErrorCorrection(dataCodewords);
+	drawCodewords(allCodewords);
+	this->mask = handleConstructorMasking(mask);
+}
+
+
+int QrCode::getVersion() const {
+	return version;
+}
+
+
+int QrCode::getSize() const {
+	return size;
+}
+
+
+QrCode::Ecc QrCode::getErrorCorrectionLevel() const {
+	return errorCorrectionLevel;
+}
+
+
+int QrCode::getMask() const {
+	return mask;
+}
+
+
+bool QrCode::getModule(int x, int y) const {
+	return 0 <= x && x < size && 0 <= y && y < size && module(x, y);
+}
+
+
+std::string QrCode::toSvgString(int border) const {
+	if (border < 0)
+		throw "Border must be non-negative";
+	if (border > INT_MAX / 2 || border * 2 > INT_MAX - size)
+		throw "Border too large";
+	
+	std::ostringstream sb;
+	sb << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	sb << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
+	sb << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 ";
+	sb << (size + border * 2) << " " << (size + border * 2) << "\" stroke=\"none\">\n";
+	sb << "\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n";
+	sb << "\t<path d=\"";
+	bool head = true;
+	for (int y = -border; y < size + border; y++) {
+		for (int x = -border; x < size + border; x++) {
+			if (getModule(x, y)) {
+				if (head)
+					head = false;
+				else
+					sb << " ";
+				sb << "M" << (x + border) << "," << (y + border) << "h1v1h-1z";
+			}
+		}
+	}
+	sb << "\" fill=\"#000000\"/>\n";
+	sb << "</svg>\n";
+	return sb.str();
+}
+
+
+void QrCode::drawFunctionPatterns() {
+	// Draw horizontal and vertical timing patterns
+	for (int i = 0; i < size; i++) {
+		setFunctionModule(6, i, i % 2 == 0);
+		setFunctionModule(i, 6, i % 2 == 0);
+	}
+	
+	// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
+	drawFinderPattern(3, 3);
+	drawFinderPattern(size - 4, 3);
+	drawFinderPattern(3, size - 4);
+	
+	// Draw numerous alignment patterns
+	const vector<int> alignPatPos = getAlignmentPatternPositions(version);
+	int numAlign = alignPatPos.size();
+	for (int i = 0; i < numAlign; i++) {
+		for (int j = 0; j < numAlign; j++) {
+			if ((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0))
+				continue;  // Skip the three finder corners
+			else
+				drawAlignmentPattern(alignPatPos.at(i), alignPatPos.at(j));
+		}
+	}
+	
+	// Draw configuration data
+	drawFormatBits(0);  // Dummy mask value; overwritten later in the constructor
+	drawVersion();
+}
+
+
+void QrCode::drawFormatBits(int mask) {
+	// Calculate error correction code and pack bits
+	int data = getFormatBits(errorCorrectionLevel) << 3 | mask;  // errCorrLvl is uint2, mask is uint3
+	int rem = data;
+	for (int i = 0; i < 10; i++)
+		rem = (rem << 1) ^ ((rem >> 9) * 0x537);
+	data = data << 10 | rem;
+	data ^= 0x5412;  // uint15
+	if (data >> 15 != 0)
+		throw "Assertion error";
+	
+	// Draw first copy
+	for (int i = 0; i <= 5; i++)
+		setFunctionModule(8, i, ((data >> i) & 1) != 0);
+	setFunctionModule(8, 7, ((data >> 6) & 1) != 0);
+	setFunctionModule(8, 8, ((data >> 7) & 1) != 0);
+	setFunctionModule(7, 8, ((data >> 8) & 1) != 0);
+	for (int i = 9; i < 15; i++)
+		setFunctionModule(14 - i, 8, ((data >> i) & 1) != 0);
+	
+	// Draw second copy
+	for (int i = 0; i <= 7; i++)
+		setFunctionModule(size - 1 - i, 8, ((data >> i) & 1) != 0);
+	for (int i = 8; i < 15; i++)
+		setFunctionModule(8, size - 15 + i, ((data >> i) & 1) != 0);
+	setFunctionModule(8, size - 8, true);
+}
+
+
+void QrCode::drawVersion() {
+	if (version < 7)
+		return;
+	
+	// Calculate error correction code and pack bits
+	int rem = version;  // version is uint6, in the range [7, 40]
+	for (int i = 0; i < 12; i++)
+		rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
+	long data = (long)version << 12 | rem;  // uint18
+	if (data >> 18 != 0)
+		throw "Assertion error";
+	
+	// Draw two copies
+	for (int i = 0; i < 18; i++) {
+		bool bit = ((data >> i) & 1) != 0;
+		int a = size - 11 + i % 3, b = i / 3;
+		setFunctionModule(a, b, bit);
+		setFunctionModule(b, a, bit);
+	}
+}
+
+
+void QrCode::drawFinderPattern(int x, int y) {
+	for (int i = -4; i <= 4; i++) {
+		for (int j = -4; j <= 4; j++) {
+			int dist = std::max(std::abs(i), std::abs(j));  // Chebyshev/infinity norm
+			int xx = x + j, yy = y + i;
+			if (0 <= xx && xx < size && 0 <= yy && yy < size)
+				setFunctionModule(xx, yy, dist != 2 && dist != 4);
+		}
+	}
+}
+
+
+void QrCode::drawAlignmentPattern(int x, int y) {
+	for (int i = -2; i <= 2; i++) {
+		for (int j = -2; j <= 2; j++)
+			setFunctionModule(x + j, y + i, std::max(std::abs(i), std::abs(j)) != 1);
+	}
+}
+
+
+void QrCode::setFunctionModule(int x, int y, bool isBlack) {
+	modules.at(y).at(x) = isBlack;
+	isFunction.at(y).at(x) = true;
+}
+
+
+bool QrCode::module(int x, int y) const {
+	return modules.at(y).at(x);
+}
+
+
+vector<uint8_t> QrCode::appendErrorCorrection(const vector<uint8_t> &data) const {
+	if (data.size() != static_cast<unsigned int>(getNumDataCodewords(version, errorCorrectionLevel)))
+		throw "Invalid argument";
+	
+	// Calculate parameter numbers
+	int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[static_cast<int>(errorCorrectionLevel)][version];
+	int blockEccLen = ECC_CODEWORDS_PER_BLOCK[static_cast<int>(errorCorrectionLevel)][version];
+	int rawCodewords = getNumRawDataModules(version) / 8;
+	int numShortBlocks = numBlocks - rawCodewords % numBlocks;
+	int shortBlockLen = rawCodewords / numBlocks;
+	
+	// Split data into blocks and append ECC to each block
+	vector<vector<uint8_t> > blocks;
+	const ReedSolomonGenerator rs(blockEccLen);
+	for (int i = 0, k = 0; i < numBlocks; i++) {
+		vector<uint8_t> dat(data.cbegin() + k, data.cbegin() + (k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1)));
+		k += dat.size();
+		const vector<uint8_t> ecc = rs.getRemainder(dat);
+		if (i < numShortBlocks)
+			dat.push_back(0);
+		dat.insert(dat.end(), ecc.cbegin(), ecc.cend());
+		blocks.push_back(std::move(dat));
+	}
+	
+	// Interleave (not concatenate) the bytes from every block into a single sequence
+	vector<uint8_t> result;
+	for (int i = 0; static_cast<unsigned int>(i) < blocks.at(0).size(); i++) {
+		for (int j = 0; static_cast<unsigned int>(j) < blocks.size(); j++) {
+			// Skip the padding byte in short blocks
+			if (i != shortBlockLen - blockEccLen || j >= numShortBlocks)
+				result.push_back(blocks.at(j).at(i));
+		}
+	}
+	if (result.size() != static_cast<unsigned int>(rawCodewords))
+		throw "Assertion error";
+	return result;
+}
+
+
+void QrCode::drawCodewords(const vector<uint8_t> &data) {
+	if (data.size() != static_cast<unsigned int>(getNumRawDataModules(version) / 8))
+		throw "Invalid argument";
+	
+	size_t i = 0;  // Bit index into the data
+	// Do the funny zigzag scan
+	for (int right = size - 1; right >= 1; right -= 2) {  // Index of right column in each column pair
+		if (right == 6)
+			right = 5;
+		for (int vert = 0; vert < size; vert++) {  // Vertical counter
+			for (int j = 0; j < 2; j++) {
+				int x = right - j;  // Actual x coordinate
+				bool upward = ((right + 1) & 2) == 0;
+				int y = upward ? size - 1 - vert : vert;  // Actual y coordinate
+				if (!isFunction.at(y).at(x) && i < data.size() * 8) {
+					modules.at(y).at(x) = ((data.at(i >> 3) >> (7 - (i & 7))) & 1) != 0;
+					i++;
+				}
+				// If there are any remainder bits (0 to 7), they are already
+				// set to 0/false/white when the grid of modules was initialized
+			}
+		}
+	}
+	if (static_cast<unsigned int>(i) != data.size() * 8)
+		throw "Assertion error";
+}
+
+
+void QrCode::applyMask(int mask) {
+	if (mask < 0 || mask > 7)
+		throw "Mask value out of range";
+	for (int y = 0; y < size; y++) {
+		for (int x = 0; x < size; x++) {
+			bool invert;
+			switch (mask) {
+				case 0:  invert = (x + y) % 2 == 0;                    break;
+				case 1:  invert = y % 2 == 0;                          break;
+				case 2:  invert = x % 3 == 0;                          break;
+				case 3:  invert = (x + y) % 3 == 0;                    break;
+				case 4:  invert = (x / 3 + y / 2) % 2 == 0;            break;
+				case 5:  invert = x * y % 2 + x * y % 3 == 0;          break;
+				case 6:  invert = (x * y % 2 + x * y % 3) % 2 == 0;    break;
+				case 7:  invert = ((x + y) % 2 + x * y % 3) % 2 == 0;  break;
+				default:  throw "Assertion error";
+			}
+			modules.at(y).at(x) = modules.at(y).at(x) ^ (invert & !isFunction.at(y).at(x));
+		}
+	}
+}
+
+
+int QrCode::handleConstructorMasking(int mask) {
+	if (mask == -1) {  // Automatically choose best mask
+		long minPenalty = LONG_MAX;
+		for (int i = 0; i < 8; i++) {
+			drawFormatBits(i);
+			applyMask(i);
+			long penalty = getPenaltyScore();
+			if (penalty < minPenalty) {
+				mask = i;
+				minPenalty = penalty;
+			}
+			applyMask(i);  // Undoes the mask due to XOR
+		}
+	}
+	if (mask < 0 || mask > 7)
+		throw "Assertion error";
+	drawFormatBits(mask);  // Overwrite old format bits
+	applyMask(mask);  // Apply the final choice of mask
+	return mask;  // The caller shall assign this value to the final-declared field
+}
+
+
+long QrCode::getPenaltyScore() const {
+	long result = 0;
+	
+	// Adjacent modules in row having same color
+	for (int y = 0; y < size; y++) {
+		bool colorX = false;
+		for (int x = 0, runX = -1; x < size; x++) {
+			if (x == 0 || module(x, y) != colorX) {
+				colorX = module(x, y);
+				runX = 1;
+			} else {
+				runX++;
+				if (runX == 5)
+					result += PENALTY_N1;
+				else if (runX > 5)
+					result++;
+			}
+		}
+	}
+	// Adjacent modules in column having same color
+	for (int x = 0; x < size; x++) {
+		bool colorY = false;
+		for (int y = 0, runY = -1; y < size; y++) {
+			if (y == 0 || module(x, y) != colorY) {
+				colorY = module(x, y);
+				runY = 1;
+			} else {
+				runY++;
+				if (runY == 5)
+					result += PENALTY_N1;
+				else if (runY > 5)
+					result++;
+			}
+		}
+	}
+	
+	// 2*2 blocks of modules having same color
+	for (int y = 0; y < size - 1; y++) {
+		for (int x = 0; x < size - 1; x++) {
+			bool  color = module(x, y);
+			if (  color == module(x + 1, y) &&
+			      color == module(x, y + 1) &&
+			      color == module(x + 1, y + 1))
+				result += PENALTY_N2;
+		}
+	}
+	
+	// Finder-like pattern in rows
+	for (int y = 0; y < size; y++) {
+		for (int x = 0, bits = 0; x < size; x++) {
+			bits = ((bits << 1) & 0x7FF) | (module(x, y) ? 1 : 0);
+			if (x >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
+				result += PENALTY_N3;
+		}
+	}
+	// Finder-like pattern in columns
+	for (int x = 0; x < size; x++) {
+		for (int y = 0, bits = 0; y < size; y++) {
+			bits = ((bits << 1) & 0x7FF) | (module(x, y) ? 1 : 0);
+			if (y >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
+				result += PENALTY_N3;
+		}
+	}
+	
+	// Balance of black and white modules
+	int black = 0;
+	for (const vector<bool> &row : modules) {
+		for (bool color : row) {
+			if (color)
+				black++;
+		}
+	}
+	int total = size * size;
+	// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
+	for (int k = 0; black*20L < (9L-k)*total || black*20L > (11L+k)*total; k++)
+		result += PENALTY_N4;
+	return result;
+}
+
+
+vector<int> QrCode::getAlignmentPatternPositions(int ver) {
+	if (ver < MIN_VERSION || ver > MAX_VERSION)
+		throw "Version number out of range";
+	else if (ver == 1)
+		return vector<int>();
+	else {
+		int numAlign = ver / 7 + 2;
+		int step;
+		if (ver != 32) {
+			// ceil((size - 13) / (2*numAlign - 2)) * 2
+			step = (ver * 4 + numAlign * 2 + 1) / (2 * numAlign - 2) * 2;
+		} else  // C-C-C-Combo breaker!
+			step = 26;
+		
+		vector<int> result;
+		for (int i = 0, pos = ver * 4 + 10; i < numAlign - 1; i++, pos -= step)
+			result.insert(result.begin(), pos);
+		result.insert(result.begin(), 6);
+		return result;
+	}
+}
+
+
+int QrCode::getNumRawDataModules(int ver) {
+	if (ver < MIN_VERSION || ver > MAX_VERSION)
+		throw "Version number out of range";
+	int result = (16 * ver + 128) * ver + 64;
+	if (ver >= 2) {
+		int numAlign = ver / 7 + 2;
+		result -= (25 * numAlign - 10) * numAlign - 55;
+		if (ver >= 7)
+			result -= 18 * 2;  // Subtract version information
+	}
+	return result;
+}
+
+
+int QrCode::getNumDataCodewords(int ver, Ecc ecl) {
+	if (ver < MIN_VERSION || ver > MAX_VERSION)
+		throw "Version number out of range";
+	return getNumRawDataModules(ver) / 8
+		- ECC_CODEWORDS_PER_BLOCK[static_cast<int>(ecl)][ver]
+		* NUM_ERROR_CORRECTION_BLOCKS[static_cast<int>(ecl)][ver];
+}
+
+
+/*---- Tables of constants ----*/
+
+const int QrCode::PENALTY_N1 = 3;
+const int QrCode::PENALTY_N2 = 3;
+const int QrCode::PENALTY_N3 = 40;
+const int QrCode::PENALTY_N4 = 10;
+
+
+const int8_t QrCode::ECC_CODEWORDS_PER_BLOCK[4][41] = {
+	// Version: (note that index 0 is for padding, and is set to an illegal value)
+	//0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+	{-1,  7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},  // Low
+	{-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28},  // Medium
+	{-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},  // Quartile
+	{-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},  // High
+};
+
+const int8_t QrCode::NUM_ERROR_CORRECTION_BLOCKS[4][41] = {
+	// Version: (note that index 0 is for padding, and is set to an illegal value)
+	//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+	{-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25},  // Low
+	{-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49},  // Medium
+	{-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68},  // Quartile
+	{-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81},  // High
+};
+
+
+QrCode::ReedSolomonGenerator::ReedSolomonGenerator(int degree) :
+		coefficients() {
+	if (degree < 1 || degree > 255)
+		throw "Degree out of range";
+	
+	// Start with the monomial x^0
+	coefficients.resize(degree);
+	coefficients.at(degree - 1) = 1;
+	
+	// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
+	// drop the highest term, and store the rest of the coefficients in order of descending powers.
+	// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
+	uint8_t root = 1;
+	for (int i = 0; i < degree; i++) {
+		// Multiply the current product by (x - r^i)
+		for (size_t j = 0; j < coefficients.size(); j++) {
+			coefficients.at(j) = multiply(coefficients.at(j), root);
+			if (j + 1 < coefficients.size())
+				coefficients.at(j) ^= coefficients.at(j + 1);
+		}
+		root = multiply(root, 0x02);
+	}
+}
+
+
+vector<uint8_t> QrCode::ReedSolomonGenerator::getRemainder(const vector<uint8_t> &data) const {
+	// Compute the remainder by performing polynomial division
+	vector<uint8_t> result(coefficients.size());
+	for (uint8_t b : data) {
+		uint8_t factor = b ^ result.at(0);
+		result.erase(result.begin());
+		result.push_back(0);
+		for (size_t j = 0; j < result.size(); j++)
+			result.at(j) ^= multiply(coefficients.at(j), factor);
+	}
+	return result;
+}
+
+
+uint8_t QrCode::ReedSolomonGenerator::multiply(uint8_t x, uint8_t y) {
+	// Russian peasant multiplication
+	int z = 0;
+	for (int i = 7; i >= 0; i--) {
+		z = (z << 1) ^ ((z >> 7) * 0x11D);
+		z ^= ((y >> i) & 1) * x;
+	}
+	if (z >> 8 != 0)
+		throw "Assertion error";
+	return static_cast<uint8_t>(z);
+}
+
+}
diff --git a/src/third_party/QR-Code-generator/cpp/QrCode.hpp b/src/third_party/QR-Code-generator/cpp/QrCode.hpp
new file mode 100644
index 0000000..14a3f61
--- /dev/null
+++ b/src/third_party/QR-Code-generator/cpp/QrCode.hpp
@@ -0,0 +1,306 @@
+/* 
+ * QR Code generator library (C++)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <string>
+#include <vector>
+#include "QrSegment.hpp"
+
+
+namespace qrcodegen {
+
+/* 
+ * Represents an immutable square grid of black and white cells for a QR Code symbol, and
+ * provides static functions to create a QR Code from user-supplied textual or binary data.
+ * This class covers the QR Code model 2 specification, supporting all versions (sizes)
+ * from 1 to 40, all 4 error correction levels, and only 3 character encoding modes.
+ */
+class QrCode final {
+	
+	/*---- Public helper enumeration ----*/
+	
+	/* 
+	 * Represents the error correction level used in a QR Code symbol.
+	 */
+	public: enum class Ecc {
+		// Constants declared in ascending order of error protection.
+		LOW = 0, MEDIUM = 1, QUARTILE = 2, HIGH = 3
+	};
+	
+	
+	// Returns a value in the range 0 to 3 (unsigned 2-bit integer).
+	private: static int getFormatBits(Ecc ecl);
+	
+	
+	
+	/*---- Public static factory functions ----*/
+	
+	/* 
+	 * Returns a QR Code symbol representing the specified Unicode text string at the specified error correction level.
+	 * As a conservative upper bound, this function is guaranteed to succeed for strings that have 2953 or fewer
+	 * UTF-8 code units (not Unicode code points) if the low error correction level is used. The smallest possible
+	 * QR Code version is automatically chosen for the output. The ECC level of the result may be higher than
+	 * the ecl argument if it can be done without increasing the version.
+	 */
+	public: static QrCode encodeText(const char *text, Ecc ecl);
+	
+	
+	/* 
+	 * Returns a QR Code symbol representing the given binary data string at the given error correction level.
+	 * This function always encodes using the binary segment mode, not any text mode. The maximum number of
+	 * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
+	 * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
+	 */
+	public: static QrCode encodeBinary(const std::vector<std::uint8_t> &data, Ecc ecl);
+	
+	
+	/* 
+	 * Returns a QR Code symbol representing the given data segments with the given encoding parameters.
+	 * The smallest possible QR Code version within the given range is automatically chosen for the output.
+	 * This function allows the user to create a custom sequence of segments that switches
+	 * between modes (such as alphanumeric and binary) to encode text more efficiently.
+	 * This function is considered to be lower level than simply encoding text or binary data.
+	 */
+	public: static QrCode encodeSegments(const std::vector<QrSegment> &segs, Ecc ecl,
+		int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true);  // All optional parameters
+	
+	
+	
+	/*---- Public constants ----*/
+	
+	public: static constexpr int MIN_VERSION =  1;
+	public: static constexpr int MAX_VERSION = 40;
+	
+	
+	
+	/*---- Instance fields ----*/
+	
+	// Immutable scalar parameters
+	
+	/* This QR Code symbol's version number, which is always between 1 and 40 (inclusive). */
+	private: int version;
+	
+	/* The width and height of this QR Code symbol, measured in modules.
+	 * Always equal to version &times; 4 + 17, in the range 21 to 177. */
+	private: int size;
+	
+	/* The error correction level used in this QR Code symbol. */
+	private: Ecc errorCorrectionLevel;
+	
+	/* The mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer).
+	 * Note that even if a constructor was called with automatic masking requested
+	 * (mask = -1), the resulting object will still have a mask value between 0 and 7. */
+	private: int mask;
+	
+	// Private grids of modules/pixels (conceptually immutable)
+	private: std::vector<std::vector<bool> > modules;     // The modules of this QR Code symbol (false = white, true = black)
+	private: std::vector<std::vector<bool> > isFunction;  // Indicates function modules that are not subjected to masking
+	
+	
+	
+	/*---- Constructors ----*/
+	
+	/* 
+	 * Creates a new QR Code symbol with the given version number, error correction level, binary data array,
+	 * and mask number. This is a cumbersome low-level constructor that should not be invoked directly by the user.
+	 * To go one level up, see the encodeSegments() function.
+	 */
+	public: QrCode(int ver, Ecc ecl, const std::vector<std::uint8_t> &dataCodewords, int mask);
+	
+	
+	
+	/*---- Public instance methods ----*/
+	
+	public: int getVersion() const;
+	
+	
+	public: int getSize() const;
+	
+	
+	public: Ecc getErrorCorrectionLevel() const;
+	
+	
+	public: int getMask() const;
+	
+	
+	/* 
+	 * Returns the color of the module (pixel) at the given coordinates, which is either
+	 * false for white or true for black. The top left corner has the coordinates (x=0, y=0).
+	 * If the given coordinates are out of bounds, then false (white) is returned.
+	 */
+	public: bool getModule(int x, int y) const;
+	
+	
+	/* 
+	 * Based on the given number of border modules to add as padding, this returns a
+	 * string whose contents represents an SVG XML file that depicts this QR Code symbol.
+	 * Note that Unix newlines (\n) are always used, regardless of the platform.
+	 */
+	public: std::string toSvgString(int border) const;
+	
+	
+	
+	/*---- Private helper methods for constructor: Drawing function modules ----*/
+	
+	private: void drawFunctionPatterns();
+	
+	
+	// Draws two copies of the format bits (with its own error correction code)
+	// based on the given mask and this object's error correction level field.
+	private: void drawFormatBits(int mask);
+	
+	
+	// Draws two copies of the version bits (with its own error correction code),
+	// based on this object's version field (which only has an effect for 7 <= version <= 40).
+	private: void drawVersion();
+	
+	
+	// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y).
+	private: void drawFinderPattern(int x, int y);
+	
+	
+	// Draws a 5*5 alignment pattern, with the center module at (x, y).
+	private: void drawAlignmentPattern(int x, int y);
+	
+	
+	// Sets the color of a module and marks it as a function module.
+	// Only used by the constructor. Coordinates must be in range.
+	private: void setFunctionModule(int x, int y, bool isBlack);
+	
+	
+	// Returns the color of the module at the given coordinates, which must be in range.
+	private: bool module(int x, int y) const;
+	
+	
+	/*---- Private helper methods for constructor: Codewords and masking ----*/
+	
+	// Returns a new byte string representing the given data with the appropriate error correction
+	// codewords appended to it, based on this object's version and error correction level.
+	private: std::vector<std::uint8_t> appendErrorCorrection(const std::vector<std::uint8_t> &data) const;
+	
+	
+	// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
+	// data area of this QR Code symbol. Function modules need to be marked off before this is called.
+	private: void drawCodewords(const std::vector<std::uint8_t> &data);
+	
+	
+	// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
+	// properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
+	// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
+	// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
+	private: void applyMask(int mask);
+	
+	
+	// A messy helper function for the constructors. This QR Code must be in an unmasked state when this
+	// method is called. The given argument is the requested mask, which is -1 for auto or 0 to 7 for fixed.
+	// This method applies and returns the actual mask chosen, from 0 to 7.
+	private: int handleConstructorMasking(int mask);
+	
+	
+	// Calculates and returns the penalty score based on state of this QR Code's current modules.
+	// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
+	private: long getPenaltyScore() const;
+	
+	
+	
+	/*---- Private static helper functions ----*/
+	
+	// Returns a set of positions of the alignment patterns in ascending order. These positions are
+	// used on both the x and y axes. Each value in the resulting array is in the range [0, 177).
+	// This stateless pure function could be implemented as table of 40 variable-length lists of unsigned bytes.
+	private: static std::vector<int> getAlignmentPatternPositions(int ver);
+	
+	
+	// Returns the number of data bits that can be stored in a QR Code of the given version number, after
+	// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
+	// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
+	private: static int getNumRawDataModules(int ver);
+	
+	
+	// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
+	// QR Code of the given version number and error correction level, with remainder bits discarded.
+	// This stateless pure function could be implemented as a (40*4)-cell lookup table.
+	private: static int getNumDataCodewords(int ver, Ecc ecl);
+	
+	
+	/*---- Private tables of constants ----*/
+	
+	// For use in getPenaltyScore(), when evaluating which mask is best.
+	private: static const int PENALTY_N1;
+	private: static const int PENALTY_N2;
+	private: static const int PENALTY_N3;
+	private: static const int PENALTY_N4;
+	
+	private: static const std::int8_t ECC_CODEWORDS_PER_BLOCK[4][41];
+	private: static const std::int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41];
+	
+	
+	
+	/*---- Private helper class ----*/
+	
+	/* 
+	 * Computes the Reed-Solomon error correction codewords for a sequence of data codewords
+	 * at a given degree. Objects are immutable, and the state only depends on the degree.
+	 * This class exists because each data block in a QR Code shares the same the divisor polynomial.
+	 */
+	private: class ReedSolomonGenerator final {
+		
+		/*-- Immutable field --*/
+		
+		// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which
+		// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
+		private: std::vector<std::uint8_t> coefficients;
+		
+		
+		/*-- Constructor --*/
+		
+		/* 
+		 * Creates a Reed-Solomon ECC generator for the given degree. This could be implemented
+		 * as a lookup table over all possible parameter values, instead of as an algorithm.
+		 */
+		public: explicit ReedSolomonGenerator(int degree);
+		
+		
+		/*-- Method --*/
+		
+		/* 
+		 * Computes and returns the Reed-Solomon error correction codewords for the given
+		 * sequence of data codewords. The returned object is always a new byte array.
+		 * This method does not alter this object's state (because it is immutable).
+		 */
+		public: std::vector<std::uint8_t> getRemainder(const std::vector<std::uint8_t> &data) const;
+		
+		
+		/*-- Static function --*/
+		
+		// Returns the product of the two given field elements modulo GF(2^8/0x11D).
+		// All inputs are valid. This could be implemented as a 256*256 lookup table.
+		private: static std::uint8_t multiply(std::uint8_t x, std::uint8_t y);
+		
+	};
+	
+};
+
+}
diff --git a/src/third_party/QR-Code-generator/cpp/QrCodeGeneratorDemo.cpp b/src/third_party/QR-Code-generator/cpp/QrCodeGeneratorDemo.cpp
new file mode 100644
index 0000000..5c78b51
--- /dev/null
+++ b/src/third_party/QR-Code-generator/cpp/QrCodeGeneratorDemo.cpp
@@ -0,0 +1,199 @@
+/* 
+ * QR Code generator demo (C++)
+ * 
+ * Run this command-line program with no arguments. The program computes a bunch of demonstration
+ * QR Codes and prints them to the console. Also, the SVG code for one QR Code is printed as a sample.
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <vector>
+#include "BitBuffer.hpp"
+#include "QrCode.hpp"
+
+using std::uint8_t;
+using qrcodegen::QrCode;
+using qrcodegen::QrSegment;
+
+
+// Function prototypes
+static void doBasicDemo();
+static void doVarietyDemo();
+static void doSegmentDemo();
+static void doMaskDemo();
+static void printQr(const QrCode &qr);
+
+
+// The main application program.
+int main() {
+	doBasicDemo();
+	doVarietyDemo();
+	doSegmentDemo();
+	doMaskDemo();
+	return EXIT_SUCCESS;
+}
+
+
+
+/*---- Demo suite ----*/
+
+// Creates a single QR Code, then prints it to the console.
+static void doBasicDemo() {
+	const char *text = "Hello, world!";  // User-supplied text
+	const QrCode::Ecc errCorLvl = QrCode::Ecc::LOW;  // Error correction level
+	
+	// Make and print the QR Code symbol
+	const QrCode qr = QrCode::encodeText(text, errCorLvl);
+	printQr(qr);
+	std::cout << qr.toSvgString(4) << std::endl;
+}
+
+
+// Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console.
+static void doVarietyDemo() {
+	// Numeric mode encoding (3.33 bits per digit)
+	const QrCode qr1 = QrCode::encodeText("314159265358979323846264338327950288419716939937510", QrCode::Ecc::MEDIUM);
+	printQr(qr1);
+	
+	// Alphanumeric mode encoding (5.5 bits per character)
+	const QrCode qr2 = QrCode::encodeText("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", QrCode::Ecc::HIGH);
+	printQr(qr2);
+	
+	// Unicode text as UTF-8
+	const QrCode qr3 = QrCode::encodeText("\xE3\x81\x93\xE3\x82\x93\xE3\x81\xAB\xE3\x81\xA1wa\xE3\x80\x81\xE4\xB8\x96\xE7\x95\x8C\xEF\xBC\x81\x20\xCE\xB1\xCE\xB2\xCE\xB3\xCE\xB4", QrCode::Ecc::QUARTILE);
+	printQr(qr3);
+	
+	// Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
+	const QrCode qr4 = QrCode::encodeText(
+		"Alice was beginning to get very tired of sitting by her sister on the bank, "
+		"and of having nothing to do: once or twice she had peeped into the book her sister was reading, "
+		"but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice "
+		"'without pictures or conversations?' So she was considering in her own mind (as well as she could, "
+		"for the hot day made her feel very sleepy and stupid), whether the pleasure of making a "
+		"daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly "
+		"a White Rabbit with pink eyes ran close by her.", QrCode::Ecc::HIGH);
+	printQr(qr4);
+}
+
+
+// Creates QR Codes with manually specified segments for better compactness.
+static void doSegmentDemo() {
+	// Illustration "silver"
+	const char *silver0 = "THE SQUARE ROOT OF 2 IS 1.";
+	const char *silver1 = "41421356237309504880168872420969807856967187537694807317667973799";
+	const QrCode qr0 = QrCode::encodeText(
+		(std::string(silver0) + silver1).c_str(),
+		QrCode::Ecc::LOW);
+	printQr(qr0);
+	
+	const QrCode qr1 = QrCode::encodeSegments(
+		{QrSegment::makeAlphanumeric(silver0), QrSegment::makeNumeric(silver1)},
+		QrCode::Ecc::LOW);
+	printQr(qr1);
+	
+	// Illustration "golden"
+	const char *golden0 = "Golden ratio \xCF\x86 = 1.";
+	const char *golden1 = "6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374";
+	const char *golden2 = "......";
+	const QrCode qr2 = QrCode::encodeText(
+		(std::string(golden0) + golden1 + golden2).c_str(),
+		QrCode::Ecc::LOW);
+	printQr(qr2);
+	
+	std::vector<uint8_t> bytes(golden0, golden0 + std::strlen(golden0));
+	const QrCode qr3 = QrCode::encodeSegments(
+		{QrSegment::makeBytes(bytes), QrSegment::makeNumeric(golden1), QrSegment::makeAlphanumeric(golden2)},
+		QrCode::Ecc::LOW);
+	printQr(qr3);
+	
+	// Illustration "Madoka": kanji, kana, Greek, Cyrillic, full-width Latin characters
+	const char *madoka =  // Encoded in UTF-8
+		"\xE3\x80\x8C\xE9\xAD\x94\xE6\xB3\x95\xE5"
+		"\xB0\x91\xE5\xA5\xB3\xE3\x81\xBE\xE3\x81"
+		"\xA9\xE3\x81\x8B\xE2\x98\x86\xE3\x83\x9E"
+		"\xE3\x82\xAE\xE3\x82\xAB\xE3\x80\x8D\xE3"
+		"\x81\xA3\xE3\x81\xA6\xE3\x80\x81\xE3\x80"
+		"\x80\xD0\x98\xD0\x90\xD0\x98\xE3\x80\x80"
+		"\xEF\xBD\x84\xEF\xBD\x85\xEF\xBD\x93\xEF"
+		"\xBD\x95\xE3\x80\x80\xCE\xBA\xCE\xB1\xEF"
+		"\xBC\x9F";
+	const QrCode qr4 = QrCode::encodeText(madoka, QrCode::Ecc::LOW);
+	printQr(qr4);
+	
+	const std::vector<int> kanjiChars{  // Kanji mode encoding (13 bits per character)
+		0x0035, 0x1002, 0x0FC0, 0x0AED, 0x0AD7,
+		0x015C, 0x0147, 0x0129, 0x0059, 0x01BD,
+		0x018D, 0x018A, 0x0036, 0x0141, 0x0144,
+		0x0001, 0x0000, 0x0249, 0x0240, 0x0249,
+		0x0000, 0x0104, 0x0105, 0x0113, 0x0115,
+		0x0000, 0x0208, 0x01FF, 0x0008,
+	};
+	qrcodegen::BitBuffer bb;
+	for (int c : kanjiChars)
+		bb.appendBits(c, 13);
+	const QrCode qr5 = QrCode::encodeSegments(
+		{QrSegment(QrSegment::Mode::KANJI, kanjiChars.size(), bb)},
+		QrCode::Ecc::LOW);
+	printQr(qr5);
+}
+
+
+// Creates QR Codes with the same size and contents but different mask patterns.
+static void doMaskDemo() {
+	// Project Nayuki URL
+	std::vector<QrSegment> segs0 = QrSegment::makeSegments("https://www.nayuki.io/");
+	printQr(QrCode::encodeSegments(segs0, QrCode::Ecc::HIGH, QrCode::MIN_VERSION, QrCode::MAX_VERSION, -1, true));  // Automatic mask
+	printQr(QrCode::encodeSegments(segs0, QrCode::Ecc::HIGH, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 3, true));  // Force mask 3
+	
+	// Chinese text as UTF-8
+	std::vector<QrSegment> segs1 = QrSegment::makeSegments(
+		"\xE7\xB6\xAD\xE5\x9F\xBA\xE7\x99\xBE\xE7\xA7\x91\xEF\xBC\x88\x57\x69\x6B\x69\x70"
+		"\x65\x64\x69\x61\xEF\xBC\x8C\xE8\x81\x86\xE8\x81\xBD\x69\x2F\xCB\x8C\x77\xC9\xAA"
+		"\x6B\xE1\xB5\xBB\xCB\x88\x70\x69\xCB\x90\x64\x69\x2E\xC9\x99\x2F\xEF\xBC\x89\xE6"
+		"\x98\xAF\xE4\xB8\x80\xE5\x80\x8B\xE8\x87\xAA\xE7\x94\xB1\xE5\x85\xA7\xE5\xAE\xB9"
+		"\xE3\x80\x81\xE5\x85\xAC\xE9\x96\x8B\xE7\xB7\xA8\xE8\xBC\xAF\xE4\xB8\x94\xE5\xA4"
+		"\x9A\xE8\xAA\x9E\xE8\xA8\x80\xE7\x9A\x84\xE7\xB6\xB2\xE8\xB7\xAF\xE7\x99\xBE\xE7"
+		"\xA7\x91\xE5\x85\xA8\xE6\x9B\xB8\xE5\x8D\x94\xE4\xBD\x9C\xE8\xA8\x88\xE7\x95\xAB");
+	printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 0, true));  // Force mask 0
+	printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 1, true));  // Force mask 1
+	printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 5, true));  // Force mask 5
+	printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 7, true));  // Force mask 7
+}
+
+
+
+/*---- Utilities ----*/
+
+// Prints the given QR Code to the console.
+static void printQr(const QrCode &qr) {
+	int border = 4;
+	for (int y = -border; y < qr.getSize() + border; y++) {
+		for (int x = -border; x < qr.getSize() + border; x++) {
+			std::cout << (qr.getModule(x, y) ? "##" : "  ");
+		}
+		std::cout << std::endl;
+	}
+	std::cout << std::endl;
+}
diff --git a/src/third_party/QR-Code-generator/cpp/QrCodeGeneratorWorker.cpp b/src/third_party/QR-Code-generator/cpp/QrCodeGeneratorWorker.cpp
new file mode 100644
index 0000000..2e14607
--- /dev/null
+++ b/src/third_party/QR-Code-generator/cpp/QrCodeGeneratorWorker.cpp
@@ -0,0 +1,104 @@
+/* 
+ * QR Code generator test worker (C++)
+ * 
+ * This program reads data and encoding parameters from standard input and writes
+ * QR Code bitmaps to standard output. The I/O format is one integer per line.
+ * Run with no command line arguments. The program is intended for automated
+ * batch testing of end-to-end functionality of this QR Code generator library.
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <vector>
+#include "QrCode.hpp"
+
+using qrcodegen::QrCode;
+using qrcodegen::QrSegment;
+
+
+static const std::vector<QrCode::Ecc> ECC_LEVELS{
+	QrCode::Ecc::LOW,
+	QrCode::Ecc::MEDIUM,
+	QrCode::Ecc::QUARTILE,
+	QrCode::Ecc::HIGH,
+};
+
+
+int main() {
+	while (true) {
+		
+		// Read data length or exit
+		int length;
+		std::cin >> length;
+		if (length == -1)
+			break;
+		
+		// Read data bytes
+		bool isAscii = true;
+		std::vector<uint8_t> data;
+		for (int i = 0; i < length; i++) {
+			int b;
+			std::cin >> b;
+			data.push_back(static_cast<uint8_t>(b));
+			isAscii &= 0 < b && b < 128;
+		}
+		
+		// Read encoding parameters
+		int errCorLvl, minVersion, maxVersion, mask, boostEcl;
+		std::cin >> errCorLvl;
+		std::cin >> minVersion;
+		std::cin >> maxVersion;
+		std::cin >> mask;
+		std::cin >> boostEcl;
+		
+		// Make list of segments
+		std::vector<QrSegment> segs;
+		if (isAscii) {
+			std::vector<char> text(data.cbegin(), data.cend());
+			text.push_back('\0');
+			segs = QrSegment::makeSegments(text.data());
+		} else
+			segs.push_back(QrSegment::makeBytes(data));
+		
+		try {  // Try to make QR Code symbol
+			const QrCode qr = QrCode::encodeSegments(segs,
+				ECC_LEVELS.at(errCorLvl), minVersion, maxVersion, mask, boostEcl == 1);
+			// Print grid of modules
+			std::cout << qr.getVersion() << std::endl;
+			for (int y = 0; y < qr.getSize(); y++) {
+				for (int x = 0; x < qr.getSize(); x++)
+					std::cout << (qr.getModule(x, y) ? 1 : 0) << std::endl;
+			}
+			
+		} catch (const char *msg) {
+			if (strcmp(msg, "Data too long") != 0) {
+				std::cerr << msg << std::endl;
+				return EXIT_FAILURE;
+			}
+			std::cout << -1 << std::endl;
+		}
+		std::cout << std::flush;
+	}
+	return EXIT_SUCCESS;
+}
diff --git a/src/third_party/QR-Code-generator/cpp/QrSegment.cpp b/src/third_party/QR-Code-generator/cpp/QrSegment.cpp
new file mode 100644
index 0000000..f711461
--- /dev/null
+++ b/src/third_party/QR-Code-generator/cpp/QrSegment.cpp
@@ -0,0 +1,228 @@
+/* 
+ * QR Code generator library (C++)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#include <climits>
+#include <cstring>
+#include <utility>
+#include "QrSegment.hpp"
+
+using std::uint8_t;
+using std::vector;
+
+
+namespace qrcodegen {
+
+QrSegment::Mode::Mode(int mode, int cc0, int cc1, int cc2) :
+		modeBits(mode) {
+	numBitsCharCount[0] = cc0;
+	numBitsCharCount[1] = cc1;
+	numBitsCharCount[2] = cc2;
+}
+
+
+int QrSegment::Mode::getModeBits() const {
+	return modeBits;
+}
+
+
+int QrSegment::Mode::numCharCountBits(int ver) const {
+	if      ( 1 <= ver && ver <=  9)  return numBitsCharCount[0];
+	else if (10 <= ver && ver <= 26)  return numBitsCharCount[1];
+	else if (27 <= ver && ver <= 40)  return numBitsCharCount[2];
+	else  throw "Version number out of range";
+}
+
+
+const QrSegment::Mode QrSegment::Mode::NUMERIC     (0x1, 10, 12, 14);
+const QrSegment::Mode QrSegment::Mode::ALPHANUMERIC(0x2,  9, 11, 13);
+const QrSegment::Mode QrSegment::Mode::BYTE        (0x4,  8, 16, 16);
+const QrSegment::Mode QrSegment::Mode::KANJI       (0x8,  8, 10, 12);
+const QrSegment::Mode QrSegment::Mode::ECI         (0x7,  0,  0,  0);
+
+
+
+QrSegment QrSegment::makeBytes(const vector<uint8_t> &data) {
+	if (data.size() > INT_MAX)
+		throw "Data too long";
+	BitBuffer bb;
+	for (uint8_t b : data)
+		bb.appendBits(b, 8);
+	return QrSegment(Mode::BYTE, static_cast<int>(data.size()), std::move(bb));
+}
+
+
+QrSegment QrSegment::makeNumeric(const char *digits) {
+	BitBuffer bb;
+	int accumData = 0;
+	int accumCount = 0;
+	int charCount = 0;
+	for (; *digits != '\0'; digits++, charCount++) {
+		char c = *digits;
+		if (c < '0' || c > '9')
+			throw "String contains non-numeric characters";
+		accumData = accumData * 10 + (c - '0');
+		accumCount++;
+		if (accumCount == 3) {
+			bb.appendBits(accumData, 10);
+			accumData = 0;
+			accumCount = 0;
+		}
+	}
+	if (accumCount > 0)  // 1 or 2 digits remaining
+		bb.appendBits(accumData, accumCount * 3 + 1);
+	return QrSegment(Mode::NUMERIC, charCount, std::move(bb));
+}
+
+
+QrSegment QrSegment::makeAlphanumeric(const char *text) {
+	BitBuffer bb;
+	int accumData = 0;
+	int accumCount = 0;
+	int charCount = 0;
+	for (; *text != '\0'; text++, charCount++) {
+		const char *temp = std::strchr(ALPHANUMERIC_CHARSET, *text);
+		if (temp == nullptr)
+			throw "String contains unencodable characters in alphanumeric mode";
+		accumData = accumData * 45 + (temp - ALPHANUMERIC_CHARSET);
+		accumCount++;
+		if (accumCount == 2) {
+			bb.appendBits(accumData, 11);
+			accumData = 0;
+			accumCount = 0;
+		}
+	}
+	if (accumCount > 0)  // 1 character remaining
+		bb.appendBits(accumData, 6);
+	return QrSegment(Mode::ALPHANUMERIC, charCount, std::move(bb));
+}
+
+
+vector<QrSegment> QrSegment::makeSegments(const char *text) {
+	// Select the most efficient segment encoding automatically
+	vector<QrSegment> result;
+	if (*text == '\0');  // Leave result empty
+	else if (isNumeric(text))
+		result.push_back(makeNumeric(text));
+	else if (isAlphanumeric(text))
+		result.push_back(makeAlphanumeric(text));
+	else {
+		vector<uint8_t> bytes;
+		for (; *text != '\0'; text++)
+			bytes.push_back(static_cast<uint8_t>(*text));
+		result.push_back(makeBytes(bytes));
+	}
+	return result;
+}
+
+
+QrSegment QrSegment::makeEci(long assignVal) {
+	BitBuffer bb;
+	if (0 <= assignVal && assignVal < (1 << 7))
+		bb.appendBits(assignVal, 8);
+	else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) {
+		bb.appendBits(2, 2);
+		bb.appendBits(assignVal, 14);
+	} else if ((1 << 14) <= assignVal && assignVal < 1000000L) {
+		bb.appendBits(6, 3);
+		bb.appendBits(assignVal, 21);
+	} else
+		throw "ECI assignment value out of range";
+	return QrSegment(Mode::ECI, 0, std::move(bb));
+}
+
+
+QrSegment::QrSegment(Mode md, int numCh, const std::vector<bool> &dt) :
+		mode(md),
+		numChars(numCh),
+		data(dt) {
+	if (numCh < 0)
+		throw "Invalid value";
+}
+
+
+QrSegment::QrSegment(Mode md, int numCh, std::vector<bool> &&dt) :
+		mode(md),
+		numChars(numCh),
+		data(std::move(dt)) {
+	if (numCh < 0)
+		throw "Invalid value";
+}
+
+
+int QrSegment::getTotalBits(const vector<QrSegment> &segs, int version) {
+	if (version < 1 || version > 40)
+		throw "Version number out of range";
+	int result = 0;
+	for (const QrSegment &seg : segs) {
+		int ccbits = seg.mode.numCharCountBits(version);
+		// Fail if segment length value doesn't fit in the length field's bit-width
+		if (seg.numChars >= (1L << ccbits))
+			return -1;
+		if (4 + ccbits > INT_MAX - result)
+			return -1;
+		result += 4 + ccbits;
+		if (seg.data.size() > static_cast<unsigned int>(INT_MAX - result))
+			return -1;
+		result += static_cast<int>(seg.data.size());
+	}
+	return result;
+}
+
+
+bool QrSegment::isAlphanumeric(const char *text) {
+	for (; *text != '\0'; text++) {
+		if (std::strchr(ALPHANUMERIC_CHARSET, *text) == nullptr)
+			return false;
+	}
+	return true;
+}
+
+
+bool QrSegment::isNumeric(const char *text) {
+	for (; *text != '\0'; text++) {
+		char c = *text;
+		if (c < '0' || c > '9')
+			return false;
+	}
+	return true;
+}
+
+
+QrSegment::Mode QrSegment::getMode() const {
+	return mode;
+}
+
+
+int QrSegment::getNumChars() const {
+	return numChars;
+}
+
+
+const std::vector<bool> &QrSegment::getData() const {
+	return data;
+}
+
+
+const char *QrSegment::ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
+
+}
diff --git a/src/third_party/QR-Code-generator/cpp/QrSegment.hpp b/src/third_party/QR-Code-generator/cpp/QrSegment.hpp
new file mode 100644
index 0000000..2b9eb66
--- /dev/null
+++ b/src/third_party/QR-Code-generator/cpp/QrSegment.hpp
@@ -0,0 +1,186 @@
+/* 
+ * QR Code generator library (C++)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <vector>
+#include "BitBuffer.hpp"
+
+
+namespace qrcodegen {
+
+/* 
+ * Represents a character string to be encoded in a QR Code symbol. Each segment has
+ * a mode, and a sequence of characters that is already encoded as a sequence of bits.
+ * Instances of this class are immutable.
+ * This segment class imposes no length restrictions, but QR Codes have restrictions.
+ * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
+ * Any segment longer than this is meaningless for the purpose of generating QR Codes.
+ */
+class QrSegment final {
+	
+	/*---- Public helper enumeration ----*/
+	
+	/* 
+	 * The mode field of a segment. Immutable. Provides methods to retrieve closely related values.
+	 */
+	public: class Mode final {
+		
+		/*-- Constants --*/
+		
+		public: static const Mode NUMERIC;
+		public: static const Mode ALPHANUMERIC;
+		public: static const Mode BYTE;
+		public: static const Mode KANJI;
+		public: static const Mode ECI;
+		
+		
+		/*-- Fields --*/
+		
+		private: int modeBits;
+		
+		private: int numBitsCharCount[3];
+		
+		
+		/*-- Constructor --*/
+		
+		private: Mode(int mode, int cc0, int cc1, int cc2);
+		
+		
+		/*-- Methods --*/
+		
+		/* 
+		 * (Package-private) Returns the mode indicator bits, which is an unsigned 4-bit value (range 0 to 15).
+		 */
+		public: int getModeBits() const;
+		
+		/* 
+		 * (Package-private) Returns the bit width of the segment character count field for this mode object at the given version number.
+		 */
+		public: int numCharCountBits(int ver) const;
+		
+	};
+	
+	
+	
+	/*---- Public static factory functions ----*/
+	
+	/* 
+	 * Returns a segment representing the given binary data encoded in byte mode.
+	 */
+	public: static QrSegment makeBytes(const std::vector<std::uint8_t> &data);
+	
+	
+	/* 
+	 * Returns a segment representing the given string of decimal digits encoded in numeric mode.
+	 */
+	public: static QrSegment makeNumeric(const char *digits);
+	
+	
+	/* 
+	 * Returns a segment representing the given text string encoded in alphanumeric mode.
+	 * The characters allowed are: 0 to 9, A to Z (uppercase only), space,
+	 * dollar, percent, asterisk, plus, hyphen, period, slash, colon.
+	 */
+	public: static QrSegment makeAlphanumeric(const char *text);
+	
+	
+	/* 
+	 * Returns a list of zero or more segments to represent the given text string.
+	 * The result may use various segment modes and switch modes to optimize the length of the bit stream.
+	 */
+	public: static std::vector<QrSegment> makeSegments(const char *text);
+	
+	
+	/* 
+	 * Returns a segment representing an Extended Channel Interpretation
+	 * (ECI) designator with the given assignment value.
+	 */
+	public: static QrSegment makeEci(long assignVal);
+	
+	
+	/*---- Public static helper functions ----*/
+	
+	/* 
+	 * Tests whether the given string can be encoded as a segment in alphanumeric mode.
+	 */
+	public: static bool isAlphanumeric(const char *text);
+	
+	
+	/* 
+	 * Tests whether the given string can be encoded as a segment in numeric mode.
+	 */
+	public: static bool isNumeric(const char *text);
+	
+	
+	
+	/*---- Instance fields ----*/
+	
+	/* The mode indicator for this segment. */
+	private: Mode mode;
+	
+	/* The length of this segment's unencoded data, measured in characters. Always zero or positive. */
+	private: int numChars;
+	
+	/* The data bits of this segment. */
+	private: std::vector<bool> data;
+	
+	
+	/*---- Constructors ----*/
+	
+	/* 
+	 * Creates a new QR Code data segment with the given parameters and data.
+	 */
+	public: QrSegment(Mode md, int numCh, const std::vector<bool> &dt);
+	
+	
+	/* 
+	 * Creates a new QR Code data segment with the given parameters and data.
+	 */
+	public: QrSegment(Mode md, int numCh, std::vector<bool> &&dt);
+	
+	
+	/*---- Methods ----*/
+	
+	public: Mode getMode() const;
+	
+	
+	public: int getNumChars() const;
+	
+	
+	public: const std::vector<bool> &getData() const;
+	
+	
+	// Package-private helper function.
+	public: static int getTotalBits(const std::vector<QrSegment> &segs, int version);
+	
+	
+	/*---- Private constant ----*/
+	
+	/* The set of all legal characters in alphanumeric mode, where each character value maps to the index in the string. */
+	private: static const char *ALPHANUMERIC_CHARSET;
+	
+};
+
+}
diff --git a/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/BitBuffer.java b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/BitBuffer.java
new file mode 100644
index 0000000..f43cc12
--- /dev/null
+++ b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/BitBuffer.java
@@ -0,0 +1,133 @@
+/* 
+ * QR Code generator library (Java)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+package io.nayuki.qrcodegen;
+
+import java.util.BitSet;
+import java.util.Objects;
+
+
+/**
+ * An appendable sequence of bits (0's and 1's).
+ */
+public final class BitBuffer implements Cloneable {
+	
+	/*---- Fields ----*/
+	
+	private BitSet data;
+	
+	private int bitLength;
+	
+	
+	
+	/*---- Constructor ----*/
+	
+	/**
+	 * Constructs an empty bit buffer (length 0).
+	 */
+	public BitBuffer() {
+		data = new BitSet();
+		bitLength = 0;
+	}
+	
+	
+	
+	/*---- Methods ----*/
+	
+	/**
+	 * Returns the length of this sequence, which is a non-negative value.
+	 * @return the length of this sequence
+	 */
+	public int bitLength() {
+		return bitLength;
+	}
+	
+	
+	/**
+	 * Returns the bit at the specified index, yielding 0 or 1.
+	 * @param index the index to get the bit at
+	 * @return the bit at the specified index
+	 * @throws IndexOutOfBoundsException if index &lt; 0 or index &ge; bitLength
+	 */
+	public int getBit(int index) {
+		if (index < 0 || index >= bitLength)
+			throw new IndexOutOfBoundsException();
+		return data.get(index) ? 1 : 0;
+	}
+	
+	
+	/**
+	 * Packs this buffer's bits into bytes in big endian,
+	 * padding with '0' bit values, and returns the new array.
+	 * @return this sequence as a new array of bytes (not {@code null})
+	 */
+	public byte[] getBytes() {
+		byte[] result = new byte[(bitLength + 7) / 8];
+		for (int i = 0; i < bitLength; i++)
+			result[i >>> 3] |= data.get(i) ? 1 << (7 - (i & 7)) : 0;
+		return result;
+	}
+	
+	
+	/**
+	 * Appends the specified number of low bits of the specified value
+	 * to this sequence. Requires 0 &le; val &lt; 2<sup>len</sup>.
+	 * @param val the value to append
+	 * @param len the number of low bits in the value to take
+	 */
+	public void appendBits(int val, int len) {
+		if (len < 0 || len > 31 || val >>> len != 0)
+			throw new IllegalArgumentException("Value out of range");
+		for (int i = len - 1; i >= 0; i--, bitLength++)  // Append bit by bit
+			data.set(bitLength, ((val >>> i) & 1) != 0);
+	}
+	
+	
+	/**
+	 * Appends the bit data of the specified segment to this bit buffer.
+	 * @param seg the segment whose data to append (not {@code null})
+	 * @throws NullPointerException if the segment is {@code null}
+	 */
+	public void appendData(QrSegment seg) {
+		Objects.requireNonNull(seg);
+		BitBuffer bb = seg.data;
+		for (int i = 0; i < bb.bitLength; i++, bitLength++)  // Append bit by bit
+			data.set(bitLength, bb.data.get(i));
+	}
+	
+	
+	/**
+	 * Returns a copy of this bit buffer object.
+	 * @return a copy of this bit buffer object
+	 */
+	public BitBuffer clone() {
+		try {
+			BitBuffer result = (BitBuffer)super.clone();
+			result.data = (BitSet)result.data.clone();
+			return result;
+		} catch (CloneNotSupportedException e) {
+			throw new AssertionError(e);
+		}
+	}
+	
+}
diff --git a/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrCode.java b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrCode.java
new file mode 100644
index 0000000..5f64ca2
--- /dev/null
+++ b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrCode.java
@@ -0,0 +1,849 @@
+/* 
+ * QR Code generator library (Java)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+package io.nayuki.qrcodegen;
+
+import java.awt.image.BufferedImage;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ * Represents an immutable square grid of black and white cells for a QR Code symbol, and
+ * provides static functions to create a QR Code from user-supplied textual or binary data.
+ * <p>This class covers the QR Code model 2 specification, supporting all versions (sizes)
+ * from 1 to 40, all 4 error correction levels, and only 3 character encoding modes.</p>
+ */
+public final class QrCode {
+	
+	/*---- Public static factory functions ----*/
+	
+	/**
+	 * Returns a QR Code symbol representing the specified Unicode text string at the specified error correction level.
+	 * As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer
+	 * Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible
+	 * QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the
+	 * ecl argument if it can be done without increasing the version.
+	 * @param text the text to be encoded, which can be any Unicode string
+	 * @param ecl the error correction level to use (will be boosted)
+	 * @return a QR Code representing the text
+	 * @throws NullPointerException if the text or error correction level is {@code null}
+	 * @throws IllegalArgumentException if the text fails to fit in the largest version QR Code, which means it is too long
+	 */
+	public static QrCode encodeText(String text, Ecc ecl) {
+		Objects.requireNonNull(text);
+		Objects.requireNonNull(ecl);
+		List<QrSegment> segs = QrSegment.makeSegments(text);
+		return encodeSegments(segs, ecl);
+	}
+	
+	
+	/**
+	 * Returns a QR Code symbol representing the specified binary data string at the specified error correction level.
+	 * This function always encodes using the binary segment mode, not any text mode. The maximum number of
+	 * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
+	 * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
+	 * @param data the binary data to encode
+	 * @param ecl the error correction level to use (will be boosted)
+	 * @return a QR Code representing the binary data
+	 * @throws NullPointerException if the data or error correction level is {@code null}
+	 * @throws IllegalArgumentException if the data fails to fit in the largest version QR Code, which means it is too long
+	 */
+	public static QrCode encodeBinary(byte[] data, Ecc ecl) {
+		Objects.requireNonNull(data);
+		Objects.requireNonNull(ecl);
+		QrSegment seg = QrSegment.makeBytes(data);
+		return encodeSegments(Arrays.asList(seg), ecl);
+	}
+	
+	
+	/**
+	 * Returns a QR Code symbol representing the specified data segments at the specified error correction
+	 * level or higher. The smallest possible QR Code version is automatically chosen for the output.
+	 * <p>This function allows the user to create a custom sequence of segments that switches
+	 * between modes (such as alphanumeric and binary) to encode text more efficiently.
+	 * This function is considered to be lower level than simply encoding text or binary data.</p>
+	 * @param segs the segments to encode
+	 * @param ecl the error correction level to use (will be boosted)
+	 * @return a QR Code representing the segments
+	 * @throws NullPointerException if the list of segments, a segment, or the error correction level is {@code null}
+	 * @throws IllegalArgumentException if the data is too long to fit in the largest version QR Code at the ECL
+	 */
+	public static QrCode encodeSegments(List<QrSegment> segs, Ecc ecl) {
+		return encodeSegments(segs, ecl, MIN_VERSION, MAX_VERSION, -1, true);
+	}
+	
+	
+	/**
+	 * Returns a QR Code symbol representing the specified data segments with the specified encoding parameters.
+	 * The smallest possible QR Code version within the specified range is automatically chosen for the output.
+	 * <p>This function allows the user to create a custom sequence of segments that switches
+	 * between modes (such as alphanumeric and binary) to encode text more efficiently.
+	 * This function is considered to be lower level than simply encoding text or binary data.</p>
+	 * @param segs the segments to encode
+	 * @param ecl the error correction level to use (may be boosted)
+	 * @param minVersion the minimum allowed version of the QR symbol (at least 1)
+	 * @param maxVersion the maximum allowed version of the QR symbol (at most 40)
+	 * @param mask the mask pattern to use, which is either -1 for automatic choice or from 0 to 7 for fixed choice
+	 * @param boostEcl increases the error correction level if it can be done without increasing the version number
+	 * @return a QR Code representing the segments
+	 * @throws NullPointerException if the list of segments, a segment, or the error correction level is {@code null}
+	 * @throws IllegalArgumentException if 1 &le; minVersion &le; maxVersion &le; 40 is violated, or if mask
+	 * &lt; &minus;1 or mask > 7, or if the data is too long to fit in a QR Code at maxVersion at the ECL
+	 */
+	public static QrCode encodeSegments(List<QrSegment> segs, Ecc ecl, int minVersion, int maxVersion, int mask, boolean boostEcl) {
+		Objects.requireNonNull(segs);
+		Objects.requireNonNull(ecl);
+		if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
+			throw new IllegalArgumentException("Invalid value");
+		
+		// Find the minimal version number to use
+		int version, dataUsedBits;
+		for (version = minVersion; ; version++) {
+			int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;  // Number of data bits available
+			dataUsedBits = QrSegment.getTotalBits(segs, version);
+			if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits)
+				break;  // This version number is found to be suitable
+			if (version >= maxVersion)  // All versions in the range could not fit the given data
+				throw new IllegalArgumentException("Data too long");
+		}
+		if (dataUsedBits == -1)
+			throw new AssertionError();
+		
+		// Increase the error correction level while the data still fits in the current version number
+		for (Ecc newEcl : Ecc.values()) {
+			if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8)
+				ecl = newEcl;
+		}
+		
+		// Create the data bit string by concatenating all segments
+		int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
+		BitBuffer bb = new BitBuffer();
+		for (QrSegment seg : segs) {
+			bb.appendBits(seg.mode.modeBits, 4);
+			bb.appendBits(seg.numChars, seg.mode.numCharCountBits(version));
+			bb.appendData(seg);
+		}
+		
+		// Add terminator and pad up to a byte if applicable
+		bb.appendBits(0, Math.min(4, dataCapacityBits - bb.bitLength()));
+		bb.appendBits(0, (8 - bb.bitLength() % 8) % 8);
+		
+		// Pad with alternate bytes until data capacity is reached
+		for (int padByte = 0xEC; bb.bitLength() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
+			bb.appendBits(padByte, 8);
+		if (bb.bitLength() % 8 != 0)
+			throw new AssertionError();
+		
+		// Create the QR Code symbol
+		return new QrCode(version, ecl, bb.getBytes(), mask);
+	}
+	
+	
+	
+	/*---- Public constants ----*/
+	
+	public static final int MIN_VERSION =  1;
+	public static final int MAX_VERSION = 40;
+	
+	
+	
+	/*---- Instance fields ----*/
+	
+	// Public immutable scalar parameters
+	
+	/** This QR Code symbol's version number, which is always between 1 and 40 (inclusive). */
+	public final int version;
+	
+	/** The width and height of this QR Code symbol, measured in modules.
+	 * Always equal to version &times; 4 + 17, in the range 21 to 177. */
+	public final int size;
+	
+	/** The error correction level used in this QR Code symbol. Never {@code null}. */
+	public final Ecc errorCorrectionLevel;
+	
+	/** The mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer).
+	 * Note that even if a constructor was called with automatic masking requested
+	 * (mask = -1), the resulting object will still have a mask value between 0 and 7. */
+	public final int mask;
+	
+	// Private grids of modules/pixels (conceptually immutable)
+	private boolean[][] modules;     // The modules of this QR Code symbol (false = white, true = black)
+	private boolean[][] isFunction;  // Indicates function modules that are not subjected to masking
+	
+	
+	
+	/*---- Constructors ----*/
+	
+	/**
+	 * Creates a new QR Code symbol with the specified version number, error correction level, binary data array, and mask number.
+	 * <p>This is a cumbersome low-level constructor that should not be invoked directly by the user.
+	 * To go one level up, see the {@link #encodeSegments(List,Ecc)} function.</p>
+	 * @param ver the version number to use, which must be in the range 1 to 40, inclusive
+	 * @param ecl the error correction level to use
+	 * @param dataCodewords the raw binary user data to encode
+	 * @param mask the mask pattern to use, which is either -1 for automatic choice or from 0 to 7 for fixed choice
+	 * @throws NullPointerException if the byte array or error correction level is {@code null}
+	 * @throws IllegalArgumentException if the version or mask value is out of range
+	 */
+	public QrCode(int ver, Ecc ecl, byte[] dataCodewords, int mask) {
+		// Check arguments
+		Objects.requireNonNull(ecl);
+		if (ver < MIN_VERSION || ver > MAX_VERSION || mask < -1 || mask > 7)
+			throw new IllegalArgumentException("Value out of range");
+		Objects.requireNonNull(dataCodewords);
+		
+		// Initialize fields
+		version = ver;
+		size = ver * 4 + 17;
+		errorCorrectionLevel = ecl;
+		modules = new boolean[size][size];  // Entirely white grid
+		isFunction = new boolean[size][size];
+		
+		// Draw function patterns, draw all codewords, do masking
+		drawFunctionPatterns();
+		byte[] allCodewords = appendErrorCorrection(dataCodewords);
+		drawCodewords(allCodewords);
+		this.mask = handleConstructorMasking(mask);
+	}
+	
+	
+	
+	/*---- Public instance methods ----*/
+	
+	/**
+	 * Returns the color of the module (pixel) at the specified coordinates, which is either
+	 * false for white or true for black. The top left corner has the coordinates (x=0, y=0).
+	 * If the specified coordinates are out of bounds, then false (white) is returned.
+	 * @param x the x coordinate, where 0 is the left edge and size&minus;1 is the right edge
+	 * @param y the y coordinate, where 0 is the top edge and size&minus;1 is the bottom edge
+	 * @return the module's color, which is either false (white) or true (black)
+	 */
+	public boolean getModule(int x, int y) {
+		return 0 <= x && x < size && 0 <= y && y < size && modules[y][x];
+	}
+	
+	
+	/**
+	 * Returns a new image object representing this QR Code, with the specified module scale and number
+	 * of border modules. For example, the arguments scale=10, border=4 means to pad the QR Code symbol
+	 * with 4 white border modules on all four edges, then use 10*10 pixels to represent each module.
+	 * The resulting image only contains the hex colors 000000 and FFFFFF.
+	 * @param scale the module scale factor, which must be positive
+	 * @param border the number of border modules to add, which must be non-negative
+	 * @return an image representing this QR Code, with padding and scaling
+	 * @throws IllegalArgumentException if the scale or border is out of range
+	 */
+	public BufferedImage toImage(int scale, int border) {
+		if (scale <= 0 || border < 0)
+			throw new IllegalArgumentException("Value out of range");
+		if (border > Integer.MAX_VALUE / 2 || size + border * 2L > Integer.MAX_VALUE / scale)
+			throw new IllegalArgumentException("Scale or border too large");
+		
+		BufferedImage result = new BufferedImage((size + border * 2) * scale, (size + border * 2) * scale, BufferedImage.TYPE_INT_RGB);
+		for (int y = 0; y < result.getHeight(); y++) {
+			for (int x = 0; x < result.getWidth(); x++) {
+				boolean val = getModule(x / scale - border, y / scale - border);
+				result.setRGB(x, y, val ? 0x000000 : 0xFFFFFF);
+			}
+		}
+		return result;
+	}
+	
+	
+	/**
+	 * Based on the specified number of border modules to add as padding, this returns a
+	 * string whose contents represents an SVG XML file that depicts this QR Code symbol.
+	 * Note that Unix newlines (\n) are always used, regardless of the platform.
+	 * @param border the number of border modules to add, which must be non-negative
+	 * @return a string representing this QR Code as an SVG document
+	 */
+	public String toSvgString(int border) {
+		if (border < 0)
+			throw new IllegalArgumentException("Border must be non-negative");
+		if (size + border * 2L > Integer.MAX_VALUE)
+			throw new IllegalArgumentException("Border too large");
+		
+		StringBuilder sb = new StringBuilder();
+		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+		sb.append("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
+		sb.append(String.format(
+			"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 %1$d %1$d\" stroke=\"none\">\n",
+			size + border * 2));
+		sb.append("\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n");
+		sb.append("\t<path d=\"");
+		boolean head = true;
+		for (int y = -border; y < size + border; y++) {
+			for (int x = -border; x < size + border; x++) {
+				if (getModule(x, y)) {
+					if (head)
+						head = false;
+					else
+						sb.append(" ");
+					sb.append(String.format("M%d,%dh1v1h-1z", x + border, y + border));
+				}
+			}
+		}
+		sb.append("\" fill=\"#000000\"/>\n");
+		sb.append("</svg>\n");
+		return sb.toString();
+	}
+	
+	
+	
+	/*---- Private helper methods for constructor: Drawing function modules ----*/
+	
+	private void drawFunctionPatterns() {
+		// Draw horizontal and vertical timing patterns
+		for (int i = 0; i < size; i++) {
+			setFunctionModule(6, i, i % 2 == 0);
+			setFunctionModule(i, 6, i % 2 == 0);
+		}
+		
+		// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
+		drawFinderPattern(3, 3);
+		drawFinderPattern(size - 4, 3);
+		drawFinderPattern(3, size - 4);
+		
+		// Draw numerous alignment patterns
+		int[] alignPatPos = getAlignmentPatternPositions(version);
+		int numAlign = alignPatPos.length;
+		for (int i = 0; i < numAlign; i++) {
+			for (int j = 0; j < numAlign; j++) {
+				if (i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0)
+					continue;  // Skip the three finder corners
+				else
+					drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);
+			}
+		}
+		
+		// Draw configuration data
+		drawFormatBits(0);  // Dummy mask value; overwritten later in the constructor
+		drawVersion();
+	}
+	
+	
+	// Draws two copies of the format bits (with its own error correction code)
+	// based on the given mask and this object's error correction level field.
+	private void drawFormatBits(int mask) {
+		// Calculate error correction code and pack bits
+		int data = errorCorrectionLevel.formatBits << 3 | mask;  // errCorrLvl is uint2, mask is uint3
+		int rem = data;
+		for (int i = 0; i < 10; i++)
+			rem = (rem << 1) ^ ((rem >>> 9) * 0x537);
+		data = data << 10 | rem;
+		data ^= 0x5412;  // uint15
+		if (data >>> 15 != 0)
+			throw new AssertionError();
+		
+		// Draw first copy
+		for (int i = 0; i <= 5; i++)
+			setFunctionModule(8, i, ((data >>> i) & 1) != 0);
+		setFunctionModule(8, 7, ((data >>> 6) & 1) != 0);
+		setFunctionModule(8, 8, ((data >>> 7) & 1) != 0);
+		setFunctionModule(7, 8, ((data >>> 8) & 1) != 0);
+		for (int i = 9; i < 15; i++)
+			setFunctionModule(14 - i, 8, ((data >>> i) & 1) != 0);
+		
+		// Draw second copy
+		for (int i = 0; i <= 7; i++)
+			setFunctionModule(size - 1 - i, 8, ((data >>> i) & 1) != 0);
+		for (int i = 8; i < 15; i++)
+			setFunctionModule(8, size - 15 + i, ((data >>> i) & 1) != 0);
+		setFunctionModule(8, size - 8, true);
+	}
+	
+	
+	// Draws two copies of the version bits (with its own error correction code),
+	// based on this object's version field (which only has an effect for 7 <= version <= 40).
+	private void drawVersion() {
+		if (version < 7)
+			return;
+		
+		// Calculate error correction code and pack bits
+		int rem = version;  // version is uint6, in the range [7, 40]
+		for (int i = 0; i < 12; i++)
+			rem = (rem << 1) ^ ((rem >>> 11) * 0x1F25);
+		int data = version << 12 | rem;  // uint18
+		if (data >>> 18 != 0)
+			throw new AssertionError();
+		
+		// Draw two copies
+		for (int i = 0; i < 18; i++) {
+			boolean bit = ((data >>> i) & 1) != 0;
+			int a = size - 11 + i % 3, b = i / 3;
+			setFunctionModule(a, b, bit);
+			setFunctionModule(b, a, bit);
+		}
+	}
+	
+	
+	// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y).
+	private void drawFinderPattern(int x, int y) {
+		for (int i = -4; i <= 4; i++) {
+			for (int j = -4; j <= 4; j++) {
+				int dist = Math.max(Math.abs(i), Math.abs(j));  // Chebyshev/infinity norm
+				int xx = x + j, yy = y + i;
+				if (0 <= xx && xx < size && 0 <= yy && yy < size)
+					setFunctionModule(xx, yy, dist != 2 && dist != 4);
+			}
+		}
+	}
+	
+	
+	// Draws a 5*5 alignment pattern, with the center module at (x, y).
+	private void drawAlignmentPattern(int x, int y) {
+		for (int i = -2; i <= 2; i++) {
+			for (int j = -2; j <= 2; j++)
+				setFunctionModule(x + j, y + i, Math.max(Math.abs(i), Math.abs(j)) != 1);
+		}
+	}
+	
+	
+	// Sets the color of a module and marks it as a function module.
+	// Only used by the constructor. Coordinates must be in range.
+	private void setFunctionModule(int x, int y, boolean isBlack) {
+		modules[y][x] = isBlack;
+		isFunction[y][x] = true;
+	}
+	
+	
+	/*---- Private helper methods for constructor: Codewords and masking ----*/
+	
+	// Returns a new byte string representing the given data with the appropriate error correction
+	// codewords appended to it, based on this object's version and error correction level.
+	private byte[] appendErrorCorrection(byte[] data) {
+		if (data.length != getNumDataCodewords(version, errorCorrectionLevel))
+			throw new IllegalArgumentException();
+		
+		// Calculate parameter numbers
+		int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[errorCorrectionLevel.ordinal()][version];
+		int blockEccLen = ECC_CODEWORDS_PER_BLOCK[errorCorrectionLevel.ordinal()][version];
+		int rawCodewords = getNumRawDataModules(version) / 8;
+		int numShortBlocks = numBlocks - rawCodewords % numBlocks;
+		int shortBlockLen = rawCodewords / numBlocks;
+		
+		// Split data into blocks and append ECC to each block
+		byte[][] blocks = new byte[numBlocks][];
+		ReedSolomonGenerator rs = new ReedSolomonGenerator(blockEccLen);
+		for (int i = 0, k = 0; i < numBlocks; i++) {
+			byte[] dat = Arrays.copyOfRange(data, k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
+			byte[] block = Arrays.copyOf(dat, shortBlockLen + 1);
+			k += dat.length;
+			byte[] ecc = rs.getRemainder(dat);
+			System.arraycopy(ecc, 0, block, block.length - blockEccLen, ecc.length);
+			blocks[i] = block;
+		}
+		
+		// Interleave (not concatenate) the bytes from every block into a single sequence
+		byte[] result = new byte[rawCodewords];
+		for (int i = 0, k = 0; i < blocks[0].length; i++) {
+			for (int j = 0; j < blocks.length; j++) {
+				// Skip the padding byte in short blocks
+				if (i != shortBlockLen - blockEccLen || j >= numShortBlocks) {
+					result[k] = blocks[j][i];
+					k++;
+				}
+			}
+		}
+		return result;
+	}
+	
+	
+	// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
+	// data area of this QR Code symbol. Function modules need to be marked off before this is called.
+	private void drawCodewords(byte[] data) {
+		Objects.requireNonNull(data);
+		if (data.length != getNumRawDataModules(version) / 8)
+			throw new IllegalArgumentException();
+		
+		int i = 0;  // Bit index into the data
+		// Do the funny zigzag scan
+		for (int right = size - 1; right >= 1; right -= 2) {  // Index of right column in each column pair
+			if (right == 6)
+				right = 5;
+			for (int vert = 0; vert < size; vert++) {  // Vertical counter
+				for (int j = 0; j < 2; j++) {
+					int x = right - j;  // Actual x coordinate
+					boolean upward = ((right + 1) & 2) == 0;
+					int y = upward ? size - 1 - vert : vert;  // Actual y coordinate
+					if (!isFunction[y][x] && i < data.length * 8) {
+						modules[y][x] = ((data[i >>> 3] >>> (7 - (i & 7))) & 1) != 0;
+						i++;
+					}
+					// If there are any remainder bits (0 to 7), they are already
+					// set to 0/false/white when the grid of modules was initialized
+				}
+			}
+		}
+		if (i != data.length * 8)
+			throw new AssertionError();
+	}
+	
+	
+	// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
+	// properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
+	// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
+	// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
+	private void applyMask(int mask) {
+		if (mask < 0 || mask > 7)
+			throw new IllegalArgumentException("Mask value out of range");
+		for (int y = 0; y < size; y++) {
+			for (int x = 0; x < size; x++) {
+				boolean invert;
+				switch (mask) {
+					case 0:  invert = (x + y) % 2 == 0;                    break;
+					case 1:  invert = y % 2 == 0;                          break;
+					case 2:  invert = x % 3 == 0;                          break;
+					case 3:  invert = (x + y) % 3 == 0;                    break;
+					case 4:  invert = (x / 3 + y / 2) % 2 == 0;            break;
+					case 5:  invert = x * y % 2 + x * y % 3 == 0;          break;
+					case 6:  invert = (x * y % 2 + x * y % 3) % 2 == 0;    break;
+					case 7:  invert = ((x + y) % 2 + x * y % 3) % 2 == 0;  break;
+					default:  throw new AssertionError();
+				}
+				modules[y][x] ^= invert & !isFunction[y][x];
+			}
+		}
+	}
+	
+	
+	// A messy helper function for the constructors. This QR Code must be in an unmasked state when this
+	// method is called. The given argument is the requested mask, which is -1 for auto or 0 to 7 for fixed.
+	// This method applies and returns the actual mask chosen, from 0 to 7.
+	private int handleConstructorMasking(int mask) {
+		if (mask == -1) {  // Automatically choose best mask
+			int minPenalty = Integer.MAX_VALUE;
+			for (int i = 0; i < 8; i++) {
+				drawFormatBits(i);
+				applyMask(i);
+				int penalty = getPenaltyScore();
+				if (penalty < minPenalty) {
+					mask = i;
+					minPenalty = penalty;
+				}
+				applyMask(i);  // Undoes the mask due to XOR
+			}
+		}
+		if (mask < 0 || mask > 7)
+			throw new AssertionError();
+		drawFormatBits(mask);  // Overwrite old format bits
+		applyMask(mask);  // Apply the final choice of mask
+		return mask;  // The caller shall assign this value to the final-declared field
+	}
+	
+	
+	// Calculates and returns the penalty score based on state of this QR Code's current modules.
+	// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
+	private int getPenaltyScore() {
+		int result = 0;
+		
+		// Adjacent modules in row having same color
+		for (int y = 0; y < size; y++) {
+			boolean colorX = false;
+			for (int x = 0, runX = 0; x < size; x++) {
+				if (x == 0 || modules[y][x] != colorX) {
+					colorX = modules[y][x];
+					runX = 1;
+				} else {
+					runX++;
+					if (runX == 5)
+						result += PENALTY_N1;
+					else if (runX > 5)
+						result++;
+				}
+			}
+		}
+		// Adjacent modules in column having same color
+		for (int x = 0; x < size; x++) {
+			boolean colorY = false;
+			for (int y = 0, runY = 0; y < size; y++) {
+				if (y == 0 || modules[y][x] != colorY) {
+					colorY = modules[y][x];
+					runY = 1;
+				} else {
+					runY++;
+					if (runY == 5)
+						result += PENALTY_N1;
+					else if (runY > 5)
+						result++;
+				}
+			}
+		}
+		
+		// 2*2 blocks of modules having same color
+		for (int y = 0; y < size - 1; y++) {
+			for (int x = 0; x < size - 1; x++) {
+				boolean color = modules[y][x];
+				if (  color == modules[y][x + 1] &&
+				      color == modules[y + 1][x] &&
+				      color == modules[y + 1][x + 1])
+					result += PENALTY_N2;
+			}
+		}
+		
+		// Finder-like pattern in rows
+		for (int y = 0; y < size; y++) {
+			for (int x = 0, bits = 0; x < size; x++) {
+				bits = ((bits << 1) & 0x7FF) | (modules[y][x] ? 1 : 0);
+				if (x >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
+					result += PENALTY_N3;
+			}
+		}
+		// Finder-like pattern in columns
+		for (int x = 0; x < size; x++) {
+			for (int y = 0, bits = 0; y < size; y++) {
+				bits = ((bits << 1) & 0x7FF) | (modules[y][x] ? 1 : 0);
+				if (y >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
+					result += PENALTY_N3;
+			}
+		}
+		
+		// Balance of black and white modules
+		int black = 0;
+		for (boolean[] row : modules) {
+			for (boolean color : row) {
+				if (color)
+					black++;
+			}
+		}
+		int total = size * size;
+		// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
+		for (int k = 0; black*20 < (9-k)*total || black*20 > (11+k)*total; k++)
+			result += PENALTY_N4;
+		return result;
+	}
+	
+	
+	
+	/*---- Private static helper functions ----*/
+	
+	// Returns a set of positions of the alignment patterns in ascending order. These positions are
+	// used on both the x and y axes. Each value in the resulting array is in the range [0, 177).
+	// This stateless pure function could be implemented as table of 40 variable-length lists of unsigned bytes.
+	private static int[] getAlignmentPatternPositions(int ver) {
+		if (ver < MIN_VERSION || ver > MAX_VERSION)
+			throw new IllegalArgumentException("Version number out of range");
+		else if (ver == 1)
+			return new int[]{};
+		else {
+			int numAlign = ver / 7 + 2;
+			int step;
+			if (ver != 32) {
+				// ceil((size - 13) / (2*numAlign - 2)) * 2
+				step = (ver * 4 + numAlign * 2 + 1) / (2 * numAlign - 2) * 2;
+			} else  // C-C-C-Combo breaker!
+				step = 26;
+			
+			int[] result = new int[numAlign];
+			result[0] = 6;
+			for (int i = result.length - 1, pos = ver * 4 + 10; i >= 1; i--, pos -= step)
+				result[i] = pos;
+			return result;
+		}
+	}
+	
+	
+	// Returns the number of data bits that can be stored in a QR Code of the given version number, after
+	// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
+	// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
+	private static int getNumRawDataModules(int ver) {
+		if (ver < MIN_VERSION || ver > MAX_VERSION)
+			throw new IllegalArgumentException("Version number out of range");
+		
+		int size = ver * 4 + 17;
+		int result = size * size;   // Number of modules in the whole QR symbol square
+		result -= 64 * 3;           // Subtract the three finders with separators
+		result -= 15 * 2 + 1;       // Subtract the format information and black module
+		result -= (size - 16) * 2;  // Subtract the timing patterns
+		// The five lines above are equivalent to: int result = (16 * ver + 128) * ver + 64;
+		if (ver >= 2) {
+			int numAlign = ver / 7 + 2;
+			result -= (numAlign - 1) * (numAlign - 1) * 25;  // Subtract alignment patterns not overlapping with timing patterns
+			result -= (numAlign - 2) * 2 * 20;  // Subtract alignment patterns that overlap with timing patterns
+			// The two lines above are equivalent to: result -= (25 * numAlign - 10) * numAlign - 55;
+			if (ver >= 7)
+				result -= 18 * 2;  // Subtract version information
+		}
+		return result;
+	}
+	
+	
+	// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
+	// QR Code of the given version number and error correction level, with remainder bits discarded.
+	// This stateless pure function could be implemented as a (40*4)-cell lookup table.
+	static int getNumDataCodewords(int ver, Ecc ecl) {
+		if (ver < MIN_VERSION || ver > MAX_VERSION)
+			throw new IllegalArgumentException("Version number out of range");
+		return getNumRawDataModules(ver) / 8
+			- ECC_CODEWORDS_PER_BLOCK[ecl.ordinal()][ver]
+			* NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal()][ver];
+	}
+	
+	
+	/*---- Private tables of constants ----*/
+	
+	// For use in getPenaltyScore(), when evaluating which mask is best.
+	private static final int PENALTY_N1 = 3;
+	private static final int PENALTY_N2 = 3;
+	private static final int PENALTY_N3 = 40;
+	private static final int PENALTY_N4 = 10;
+	
+	
+	private static final byte[][] ECC_CODEWORDS_PER_BLOCK = {
+		// Version: (note that index 0 is for padding, and is set to an illegal value)
+		//0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+		{-1,  7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},  // Low
+		{-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28},  // Medium
+		{-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},  // Quartile
+		{-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},  // High
+	};
+	
+	private static final byte[][] NUM_ERROR_CORRECTION_BLOCKS = {
+		// Version: (note that index 0 is for padding, and is set to an illegal value)
+		//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+		{-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25},  // Low
+		{-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49},  // Medium
+		{-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68},  // Quartile
+		{-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81},  // High
+	};
+	
+	
+	
+	/*---- Public helper enumeration ----*/
+	
+	/**
+	 * Represents the error correction level used in a QR Code symbol.
+	 */
+	public enum Ecc {
+		// These enum constants must be declared in ascending order of error protection,
+		// for the sake of the implicit ordinal() method and values() function.
+		LOW(1), MEDIUM(0), QUARTILE(3), HIGH(2);
+		
+		// In the range 0 to 3 (unsigned 2-bit integer).
+		final int formatBits;
+		
+		// Constructor.
+		private Ecc(int fb) {
+			formatBits = fb;
+		}
+	}
+	
+	
+	
+	/*---- Private helper class ----*/
+	
+	/**
+	 * Computes the Reed-Solomon error correction codewords for a sequence of data codewords
+	 * at a given degree. Objects are immutable, and the state only depends on the degree.
+	 * This class exists because each data block in a QR Code shares the same the divisor polynomial.
+	 */
+	private static final class ReedSolomonGenerator {
+		
+		/*-- Immutable field --*/
+		
+		// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which
+		// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
+		private final byte[] coefficients;
+		
+		
+		/*-- Constructor --*/
+		
+		/**
+		 * Creates a Reed-Solomon ECC generator for the specified degree. This could be implemented
+		 * as a lookup table over all possible parameter values, instead of as an algorithm.
+		 * @param degree the divisor polynomial degree, which must be between 1 and 255
+		 * @throws IllegalArgumentException if degree &lt; 1 or degree > 255
+		 */
+		public ReedSolomonGenerator(int degree) {
+			if (degree < 1 || degree > 255)
+				throw new IllegalArgumentException("Degree out of range");
+			
+			// Start with the monomial x^0
+			coefficients = new byte[degree];
+			coefficients[degree - 1] = 1;
+			
+			// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
+			// drop the highest term, and store the rest of the coefficients in order of descending powers.
+			// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
+			int root = 1;
+			for (int i = 0; i < degree; i++) {
+				// Multiply the current product by (x - r^i)
+				for (int j = 0; j < coefficients.length; j++) {
+					coefficients[j] = (byte)multiply(coefficients[j] & 0xFF, root);
+					if (j + 1 < coefficients.length)
+						coefficients[j] ^= coefficients[j + 1];
+				}
+				root = multiply(root, 0x02);
+			}
+		}
+		
+		
+		/*-- Method --*/
+		
+		/**
+		 * Computes and returns the Reed-Solomon error correction codewords for the specified
+		 * sequence of data codewords. The returned object is always a new byte array.
+		 * This method does not alter this object's state (because it is immutable).
+		 * @param data the sequence of data codewords
+		 * @return the Reed-Solomon error correction codewords
+		 * @throws NullPointerException if the data is {@code null}
+		 */
+		public byte[] getRemainder(byte[] data) {
+			Objects.requireNonNull(data);
+			
+			// Compute the remainder by performing polynomial division
+			byte[] result = new byte[coefficients.length];
+			for (byte b : data) {
+				int factor = (b ^ result[0]) & 0xFF;
+				System.arraycopy(result, 1, result, 0, result.length - 1);
+				result[result.length - 1] = 0;
+				for (int i = 0; i < result.length; i++)
+					result[i] ^= multiply(coefficients[i] & 0xFF, factor);
+			}
+			return result;
+		}
+		
+		
+		/*-- Static function --*/
+		
+		// Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
+		// are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
+		private static int multiply(int x, int y) {
+			if (x >>> 8 != 0 || y >>> 8 != 0)
+				throw new IllegalArgumentException("Byte out of range");
+			// Russian peasant multiplication
+			int z = 0;
+			for (int i = 7; i >= 0; i--) {
+				z = (z << 1) ^ ((z >>> 7) * 0x11D);
+				z ^= ((y >>> i) & 1) * x;
+			}
+			if (z >>> 8 != 0)
+				throw new AssertionError();
+			return z;
+		}
+		
+	}
+	
+}
diff --git a/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrCodeGeneratorDemo.java b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrCodeGeneratorDemo.java
new file mode 100644
index 0000000..b05c2b2
--- /dev/null
+++ b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrCodeGeneratorDemo.java
@@ -0,0 +1,190 @@
+/* 
+ * QR Code generator demo (Java)
+ * 
+ * Run this command-line program with no arguments. The program creates/overwrites a bunch of
+ * PNG and SVG files in the current working directory to demonstrate the creation of QR Codes.
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+package io.nayuki.qrcodegen;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+import javax.imageio.ImageIO;
+
+
+public final class QrCodeGeneratorDemo {
+	
+	// The main application program.
+	public static void main(String[] args) throws IOException {
+		doBasicDemo();
+		doVarietyDemo();
+		doSegmentDemo();
+		doMaskDemo();
+	}
+	
+	
+	
+	/*---- Demo suite ----*/
+	
+	// Creates a single QR Code, then writes it to a PNG file and an SVG file.
+	private static void doBasicDemo() throws IOException {
+		String text = "Hello, world!";          // User-supplied Unicode text
+		QrCode.Ecc errCorLvl = QrCode.Ecc.LOW;  // Error correction level
+		
+		QrCode qr = QrCode.encodeText(text, errCorLvl);  // Make the QR Code symbol
+		
+		BufferedImage img = qr.toImage(10, 4);          // Convert to bitmap image
+		File imgFile = new File("hello-world-QR.png");  // File path for output
+		ImageIO.write(img, "png", imgFile);             // Write image to file
+		
+		String svg = qr.toSvgString(4);  // Convert to SVG XML code
+		try (Writer out = new OutputStreamWriter(
+				new FileOutputStream("hello-world-QR.svg"),
+				StandardCharsets.UTF_8)) {
+			out.write(svg);  // Create/overwrite file and write SVG data
+		}
+	}
+	
+	
+	// Creates a variety of QR Codes that exercise different features of the library, and writes each one to file.
+	private static void doVarietyDemo() throws IOException {
+		QrCode qr;
+		
+		// Numeric mode encoding (3.33 bits per digit)
+		qr = QrCode.encodeText("314159265358979323846264338327950288419716939937510", QrCode.Ecc.MEDIUM);
+		writePng(qr.toImage(13, 1), "pi-digits-QR.png");
+		
+		// Alphanumeric mode encoding (5.5 bits per character)
+		qr = QrCode.encodeText("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", QrCode.Ecc.HIGH);
+		writePng(qr.toImage(10, 2), "alphanumeric-QR.png");
+		
+		// Unicode text as UTF-8
+		qr = QrCode.encodeText("こんにちwa、世界！ αβγδ", QrCode.Ecc.QUARTILE);
+		writePng(qr.toImage(10, 3), "unicode-QR.png");
+		
+		// Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
+		qr = QrCode.encodeText(
+			"Alice was beginning to get very tired of sitting by her sister on the bank, "
+			+ "and of having nothing to do: once or twice she had peeped into the book her sister was reading, "
+			+ "but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice "
+			+ "'without pictures or conversations?' So she was considering in her own mind (as well as she could, "
+			+ "for the hot day made her feel very sleepy and stupid), whether the pleasure of making a "
+			+ "daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly "
+			+ "a White Rabbit with pink eyes ran close by her.", QrCode.Ecc.HIGH);
+		writePng(qr.toImage(6, 10), "alice-wonderland-QR.png");
+	}
+	
+	
+	// Creates QR Codes with manually specified segments for better compactness.
+	private static void doSegmentDemo() throws IOException {
+		QrCode qr;
+		List<QrSegment> segs;
+		
+		// Illustration "silver"
+		String silver0 = "THE SQUARE ROOT OF 2 IS 1.";
+		String silver1 = "41421356237309504880168872420969807856967187537694807317667973799";
+		qr = QrCode.encodeText(silver0 + silver1, QrCode.Ecc.LOW);
+		writePng(qr.toImage(10, 3), "sqrt2-monolithic-QR.png");
+		
+		segs = Arrays.asList(
+			QrSegment.makeAlphanumeric(silver0),
+			QrSegment.makeNumeric(silver1));
+		qr = QrCode.encodeSegments(segs, QrCode.Ecc.LOW);
+		writePng(qr.toImage(10, 3), "sqrt2-segmented-QR.png");
+		
+		// Illustration "golden"
+		String golden0 = "Golden ratio φ = 1.";
+		String golden1 = "6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374";
+		String golden2 = "......";
+		qr = QrCode.encodeText(golden0 + golden1 + golden2, QrCode.Ecc.LOW);
+		writePng(qr.toImage(8, 5), "phi-monolithic-QR.png");
+		
+		segs = Arrays.asList(
+			QrSegment.makeBytes(golden0.getBytes(StandardCharsets.UTF_8)),
+			QrSegment.makeNumeric(golden1),
+			QrSegment.makeAlphanumeric(golden2));
+		qr = QrCode.encodeSegments(segs, QrCode.Ecc.LOW);
+		writePng(qr.toImage(8, 5), "phi-segmented-QR.png");
+		
+		// Illustration "Madoka": kanji, kana, Greek, Cyrillic, full-width Latin characters
+		String madoka = "「魔法少女まどか☆マギカ」って、　ИАИ　ｄｅｓｕ　κα？";
+		qr = QrCode.encodeText(madoka, QrCode.Ecc.LOW);
+		writePng(qr.toImage(9, 4), "madoka-utf8-QR.png");
+		
+		int[] kanjiChars = {  // Kanji mode encoding (13 bits per character)
+			0x0035, 0x1002, 0x0FC0, 0x0AED, 0x0AD7,
+			0x015C, 0x0147, 0x0129, 0x0059, 0x01BD,
+			0x018D, 0x018A, 0x0036, 0x0141, 0x0144,
+			0x0001, 0x0000, 0x0249, 0x0240, 0x0249,
+			0x0000, 0x0104, 0x0105, 0x0113, 0x0115,
+			0x0000, 0x0208, 0x01FF, 0x0008,
+		};
+		BitBuffer bb = new BitBuffer();
+		for (int c : kanjiChars)
+			bb.appendBits(c, 13);
+		segs = Arrays.asList(new QrSegment(QrSegment.Mode.KANJI, kanjiChars.length, bb));
+		qr = QrCode.encodeSegments(segs, QrCode.Ecc.LOW);
+		writePng(qr.toImage(9, 4), "madoka-kanji-QR.png");
+	}
+	
+	
+	// Creates QR Codes with the same size and contents but different mask patterns.
+	private static void doMaskDemo() throws IOException {
+		QrCode qr;
+		List<QrSegment> segs;
+		
+		// Project Nayuki URL
+		segs = QrSegment.makeSegments("https://www.nayuki.io/");
+		qr = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, QrCode.MIN_VERSION, QrCode.MAX_VERSION, -1, true);  // Automatic mask
+		writePng(qr.toImage(8, 6), "project-nayuki-automask-QR.png");
+		qr = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 3, true);  // Force mask 3
+		writePng(qr.toImage(8, 6), "project-nayuki-mask3-QR.png");
+		
+		// Chinese text as UTF-8
+		segs = QrSegment.makeSegments("維基百科（Wikipedia，聆聽i/ˌwɪkᵻˈpiːdi.ə/）是一個自由內容、公開編輯且多語言的網路百科全書協作計畫");
+		qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 0, true);  // Force mask 0
+		writePng(qr.toImage(10, 3), "unicode-mask0-QR.png");
+		qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 1, true);  // Force mask 1
+		writePng(qr.toImage(10, 3), "unicode-mask1-QR.png");
+		qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 5, true);  // Force mask 5
+		writePng(qr.toImage(10, 3), "unicode-mask5-QR.png");
+		qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 7, true);  // Force mask 7
+		writePng(qr.toImage(10, 3), "unicode-mask7-QR.png");
+	}
+	
+	
+	
+	/*---- Utilities ----*/
+	
+	// Helper function to reduce code duplication.
+	private static void writePng(BufferedImage img, String filepath) throws IOException {
+		ImageIO.write(img, "png", new File(filepath));
+	}
+	
+}
diff --git a/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrCodeGeneratorWorker.java b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrCodeGeneratorWorker.java
new file mode 100644
index 0000000..e9d7ecc
--- /dev/null
+++ b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrCodeGeneratorWorker.java
@@ -0,0 +1,103 @@
+/* 
+ * QR Code generator test worker (Java)
+ * 
+ * This program reads data and encoding parameters from standard input and writes
+ * QR Code bitmaps to standard output. The I/O format is one integer per line.
+ * Run with no command line arguments. The program is intended for automated
+ * batch testing of end-to-end functionality of this QR Code generator library.
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+package io.nayuki.qrcodegen;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
+
+public final class QrCodeGeneratorWorker {
+	
+	public static void main(String[] args) {
+		// Set up input stream and start loop
+		try (Scanner input = new Scanner(System.in, "US-ASCII")) {
+			input.useDelimiter("\r\n|\n|\r");
+			while (processCase(input));
+		}
+	}
+	
+	
+	private static boolean processCase(Scanner input) {
+		// Read data length or exit
+		int length = input.nextInt();
+		if (length == -1)
+			return false;
+		if (length > Short.MAX_VALUE)
+			throw new RuntimeException();
+		
+		// Read data bytes
+		boolean isAscii = true;
+		byte[] data = new byte[length];
+		for (int i = 0; i < data.length; i++) {
+			int b = input.nextInt();
+			if (b < 0 || b > 255)
+				throw new RuntimeException();
+			data[i] = (byte)b;
+			isAscii &= b < 128;
+		}
+		
+		// Read encoding parameters
+		int errCorLvl  = input.nextInt();
+		int minVersion = input.nextInt();
+		int maxVersion = input.nextInt();
+		int mask       = input.nextInt();
+		int boostEcl   = input.nextInt();
+		if (!(0 <= errCorLvl && errCorLvl <= 3) || !(-1 <= mask && mask <= 7) || (boostEcl >>> 1) != 0
+				|| !(QrCode.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= QrCode.MAX_VERSION))
+			throw new RuntimeException();
+		
+		// Make segments for encoding
+		List<QrSegment> segs;
+		if (isAscii)
+			segs = QrSegment.makeSegments(new String(data, StandardCharsets.US_ASCII));
+		else
+			segs = Arrays.asList(QrSegment.makeBytes(data));
+		
+		
+		try {  // Try to make QR Code symbol
+			QrCode qr = QrCode.encodeSegments(segs, QrCode.Ecc.values()[errCorLvl], minVersion, maxVersion, mask, boostEcl != 0);
+			// Print grid of modules
+			System.out.println(qr.version);
+			for (int y = 0; y < qr.size; y++) {
+				for (int x = 0; x < qr.size; x++)
+					System.out.println(qr.getModule(x, y) ? 1 : 0);
+			}
+			
+		} catch (IllegalArgumentException e) {
+			if (!e.getMessage().equals("Data too long"))
+				throw e;
+			System.out.println(-1);
+		}
+		System.out.flush();
+		return true;
+	}
+	
+}
diff --git a/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrSegment.java b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrSegment.java
new file mode 100644
index 0000000..a4e8a2a
--- /dev/null
+++ b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrSegment.java
@@ -0,0 +1,284 @@
+/* 
+ * QR Code generator library (Java)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+package io.nayuki.qrcodegen;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+
+/**
+ * Represents a character string to be encoded in a QR Code symbol. Each segment has
+ * a mode, and a sequence of characters that is already encoded as a sequence of bits.
+ * Instances of this class are immutable.
+ * <p>This segment class imposes no length restrictions, but QR Codes have restrictions.
+ * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
+ * Any segment longer than this is meaningless for the purpose of generating QR Codes.</p>
+ */
+public final class QrSegment {
+	
+	/*---- Static factory functions ----*/
+	
+	/**
+	 * Returns a segment representing the specified binary data encoded in byte mode.
+	 * @param data the binary data
+	 * @return a segment containing the data
+	 * @throws NullPointerException if the array is {@code null}
+	 */
+	public static QrSegment makeBytes(byte[] data) {
+		Objects.requireNonNull(data);
+		BitBuffer bb = new BitBuffer();
+		for (byte b : data)
+			bb.appendBits(b & 0xFF, 8);
+		return new QrSegment(Mode.BYTE, data.length, bb);
+	}
+	
+	
+	/**
+	 * Returns a segment representing the specified string of decimal digits encoded in numeric mode.
+	 * @param digits a string consisting of digits from 0 to 9
+	 * @return a segment containing the data
+	 * @throws NullPointerException if the string is {@code null}
+	 * @throws IllegalArgumentException if the string contains non-digit characters
+	 */
+	public static QrSegment makeNumeric(String digits) {
+		Objects.requireNonNull(digits);
+		if (!NUMERIC_REGEX.matcher(digits).matches())
+			throw new IllegalArgumentException("String contains non-numeric characters");
+		
+		BitBuffer bb = new BitBuffer();
+		int i;
+		for (i = 0; i + 3 <= digits.length(); i += 3)  // Process groups of 3
+			bb.appendBits(Integer.parseInt(digits.substring(i, i + 3)), 10);
+		int rem = digits.length() - i;
+		if (rem > 0)  // 1 or 2 digits remaining
+			bb.appendBits(Integer.parseInt(digits.substring(i)), rem * 3 + 1);
+		return new QrSegment(Mode.NUMERIC, digits.length(), bb);
+	}
+	
+	
+	/**
+	 * Returns a segment representing the specified text string encoded in alphanumeric mode.
+	 * The characters allowed are: 0 to 9, A to Z (uppercase only), space,
+	 * dollar, percent, asterisk, plus, hyphen, period, slash, colon.
+	 * @param text a string of text, with only certain characters allowed
+	 * @return a segment containing the data
+	 * @throws NullPointerException if the string is {@code null}
+	 * @throws IllegalArgumentException if the string contains non-encodable characters
+	 */
+	public static QrSegment makeAlphanumeric(String text) {
+		Objects.requireNonNull(text);
+		if (!ALPHANUMERIC_REGEX.matcher(text).matches())
+			throw new IllegalArgumentException("String contains unencodable characters in alphanumeric mode");
+		
+		BitBuffer bb = new BitBuffer();
+		int i;
+		for (i = 0; i + 2 <= text.length(); i += 2) {  // Process groups of 2
+			int temp = ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;
+			temp += ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));
+			bb.appendBits(temp, 11);
+		}
+		if (i < text.length())  // 1 character remaining
+			bb.appendBits(ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6);
+		return new QrSegment(Mode.ALPHANUMERIC, text.length(), bb);
+	}
+	
+	
+	/**
+	 * Returns a new mutable list of zero or more segments to represent the specified Unicode text string.
+	 * The result may use various segment modes and switch modes to optimize the length of the bit stream.
+	 * @param text the text to be encoded, which can be any Unicode string
+	 * @return a list of segments containing the text
+	 * @throws NullPointerException if the text is {@code null}
+	 */
+	public static List<QrSegment> makeSegments(String text) {
+		Objects.requireNonNull(text);
+		
+		// Select the most efficient segment encoding automatically
+		List<QrSegment> result = new ArrayList<>();
+		if (text.equals(""));  // Leave result empty
+		else if (NUMERIC_REGEX.matcher(text).matches())
+			result.add(makeNumeric(text));
+		else if (ALPHANUMERIC_REGEX.matcher(text).matches())
+			result.add(makeAlphanumeric(text));
+		else
+			result.add(makeBytes(text.getBytes(StandardCharsets.UTF_8)));
+		return result;
+	}
+	
+	
+	/**
+	 * Returns a segment representing an Extended Channel Interpretation
+	 * (ECI) designator with the specified assignment value.
+	 * @param assignVal the ECI assignment number (see the AIM ECI specification)
+	 * @return a segment containing the data
+	 * @throws IllegalArgumentException if the value is outside the range [0, 10<sup>6</sup>)
+	 */
+	public static QrSegment makeEci(int assignVal) {
+		BitBuffer bb = new BitBuffer();
+		if (0 <= assignVal && assignVal < (1 << 7))
+			bb.appendBits(assignVal, 8);
+		else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) {
+			bb.appendBits(2, 2);
+			bb.appendBits(assignVal, 14);
+		} else if ((1 << 14) <= assignVal && assignVal < 1000000) {
+			bb.appendBits(6, 3);
+			bb.appendBits(assignVal, 21);
+		} else
+			throw new IllegalArgumentException("ECI assignment value out of range");
+		return new QrSegment(Mode.ECI, 0, bb);
+	}
+	
+	
+	
+	/*---- Instance fields ----*/
+	
+	/** The mode indicator for this segment. Never {@code null}. */
+	public final Mode mode;
+	
+	/** The length of this segment's unencoded data, measured in characters. Always zero or positive. */
+	public final int numChars;
+	
+	/** The data bits of this segment. Accessed through {@link getBits()}. Not {@code null}. */
+	final BitBuffer data;
+	
+	
+	/*---- Constructor ----*/
+	
+	/**
+	 * Creates a new QR Code data segment with the specified parameters and data.
+	 * @param md the mode, which is not {@code null}
+	 * @param numCh the data length in characters, which is non-negative
+	 * @param data the data bits of this segment, which is not {@code null}
+	 * @throws NullPointerException if the mode or bit buffer is {@code null}
+	 * @throws IllegalArgumentException if the character count is negative
+	 */
+	public QrSegment(Mode md, int numCh, BitBuffer data) {
+		Objects.requireNonNull(md);
+		Objects.requireNonNull(data);
+		if (numCh < 0)
+			throw new IllegalArgumentException("Invalid value");
+		mode = md;
+		numChars = numCh;
+		this.data = data.clone();  // Make defensive copy
+	}
+	
+	
+	/*---- Methods ----*/
+	
+	/**
+	 * Returns the data bits of this segment.
+	 * @return the data bits of this segment (not {@code null})
+	 */
+	public BitBuffer getBits() {
+		return data.clone();  // Make defensive copy
+	}
+	
+	
+	// Package-private helper function.
+	static int getTotalBits(List<QrSegment> segs, int version) {
+		Objects.requireNonNull(segs);
+		if (version < 1 || version > 40)
+			throw new IllegalArgumentException("Version number out of range");
+		
+		long result = 0;
+		for (QrSegment seg : segs) {
+			Objects.requireNonNull(seg);
+			int ccbits = seg.mode.numCharCountBits(version);
+			// Fail if segment length value doesn't fit in the length field's bit-width
+			if (seg.numChars >= (1 << ccbits))
+				return -1;
+			result += 4L + ccbits + seg.data.bitLength();
+			if (result > Integer.MAX_VALUE)
+				return -1;
+		}
+		return (int)result;
+	}
+	
+	
+	/*---- Constants ----*/
+	
+	/** Can test whether a string is encodable in numeric mode (such as by using {@link #makeNumeric(String)}). */
+	public static final Pattern NUMERIC_REGEX = Pattern.compile("[0-9]*");
+	
+	/** Can test whether a string is encodable in alphanumeric mode (such as by using {@link #makeAlphanumeric(String)}). */
+	public static final Pattern ALPHANUMERIC_REGEX = Pattern.compile("[A-Z0-9 $%*+./:-]*");
+	
+	/** The set of all legal characters in alphanumeric mode, where each character value maps to the index in the string. */
+	private static final String ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
+	
+	
+	
+	/*---- Public helper enumeration ----*/
+	
+	/**
+	 * The mode field of a segment. Immutable. Provides methods to retrieve closely related values.
+	 */
+	public enum Mode {
+		
+		/*-- Constants --*/
+		
+		NUMERIC     (0x1, 10, 12, 14),
+		ALPHANUMERIC(0x2,  9, 11, 13),
+		BYTE        (0x4,  8, 16, 16),
+		KANJI       (0x8,  8, 10, 12),
+		ECI         (0x7,  0,  0,  0);
+		
+		
+		/*-- Fields --*/
+		
+		/** An unsigned 4-bit integer value (range 0 to 15) representing the mode indicator bits for this mode object. */
+		final int modeBits;
+		
+		private final int[] numBitsCharCount;
+		
+		
+		/*-- Constructor --*/
+		
+		private Mode(int mode, int... ccbits) {
+			this.modeBits = mode;
+			numBitsCharCount = ccbits;
+		}
+		
+		
+		/*-- Method --*/
+		
+		/**
+		 * Returns the bit width of the segment character count field for this mode object at the specified version number.
+		 * @param ver the version number, which is between 1 to 40, inclusive
+		 * @return the number of bits for the character count, which is between 8 to 16, inclusive
+		 * @throws IllegalArgumentException if the version number is out of range
+		 */
+		int numCharCountBits(int ver) {
+			if      ( 1 <= ver && ver <=  9)  return numBitsCharCount[0];
+			else if (10 <= ver && ver <= 26)  return numBitsCharCount[1];
+			else if (27 <= ver && ver <= 40)  return numBitsCharCount[2];
+			else  throw new IllegalArgumentException("Version number out of range");
+		}
+		
+	}
+	
+}
diff --git a/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrSegmentAdvanced.java b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrSegmentAdvanced.java
new file mode 100644
index 0000000..34847e4
--- /dev/null
+++ b/src/third_party/QR-Code-generator/java/io/nayuki/qrcodegen/QrSegmentAdvanced.java
@@ -0,0 +1,402 @@
+/* 
+ * QR Code generator library - Optional advanced logic (Java)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+package io.nayuki.qrcodegen;
+
+import static io.nayuki.qrcodegen.QrSegment.Mode.ALPHANUMERIC;
+import static io.nayuki.qrcodegen.QrSegment.Mode.BYTE;
+import static io.nayuki.qrcodegen.QrSegment.Mode.NUMERIC;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.List;
+import java.util.Objects;
+
+
+public final class QrSegmentAdvanced {
+	
+	/*---- Optimal list of segments encoder ----*/
+	
+	/**
+	 * Returns a new mutable list of zero or more segments to represent the specified Unicode text string.
+	 * The resulting list optimally minimizes the total encoded bit length, subjected to the constraints given
+	 * by the specified {error correction level, minimum version number, maximum version number}, plus the additional
+	 * constraint that the segment modes {NUMERIC, ALPHANUMERIC, BYTE} can be used but KANJI cannot be used.
+	 * <p>This function can be viewed as a significantly more sophisticated and slower replacement
+	 * for {@link QrSegment#makeSegments(String)}, but requiring more input parameters in a way
+	 * that overlaps with {@link QrCode#encodeSegments(List,QrCode.Ecc,int,int,int,boolean)}.</p>
+	 * @param text the text to be encoded, which can be any Unicode string
+	 * @param ecl the error correction level to use
+	 * @param minVersion the minimum allowed version of the QR symbol (at least 1)
+	 * @param maxVersion the maximum allowed version of the QR symbol (at most 40)
+	 * @return a list of segments containing the text, minimizing the bit length with respect to the constraints
+	 * @throws NullPointerException if the data or error correction level is {@code null}
+	 * @throws IllegalArgumentException if 1 &le; minVersion &le; maxVersion &le; 40 is violated,
+	 * or if the data is too long to fit in a QR Code at maxVersion at the ECL
+	 */
+	public static List<QrSegment> makeSegmentsOptimally(String text, QrCode.Ecc ecl, int minVersion, int maxVersion) {
+		// Check arguments
+		Objects.requireNonNull(text);
+		Objects.requireNonNull(ecl);
+		if (!(1 <= minVersion && minVersion <= maxVersion && maxVersion <= 40))
+			throw new IllegalArgumentException("Invalid value");
+		
+		// Iterate through version numbers, and make tentative segments
+		List<QrSegment> segs = null;
+		for (int version = minVersion; version <= maxVersion; version++) {
+			if (version == minVersion || version == 10 || version == 27)
+				segs = makeSegmentsOptimally(text, version);
+			
+			// Check if the segments fit
+			int dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;
+			int dataUsedBits = QrSegment.getTotalBits(segs, version);
+			if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits)
+				return segs;
+		}
+		throw new IllegalArgumentException("Data too long");
+	}
+	
+	
+	// Returns a list of segments that is optimal for the given text at the given version number.
+	private static List<QrSegment> makeSegmentsOptimally(String text, int version) {
+		byte[] data = text.getBytes(StandardCharsets.UTF_8);
+		int[][] bitCosts = computeBitCosts(data, version);
+		QrSegment.Mode[] charModes = computeCharacterModes(data, version, bitCosts);
+		return splitIntoSegments(data, charModes);
+	}
+	
+	
+	private static int[][] computeBitCosts(byte[] data, int version) {
+		// Segment header sizes, measured in 1/6 bits
+		int bytesCost   = (4 + BYTE        .numCharCountBits(version)) * 6;
+		int alphnumCost = (4 + ALPHANUMERIC.numCharCountBits(version)) * 6;
+		int numberCost  = (4 + NUMERIC     .numCharCountBits(version)) * 6;
+		
+		// result[mode][len] is the number of 1/6 bits to encode the first len characters of the text, ending in the mode
+		int[][] result = new int[3][data.length + 1];
+		Arrays.fill(result[1], Integer.MAX_VALUE / 2);
+		Arrays.fill(result[2], Integer.MAX_VALUE / 2);
+		result[0][0] = bytesCost;
+		result[1][0] = alphnumCost;
+		result[2][0] = numberCost;
+		
+		// Calculate the cost table using dynamic programming
+		for (int i = 0; i < data.length; i++) {
+			// Encode a character
+			int j = i + 1;
+			char c = (char)data[i];
+			result[0][j] = result[0][i] + 48;  // 8 bits per byte
+			if (isAlphanumeric(c))
+				result[1][j] = result[1][i] + 33;  // 5.5 bits per alphanumeric char
+			if (isNumeric(c))
+				result[2][j] = result[2][i] + 20;  // 3.33 bits per digit
+			
+			// Switch modes, rounding up fractional bits
+			result[0][j] = Math.min((Math.min(result[1][j], result[2][j]) + 5) / 6 * 6 + bytesCost  , result[0][j]);
+			result[1][j] = Math.min((Math.min(result[2][j], result[0][j]) + 5) / 6 * 6 + alphnumCost, result[1][j]);
+			result[2][j] = Math.min((Math.min(result[0][j], result[1][j]) + 5) / 6 * 6 + numberCost , result[2][j]);
+		}
+		return result;
+	}
+	
+	
+	private static QrSegment.Mode[] computeCharacterModes(byte[] data, int version, int[][] bitCosts) {
+		// Segment header sizes, measured in 1/6 bits
+		int bytesCost   = (4 + BYTE        .numCharCountBits(version)) * 6;
+		int alphnumCost = (4 + ALPHANUMERIC.numCharCountBits(version)) * 6;
+		int numberCost  = (4 + NUMERIC     .numCharCountBits(version)) * 6;
+		
+		// Infer the mode used for last character by taking the minimum
+		QrSegment.Mode curMode;
+		int end = bitCosts[0].length - 1;
+		if (bitCosts[0][end] <= Math.min(bitCosts[1][end], bitCosts[2][end]))
+			curMode = BYTE;
+		else if (bitCosts[1][end] <= bitCosts[2][end])
+			curMode = ALPHANUMERIC;
+		else
+			curMode = NUMERIC;
+		
+		// Work backwards to calculate optimal encoding mode for each character
+		QrSegment.Mode[] result = new QrSegment.Mode[data.length];
+		if (data.length == 0)
+			return result;
+		result[data.length - 1] = curMode;
+		for (int i = data.length - 2; i >= 0; i--) {
+			char c = (char)data[i];
+			if (curMode == NUMERIC) {
+				if (isNumeric(c))
+					curMode = NUMERIC;
+				else if (isAlphanumeric(c) && (bitCosts[1][i] + 33 + 5) / 6 * 6 + numberCost == bitCosts[2][i + 1])
+					curMode = ALPHANUMERIC;
+				else
+					curMode = BYTE;
+			} else if (curMode == ALPHANUMERIC) {
+				if (isNumeric(c) && (bitCosts[2][i] + 20 + 5) / 6 * 6 + alphnumCost == bitCosts[1][i + 1])
+					curMode = NUMERIC;
+				else if (isAlphanumeric(c))
+					curMode = ALPHANUMERIC;
+				else
+					curMode = BYTE;
+			} else if (curMode == BYTE) {
+				if (isNumeric(c) && (bitCosts[2][i] + 20 + 5) / 6 * 6 + bytesCost == bitCosts[0][i + 1])
+					curMode = NUMERIC;
+				else if (isAlphanumeric(c) && (bitCosts[1][i] + 33 + 5) / 6 * 6 + bytesCost == bitCosts[0][i + 1])
+					curMode = ALPHANUMERIC;
+				else
+					curMode = BYTE;
+			} else
+				throw new AssertionError();
+			result[i] = curMode;
+		}
+		return result;
+	}
+	
+	
+	private static List<QrSegment> splitIntoSegments(byte[] data, QrSegment.Mode[] charModes) {
+		List<QrSegment> result = new ArrayList<>();
+		if (data.length == 0)
+			return result;
+		
+		// Accumulate run of modes
+		QrSegment.Mode curMode = charModes[0];
+		int start = 0;
+		for (int i = 1; i < data.length; i++) {
+			if (charModes[i] != curMode) {
+				if (curMode == BYTE)
+					result.add(QrSegment.makeBytes(Arrays.copyOfRange(data, start, i)));
+				else {
+					String temp = new String(data, start, i - start, StandardCharsets.US_ASCII);
+					if (curMode == NUMERIC)
+						result.add(QrSegment.makeNumeric(temp));
+					else if (curMode == ALPHANUMERIC)
+						result.add(QrSegment.makeAlphanumeric(temp));
+					else
+						throw new AssertionError();
+				}
+				curMode = charModes[i];
+				start = i;
+			}
+		}
+		
+		// Final segment
+		if (curMode == BYTE)
+			result.add(QrSegment.makeBytes(Arrays.copyOfRange(data, start, data.length)));
+		else {
+			String temp = new String(data, start, data.length - start, StandardCharsets.US_ASCII);
+			if (curMode == NUMERIC)
+				result.add(QrSegment.makeNumeric(temp));
+			else if (curMode == ALPHANUMERIC)
+				result.add(QrSegment.makeAlphanumeric(temp));
+			else
+				throw new AssertionError();
+		}
+		return result;
+	}
+	
+	
+	private static boolean isAlphanumeric(char c) {
+		return isNumeric(c) || 'A' <= c && c <= 'Z' || " $%*+./:-".indexOf(c) != -1;
+	}
+	
+	private static boolean isNumeric(char c) {
+		return '0' <= c && c <= '9';
+	}
+	
+	
+	/*---- Kanji mode segment encoder ----*/
+	
+	/**
+	 * Returns a segment representing the specified string encoded in kanji mode.
+	 * <p>Note that broadly speaking, the set of encodable characters are {kanji used in Japan, hiragana, katakana,
+	 * Asian punctuation, full-width ASCII}.<br/>
+	 * In particular, non-encodable characters are {normal ASCII, half-width katakana, more extensive Chinese hanzi}.
+	 * @param text the text to be encoded, which must fall in the kanji mode subset of characters
+	 * @return a segment containing the data
+	 * @throws NullPointerException if the string is {@code null}
+	 * @throws IllegalArgumentException if the string contains non-kanji-mode characters
+	 * @see #isEncodableAsKanji(String)
+	 */
+	public static QrSegment makeKanjiSegment(String text) {
+		Objects.requireNonNull(text);
+		BitBuffer bb = new BitBuffer();
+		for (int i = 0; i < text.length(); i++) {
+			int val = UNICODE_TO_QR_KANJI[text.charAt(i)];
+			if (val == -1)
+				throw new IllegalArgumentException("String contains non-kanji-mode characters");
+			bb.appendBits(val, 13);
+		}
+		return new QrSegment(QrSegment.Mode.KANJI, text.length(), bb);
+	}
+	
+	
+	/**
+	 * Tests whether the specified text string can be encoded as a segment in kanji mode.
+	 * <p>Note that broadly speaking, the set of encodable characters are {kanji used in Japan, hiragana, katakana,
+	 * Asian punctuation, full-width ASCII}.<br/>
+	 * In particular, non-encodable characters are {normal ASCII, half-width katakana, more extensive Chinese hanzi}.
+	 * @param text the string to test for encodability
+	 * @return {@code true} if and only if the string can be encoded in kanji mode
+	 * @throws NullPointerException if the string is {@code null}
+	 * @see #makeKanjiSegment(String)
+	 */
+	public static boolean isEncodableAsKanji(String text) {
+		Objects.requireNonNull(text);
+		for (int i = 0; i < text.length(); i++) {
+			if (UNICODE_TO_QR_KANJI[text.charAt(i)] == -1)
+				return false;
+		}
+		return true;
+	}
+	
+	
+	// Data derived from ftp://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT
+	private static final String PACKED_QR_KANJI_TO_UNICODE =
+		"MAAwATAC/wz/DjD7/xr/G/8f/wEwmzCcALT/QACo/z7/4/8/MP0w/jCdMJ4wA07dMAUwBjAHMPwgFSAQ/w8AXDAcIBb/XCAmICUgGCAZIBwgHf8I/wkwFDAV/zv/Pf9b/10wCDAJMAowCzAMMA0wDjAPMBAwEf8LIhIAsQDX//8A9/8dImD/HP8eImYiZyIeIjQmQiZA" +
+		"ALAgMiAzIQP/5f8EAKIAo/8F/wP/Bv8K/yAApyYGJgUlyyXPJc4lxyXGJaEloCWzJbIlvSW8IDswEiGSIZAhkSGTMBP/////////////////////////////IggiCyKGIocigiKDIioiKf////////////////////8iJyIoAKwh0iHUIgAiA///////////////////" +
+		"//////////8iICKlIxIiAiIHImEiUiJqImsiGiI9Ih0iNSIrIiz//////////////////yErIDAmbyZtJmogICAhALb//////////yXv/////////////////////////////////////////////////xD/Ef8S/xP/FP8V/xb/F/8Y/xn///////////////////8h" +
+		"/yL/I/8k/yX/Jv8n/yj/Kf8q/yv/LP8t/y7/L/8w/zH/Mv8z/zT/Nf82/zf/OP85/zr///////////////////9B/0L/Q/9E/0X/Rv9H/0j/Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r//////////zBBMEIwQzBEMEUwRjBHMEgwSTBKMEswTDBN" +
+		"ME4wTzBQMFEwUjBTMFQwVTBWMFcwWDBZMFowWzBcMF0wXjBfMGAwYTBiMGMwZDBlMGYwZzBoMGkwajBrMGwwbTBuMG8wcDBxMHIwczB0MHUwdjB3MHgweTB6MHswfDB9MH4wfzCAMIEwgjCDMIQwhTCGMIcwiDCJMIowizCMMI0wjjCPMJAwkTCSMJP/////////////" +
+		"////////////////////////MKEwojCjMKQwpTCmMKcwqDCpMKowqzCsMK0wrjCvMLAwsTCyMLMwtDC1MLYwtzC4MLkwujC7MLwwvTC+ML8wwDDBMMIwwzDEMMUwxjDHMMgwyTDKMMswzDDNMM4wzzDQMNEw0jDTMNQw1TDWMNcw2DDZMNow2zDcMN0w3jDf//8w4DDh" +
+		"MOIw4zDkMOUw5jDnMOgw6TDqMOsw7DDtMO4w7zDwMPEw8jDzMPQw9TD2/////////////////////wORA5IDkwOUA5UDlgOXA5gDmQOaA5sDnAOdA54DnwOgA6EDowOkA6UDpgOnA6gDqf////////////////////8DsQOyA7MDtAO1A7YDtwO4A7kDugO7A7wDvQO+" +
+		"A78DwAPBA8MDxAPFA8YDxwPIA8n/////////////////////////////////////////////////////////////////////////////////////////////////////////////BBAEEQQSBBMEFAQVBAEEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQm" +
+		"BCcEKAQpBCoEKwQsBC0ELgQv////////////////////////////////////////BDAEMQQyBDMENAQ1BFEENgQ3BDgEOQQ6BDsEPAQ9//8EPgQ/BEAEQQRCBEMERARFBEYERwRIBEkESgRLBEwETQROBE///////////////////////////////////yUAJQIlDCUQ" +
+		"JRglFCUcJSwlJCU0JTwlASUDJQ8lEyUbJRclIyUzJSslOyVLJSAlLyUoJTclPyUdJTAlJSU4JUL/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"/////////////////////////////////////06cVRZaA5Y/VMBhG2MoWfaQIoR1gxx6UGCqY+FuJWXthGaCppv1aJNXJ2WhYnFbm1nQhnuY9H1ifb6bjmIWfJ+It1uJXrVjCWaXaEiVx5eNZ09O5U8KT01PnVBJVvJZN1nUWgFcCWDfYQ9hcGYTaQVwunVPdXB5+32t" +
+		"fe+Aw4QOiGOLApBVkHpTO06VTqVX34CykMF4704AWPFuopA4ejKDKIKLnC9RQVNwVL1U4VbgWftfFZjybeuA5IUt////////lmKWcJagl/tUC1PzW4dwz3+9j8KW6FNvnVx6uk4ReJOB/G4mVhhVBGsdhRqcO1nlU6ltZnTclY9WQk6RkEuW8oNPmQxT4VW2WzBfcWYg" +
+		"ZvNoBGw4bPNtKXRbdsh6Tpg0gvGIW4pgku1tsnWrdsqZxWCmiwGNipWyaY5TrVGG//9XElgwWURbtF72YChjqWP0bL9vFHCOcRRxWXHVcz9+AYJ2gtGFl5BgkludG1hpZbxsWnUlUflZLlllX4Bf3GK8ZfpqKmsna7Rzi3/BiVadLJ0OnsRcoWyWg3tRBFxLYbaBxmh2" +
+		"cmFOWU/6U3hgaW4pek+X804LUxZO7k9VTz1PoU9zUqBT71YJWQ9awVu2W+F50WaHZ5xntmtMbLNwa3PCeY15vno8e4eCsYLbgwSDd4Pvg9OHZoqyVimMqI/mkE6XHoaKT8Rc6GIRcll1O4Hlgr2G/ozAlsWZE5nVTstPGonjVt5YSljKXvtf62AqYJRgYmHQYhJi0GU5" +
+		"////////m0FmZmiwbXdwcHVMdoZ9dYKlh/mVi5aOjJ1R8VK+WRZUs1uzXRZhaGmCba94jYTLiFeKcpOnmrhtbJmohtlXo2f/hs6SDlKDVodUBF7TYuFkuWg8aDhru3NyeLp6a4maidKNa48DkO2Vo5aUl2lbZlyzaX2YTZhOY5t7IGor//9qf2i2nA1vX1JyVZ1gcGLs" +
+		"bTtuB27RhFuJEI9EThScOVP2aRtqOpeEaCpRXHrDhLKR3JOMVludKGgigwWEMXylUgiCxXTmTn5Pg1GgW9JSClLYUudd+1WaWCpZ5luMW5hb215yXnlgo2EfYWNhvmPbZWJn0WhTaPprPmtTbFdvIm+Xb0V0sHUYduN3C3r/e6F8IX3pfzZ/8ICdgmaDnomzisyMq5CE" +
+		"lFGVk5WRlaKWZZfTmSiCGE44VCtcuF3Mc6l2THc8XKl/640LlsGYEZhUmFhPAU8OU3FVnFZoV/pZR1sJW8RckF4MXn5fzGPuZzpl12XiZx9oy2jE////////al9eMGvFbBdsfXV/eUhbY3oAfQBfvYmPihiMtI13jsyPHZjimg6bPE6AUH1RAFmTW5xiL2KAZOxrOnKg" +
+		"dZF5R3+ph/uKvItwY6yDypegVAlUA1WraFRqWIpweCdndZ7NU3RbooEahlCQBk4YTkVOx08RU8pUOFuuXxNgJWVR//9nPWxCbHJs43B4dAN6dnquewh9Gnz+fWZl53JbU7tcRV3oYtJi4GMZbiCGWooxjd2S+G8BeaabWk6oTqtOrE+bT6BQ0VFHevZRcVH2U1RTIVN/" +
+		"U+tVrFiDXOFfN19KYC9gUGBtYx9lWWpLbMFywnLtd++A+IEFggiFTpD3k+GX/5lXmlpO8FHdXC1mgWltXEBm8ml1c4loUHyBUMVS5FdHXf6TJmWkayNrPXQ0eYF5vXtLfcqCuYPMiH+JX4s5j9GR0VQfkoBOXVA2U+VTOnLXc5Z36YLmjq+ZxpnImdJRd2Eahl5VsHp6" +
+		"UHZb05BHloVOMmrbkedcUVxI////////Y5h6n2yTl3SPYXqqcYqWiHyCaBd+cGhRk2xS8lQbhauKE3+kjs2Q4VNmiIh5QU/CUL5SEVFEVVNXLXPqV4tZUV9iX4RgdWF2YWdhqWOyZDplbGZvaEJuE3Vmej18+31MfZl+S39rgw6DSobNigiKY4tmjv2YGp2PgriPzpvo" +
+		"//9Sh2IfZINvwJaZaEFQkWsgbHpvVHp0fVCIQIojZwhO9lA5UCZQZVF8UjhSY1WnVw9YBVrMXvphsmH4YvNjcmkcailyfXKscy54FHhvfXl3DICpiYuLGYzijtKQY5N1lnqYVZoTnnhRQ1OfU7Nee18mbhtukHOEc/59Q4I3igCK+pZQTk5QC1PkVHxW+lnRW2Rd8V6r" +
+		"XydiOGVFZ69uVnLQfMqItIChgOGD8IZOioeN6JI3lseYZ58TTpROkk8NU0hUSVQ+Wi9fjF+hYJ9op2qOdFp4gYqeiqSLd5GQTl6byU6kT3xPr1AZUBZRSVFsUp9SuVL+U5pT41QR////////VA5ViVdRV6JZfVtUW11bj13lXedd9154XoNeml63XxhgUmFMYpdi2GOn" +
+		"ZTtmAmZDZvRnbWghaJdpy2xfbSptaW4vbp11MnaHeGx6P3zgfQV9GH1efbGAFYADgK+AsYFUgY+CKoNSiEyIYYsbjKKM/JDKkXWScXg/kvyVpJZN//+YBZmZmtidO1JbUqtT91QIWNVi92/gjGqPX565UUtSO1RKVv16QJF3nWCe0nNEbwmBcHURX/1g2pqoctuPvGtk" +
+		"mANOylbwV2RYvlpaYGhhx2YPZgZoOWixbfd11X06gm6bQk6bT1BTyVUGXW9d5l3uZ/tsmXRzeAKKUJOWiN9XUF6nYytQtVCsUY1nAFTJWF5Zu1uwX2liTWOhaD1rc24IcH2Rx3KAeBV4JnltZY59MIPciMGPCZabUmRXKGdQf2qMoVG0V0KWKlg6aYqAtFSyXQ5X/HiV" +
+		"nfpPXFJKVItkPmYoZxRn9XqEe1Z9IpMvaFybrXs5UxlRilI3////////W99i9mSuZOZnLWu6hamW0XaQm9ZjTJMGm6t2v2ZSTglQmFPCXHFg6GSSZWNoX3Hmc8p1I3uXfoKGlYuDjNuReJkQZaxmq2uLTtVO1E86T39SOlP4U/JV41bbWOtZy1nJWf9bUFxNXgJeK1/X" +
+		"YB1jB2UvW1xlr2W9ZehnnWti//9re2wPc0V5SXnBfPh9GX0rgKKBAoHziZaKXoppimaKjIrujMeM3JbMmPxrb06LTzxPjVFQW1db+mFIYwFmQmshbstsu3I+dL111HjBeTqADIAzgeqElI+ebFCef18Pi1idK3r6jvhbjZbrTgNT8Vf3WTFayVukYIluf28Gdb6M6luf" +
+		"hQB74FByZ/SCnVxhhUp+HoIOUZlcBGNojWZlnHFueT59F4AFix2OypBuhseQqlAfUvpcOmdTcHxyNZFMkciTK4LlW8JfMWD5TjtT1luIYktnMWuKculz4HougWuNo5FSmZZRElPXVGpb/2OIajl9rJcAVtpTzlRo////////W5dcMV3eT+5hAWL+bTJ5wHnLfUJ+TX/S" +
+		"ge2CH4SQiEaJcouQjnSPL5AxkUuRbJbGkZxOwE9PUUVTQV+TYg5n1GxBbgtzY34mkc2Sg1PUWRlbv23ReV1+LnybWH5xn1H6iFOP8E/KXPtmJXeseuOCHJn/UcZfqmXsaW9riW3z//9ulm9kdv59FF3hkHWRh5gGUeZSHWJAZpFm2W4aXrZ90n9yZviFr4X3ivhSqVPZ" +
+		"WXNej1+QYFWS5JZkULdRH1LdUyBTR1PsVOhVRlUxVhdZaFm+WjxbtVwGXA9cEVwaXoReil7gX3Bif2KEYttjjGN3ZgdmDGYtZnZnfmiiah9qNWy8bYhuCW5YcTxxJnFndcd3AXhdeQF5ZXnweuB7EXynfTmAloPWhIuFSYhdiPOKH4o8ilSKc4xhjN6RpJJmk36UGJac" +
+		"l5hOCk4ITh5OV1GXUnBXzlg0WMxbIl44YMVk/mdhZ1ZtRHK2dXN6Y4S4i3KRuJMgVjFX9Jj+////////Yu1pDWuWce1+VIB3gnKJ5pjfh1WPsVw7TzhP4U+1VQdaIFvdW+lfw2FOYy9lsGZLaO5pm214bfF1M3W5dx95XnnmfTOB44KvhaqJqoo6jquPm5Aykd2XB066" +
+		"TsFSA1h1WOxcC3UaXD2BTooKj8WWY5dteyWKz5gIkWJW81Oo//+QF1Q5V4JeJWOobDRwindhfIt/4IhwkEKRVJMQkxiWj3RemsRdB11pZXBnoo2olttjbmdJaRmDxZgXlsCI/m+EZHpb+E4WcCx1XWYvUcRSNlLiWdNfgWAnYhBlP2V0Zh9mdGjyaBZrY24FcnJ1H3bb" +
+		"fL6AVljwiP2Jf4qgipOKy5AdkZKXUpdZZYl6DoEGlrteLWDcYhplpWYUZ5B383pNfE1+PoEKjKyNZI3hjl94qVIHYtljpWRCYpiKLXqDe8CKrJbqfXaCDIdJTtlRSFNDU2Bbo1wCXBZd3WImYkdksGgTaDRsyW1FbRdn029ccU5xfWXLen97rX3a////////fkp/qIF6" +
+		"ghuCOYWmim6Mzo31kHiQd5KtkpGVg5uuUk1VhG84cTZRaHmFflWBs3zOVkxYUVyoY6pm/mb9aVpy2XWPdY55DnlWed98l30gfUSGB4o0ljuQYZ8gUOdSdVPMU+JQCVWqWO5ZT3I9W4tcZFMdYONg82NcY4NjP2O7//9kzWXpZvld42nNaf1vFXHlTol16Xb4epN8333P" +
+		"fZyAYYNJg1iEbIS8hfuIxY1wkAGQbZOXlxyaElDPWJdhjoHThTWNCJAgT8NQdFJHU3Ngb2NJZ19uLI2zkB9P11xejMplz32aU1KIllF2Y8NbWFtrXApkDWdRkFxO1lkaWSpscIpRVT5YFVmlYPBiU2fBgjVpVZZAmcSaKE9TWAZb/oAQXLFeL1+FYCBhS2I0Zv9s8G7e" +
+		"gM6Bf4LUiIuMuJAAkC6Wip7bm9tO41PwWSd7LJGNmEyd+W7dcCdTU1VEW4ViWGKeYtNsom/vdCKKF5Q4b8GK/oM4UeeG+FPq////////U+lPRpBUj7BZaoExXf166o+/aNqMN3L4nEhqPYqwTjlTWFYGV2ZixWOiZeZrTm3hbltwrXfteu97qn27gD2AxobLipWTW1bj" +
+		"WMdfPmWtZpZqgGu1dTeKx1Akd+VXMF8bYGVmemxgdfR6Gn9ugfSHGJBFmbN7yXVcevl7UYTE//+QEHnpepKDNlrhd0BOLU7yW5lf4GK9Zjxn8WzohmuId4o7kU6S85nQahdwJnMqgueEV4yvTgFRRlHLVYtb9V4WXjNegV8UXzVfa1+0YfJjEWaiZx1vbnJSdTp3OoB0" +
+		"gTmBeId2ir+K3I2FjfOSmpV3mAKc5VLFY1d29GcVbIhzzYzDk66Wc20lWJxpDmnMj/2TmnXbkBpYWmgCY7Rp+09Dbyxn2I+7hSZ9tJNUaT9vcFdqWPdbLH0scipUCpHjnbROrU9OUFxQdVJDjJ5USFgkW5peHV6VXq1e918fYIxitWM6Y9Bor2xAeId5jnoLfeCCR4oC" +
+		"iuaORJAT////////kLiRLZHYnw5s5WRYZOJldW70doR7G5Bpk9FuulTyX7lkpI9Nj+2SRFF4WGtZKVxVXpdt+36PdRyMvI7imFtwuU8da79vsXUwlvtRTlQQWDVYV1msXGBfkmWXZ1xuIXZ7g9+M7ZAUkP2TTXgleDpSql6mVx9ZdGASUBJRWlGs//9RzVIAVRBYVFhY" +
+		"WVdblVz2XYtgvGKVZC1ncWhDaLxo33bXbdhub22bcG9xyF9Tddh5d3tJe1R7UnzWfXFSMIRjhWmF5IoOiwSMRo4PkAOQD5QZlnaYLZowldhQzVLVVAxYAlwOYadknm0ed7N65YD0hASQU5KFXOCdB1M/X5dfs22ccnl3Y3m/e+Rr0nLsiq1oA2phUfh6gWk0XEqc9oLr" +
+		"W8WRSXAeVnhcb2DHZWZsjIxakEGYE1RRZseSDVlIkKNRhU5NUeqFmYsOcFhjepNLaWKZtH4EdXdTV2lgjt+W42xdToxcPF8Qj+lTAozRgImGeV7/ZeVOc1Fl////////WYJcP5fuTvtZil/Nio1v4XmweWJb54RxcytxsV50X/Vje2SaccN8mE5DXvxOS1fcVqJgqW/D" +
+		"fQ2A/YEzgb+PsomXhqRd9GKKZK2Jh2d3bOJtPnQ2eDRaRn91gq2ZrE/zXsNi3WOSZVdnb3bDckyAzIC6jymRTVANV/lakmiF//9pc3Fkcv2Mt1jyjOCWapAZh3955HfnhClPL1JlU1pizWfPbMp2fXuUfJWCNoWEj+tm3W8gcgZ+G4OrmcGeplH9e7F4cnu4gId7SGro" +
+		"XmGAjHVRdWBRa5Jibox2epGXmupPEH9wYpx7T5WlnOlWelhZhuSWvE80UiRTSlPNU9teBmQsZZFnf2w+bE5ySHKvc+11VH5BgiyF6Yype8SRxnFpmBKY72M9Zml1anbkeNCFQ4buUypTUVQmWYNeh198YLJiSWJ5YqtlkGvUbMx1snaueJF52H3Lf3eApYirirmMu5B/" +
+		"l16Y22oLfDhQmVw+X65nh2vYdDV3CX+O////////nztnynoXUzl1i5rtX2aBnYPxgJhfPF/FdWJ7RpA8aGdZ61qbfRB2fossT/VfamoZbDdvAnTieWiIaIpVjHle32PPdcV50oLXkyiS8oSchu2cLVTBX2xljG1ccBWMp4zTmDtlT3T2Tg1O2FfgWStaZlvMUaheA16c" +
+		"YBZidmV3//9lp2ZubW5yNnsmgVCBmoKZi1yMoIzmjXSWHJZET65kq2tmgh6EYYVqkOhcAWlTmKiEeoVXTw9Sb1+pXkVnDXmPgXmJB4mGbfVfF2JVbLhOz3Jpm5JSBlQ7VnRYs2GkYm5xGllufIl83n0blvBlh4BeThlPdVF1WEBeY15zXwpnxE4mhT2ViZZbfHOYAVD7" +
+		"WMF2VninUiV3pYURe4ZQT1kJckd7x33oj7qP1JBNT79SyVopXwGXrU/dgheS6lcDY1VraXUriNyPFHpCUt9Yk2FVYgpmrmvNfD+D6VAjT/hTBVRGWDFZSVudXPBc710pXpZisWNnZT5luWcL////////bNVs4XD5eDJ+K4DegrOEDITshwKJEooqjEqQppLSmP2c851s" +
+		"Tk9OoVCNUlZXSlmoXj1f2F/ZYj9mtGcbZ9Bo0lGSfSGAqoGoiwCMjIy/kn6WMlQgmCxTF1DVU1xYqGSyZzRyZ3dmekaR5lLDbKFrhlgAXkxZVGcsf/tR4XbG//9kaXjom1Seu1fLWblmJ2eaa85U6WnZXlWBnGeVm6pn/pxSaF1Opk/jU8hiuWcrbKuPxE+tfm2ev04H" +
+		"YWJugG8rhRNUc2cqm0Vd83uVXKxbxoccbkqE0XoUgQhZmXyNbBF3IFLZWSJxIXJfd9uXJ51haQtaf1oYUaVUDVR9Zg5234/3kpic9Fnqcl1uxVFNaMl9v33sl2KeumR4aiGDAlmEW19r23MbdvJ9soAXhJlRMmcontl27mdiUv+ZBVwkYjt8foywVU9gtn0LlYBTAU5f" +
+		"UbZZHHI6gDaRzl8ld+JThF95fQSFrIozjo2XVmfzha6UU2EJYQhsuXZS////////iu2POFUvT1FRKlLHU8tbpV59YKBhgmPWZwln2m5nbYxzNnM3dTF5UIjVipiQSpCRkPWWxIeNWRVOiE9ZTg6KiY8/mBBQrV58WZZbuV64Y9pj+mTBZtxpSmnYbQtutnGUdSh6r3+K" +
+		"gACESYTJiYGLIY4KkGWWfZkKYX5ikWsy//9sg210f8x//G3Af4WHuoj4Z2WDsZg8lvdtG31hhD2Rak5xU3VdUGsEb+uFzYYtiadSKVQPXGVnTmiodAZ0g3XiiM+I4ZHMluKWeF+Lc4d6y4ROY6B1ZVKJbUFunHQJdVl4a3ySloZ63J+NT7ZhbmXFhlxOhk6uUNpOIVHM" +
+		"W+5lmWiBbbxzH3ZCd616HHzngm+K0pB8kc+WdZgYUpt90VArU5hnl23LcdB0M4HojyqWo5xXnp90YFhBbZl9L5heTuRPNk+LUbdSsV26YBxzsnk8gtOSNJa3lvaXCp6Xn2Jmpmt0UhdSo3DIiMJeyWBLYZBvI3FJfD599IBv////////hO6QI5MsVEKbb2rTcImMwo3v" +
+		"lzJStFpBXspfBGcXaXxplG1qbw9yYnL8e+2AAYB+h0uQzlFtnpN5hICLkzKK1lAtVIyKcWtqjMSBB2DRZ6Cd8k6ZTpicEIprhcGFaGkAbn54l4FV////////////////////////////////////////////////////////////////////////////////////////" +
+		"/////////////////////////////18MThBOFU4qTjFONk48Tj9OQk5WTlhOgk6FjGtOioISXw1Ojk6eTp9OoE6iTrBOs062Ts5OzU7ETsZOwk7XTt5O7U7fTvdPCU9aTzBPW09dT1dPR092T4hPj0+YT3tPaU9wT5FPb0+GT5ZRGE/UT99Pzk/YT9tP0U/aT9BP5E/l" +
+		"UBpQKFAUUCpQJVAFTxxP9lAhUClQLE/+T+9QEVAGUENQR2cDUFVQUFBIUFpQVlBsUHhQgFCaUIVQtFCy////////UMlQylCzUMJQ1lDeUOVQ7VDjUO5Q+VD1UQlRAVECURZRFVEUURpRIVE6UTdRPFE7UT9RQFFSUUxRVFFievhRaVFqUW5RgFGCVthRjFGJUY9RkVGT" +
+		"UZVRllGkUaZRolGpUapRq1GzUbFRslGwUbVRvVHFUclR21HghlVR6VHt//9R8FH1Uf5SBFILUhRSDlInUipSLlIzUjlST1JEUktSTFJeUlRSalJ0UmlSc1J/Un1SjVKUUpJScVKIUpGPqI+nUqxSrVK8UrVSwVLNUtdS3lLjUuaY7VLgUvNS9VL4UvlTBlMIdThTDVMQ" +
+		"Uw9TFVMaUyNTL1MxUzNTOFNAU0ZTRU4XU0lTTVHWU15TaVNuWRhTe1N3U4JTllOgU6ZTpVOuU7BTtlPDfBKW2VPfZvxx7lPuU+hT7VP6VAFUPVRAVCxULVQ8VC5UNlQpVB1UTlSPVHVUjlRfVHFUd1RwVJJUe1SAVHZUhFSQVIZUx1SiVLhUpVSsVMRUyFSo////////" +
+		"VKtUwlSkVL5UvFTYVOVU5lUPVRRU/VTuVO1U+lTiVTlVQFVjVUxVLlVcVUVVVlVXVThVM1VdVZlVgFSvVYpVn1V7VX5VmFWeVa5VfFWDValVh1WoVdpVxVXfVcRV3FXkVdRWFFX3VhZV/lX9VhtV+VZOVlBx31Y0VjZWMlY4//9Wa1ZkVi9WbFZqVoZWgFaKVqBWlFaP" +
+		"VqVWrla2VrRWwla8VsFWw1bAVshWzlbRVtNW11buVvlXAFb/VwRXCVcIVwtXDVcTVxhXFlXHVxxXJlc3VzhXTlc7V0BXT1dpV8BXiFdhV39XiVeTV6BXs1ekV6pXsFfDV8ZX1FfSV9NYClfWV+NYC1gZWB1YclghWGJYS1hwa8BYUlg9WHlYhVi5WJ9Yq1i6WN5Yu1i4" +
+		"WK5YxVjTWNFY11jZWNhY5VjcWORY31jvWPpY+Vj7WPxY/VkCWQpZEFkbaKZZJVksWS1ZMlk4WT560llVWVBZTllaWVhZYllgWWdZbFlp////////WXhZgVmdT15Pq1mjWbJZxlnoWdxZjVnZWdpaJVofWhFaHFoJWhpaQFpsWklaNVo2WmJaalqaWrxavlrLWsJavVrj" +
+		"Wtda5lrpWtZa+lr7WwxbC1sWWzJa0FsqWzZbPltDW0VbQFtRW1VbWltbW2VbaVtwW3NbdVt4ZYhbeluA//9bg1umW7hbw1vHW8lb1FvQW+Rb5lviW95b5VvrW/Bb9lvzXAVcB1wIXA1cE1wgXCJcKFw4XDlcQVxGXE5cU1xQXE9bcVxsXG5OYlx2XHlcjFyRXJRZm1yr" +
+		"XLtctly8XLdcxVy+XMdc2VzpXP1c+lztXYxc6l0LXRVdF11cXR9dG10RXRRdIl0aXRldGF1MXVJdTl1LXWxdc112XYddhF2CXaJdnV2sXa5dvV2QXbddvF3JXc1d013SXdZd213rXfJd9V4LXhpeGV4RXhteNl43XkReQ15AXk5eV15UXl9eYl5kXkdedV52XnqevF5/" +
+		"XqBewV7CXshe0F7P////////XtZe417dXtpe217iXuFe6F7pXuxe8V7zXvBe9F74Xv5fA18JX11fXF8LXxFfFl8pXy1fOF9BX0hfTF9OXy9fUV9WX1dfWV9hX21fc193X4Nfgl9/X4pfiF+RX4dfnl+ZX5hfoF+oX61fvF/WX/tf5F/4X/Ff3WCzX/9gIWBg//9gGWAQ" +
+		"YClgDmAxYBtgFWArYCZgD2A6YFpgQWBqYHdgX2BKYEZgTWBjYENgZGBCYGxga2BZYIFgjWDnYINgmmCEYJtglmCXYJJgp2CLYOFguGDgYNNgtF/wYL1gxmC1YNhhTWEVYQZg9mD3YQBg9GD6YQNhIWD7YPFhDWEOYUdhPmEoYSdhSmE/YTxhLGE0YT1hQmFEYXNhd2FY" +
+		"YVlhWmFrYXRhb2FlYXFhX2FdYVNhdWGZYZZhh2GsYZRhmmGKYZFhq2GuYcxhymHJYfdhyGHDYcZhumHLf3lhzWHmYeNh9mH6YfRh/2H9Yfxh/mIAYghiCWINYgxiFGIb////////Yh5iIWIqYi5iMGIyYjNiQWJOYl5iY2JbYmBiaGJ8YoJiiWJ+YpJik2KWYtRig2KU" +
+		"Ytdi0WK7Ys9i/2LGZNRiyGLcYsxiymLCYsdim2LJYwxi7mLxYydjAmMIYu9i9WNQYz5jTWQcY09jlmOOY4Bjq2N2Y6Njj2OJY59jtWNr//9jaWO+Y+ljwGPGY+NjyWPSY/ZjxGQWZDRkBmQTZCZkNmUdZBdkKGQPZGdkb2R2ZE5lKmSVZJNkpWSpZIhkvGTaZNJkxWTH" +
+		"ZLtk2GTCZPFk54IJZOBk4WKsZONk72UsZPZk9GTyZPplAGT9ZRhlHGUFZSRlI2UrZTRlNWU3ZTZlOHVLZUhlVmVVZU1lWGVeZV1lcmV4ZYJlg4uKZZtln2WrZbdlw2XGZcFlxGXMZdJl22XZZeBl4WXxZ3JmCmYDZftnc2Y1ZjZmNGYcZk9mRGZJZkFmXmZdZmRmZ2Zo" +
+		"Zl9mYmZwZoNmiGaOZolmhGaYZp1mwWa5Zslmvma8////////ZsRmuGbWZtpm4GY/ZuZm6WbwZvVm92cPZxZnHmcmZyeXOGcuZz9nNmdBZzhnN2dGZ15nYGdZZ2NnZGeJZ3BnqWd8Z2pnjGeLZ6ZnoWeFZ7dn72e0Z+xns2fpZ7hn5GfeZ91n4mfuZ7lnzmfGZ+dqnGge" +
+		"aEZoKWhAaE1oMmhO//9os2graFloY2h3aH9on2iPaK1olGidaJtog2quaLlodGi1aKBoumkPaI1ofmkBaMppCGjYaSJpJmjhaQxozWjUaOdo1Wk2aRJpBGjXaONpJWj5aOBo72koaSppGmkjaSFoxml5aXdpXGl4aWtpVGl+aW5pOWl0aT1pWWkwaWFpXmldaYFpammy" +
+		"aa5p0Gm/acFp02m+ac5b6GnKad1pu2nDaadqLmmRaaBpnGmVabRp3mnoagJqG2n/awpp+WnyaedqBWmxah5p7WoUaetqCmoSasFqI2oTakRqDGpyajZqeGpHamJqWWpmakhqOGoiapBqjWqgaoRqomqj////////apeGF2q7asNqwmq4arNqrGreatFq32qqatpq6mr7" +
+		"awWGFmr6axJrFpsxax9rOGs3dtxrOZjua0drQ2tJa1BrWWtUa1trX2tha3hreWt/a4BrhGuDa41rmGuVa55rpGuqa6trr2uya7Frs2u3a7xrxmvLa9Nr32vsa+tr82vv//+evmwIbBNsFGwbbCRsI2xebFVsYmxqbIJsjWyabIFsm2x+bGhsc2ySbJBsxGzxbNNsvWzX" +
+		"bMVs3WyubLFsvmy6bNts72zZbOptH4hNbTZtK209bThtGW01bTNtEm0MbWNtk21kbVpteW1ZbY5tlW/kbYVt+W4VbgpttW3HbeZtuG3Gbext3m3Mbeht0m3Fbfpt2W3kbdVt6m3ubi1ubm4ubhlucm5fbj5uI25rbitudm5Nbh9uQ246bk5uJG7/bh1uOG6CbqpumG7J" +
+		"brdu0269bq9uxG6ybtRu1W6PbqVuwm6fb0FvEXBMbuxu+G7+bz9u8m8xbu9vMm7M////////bz5vE273b4Zvem94b4FvgG9vb1tv829tb4JvfG9Yb45vkW/Cb2Zvs2+jb6FvpG+5b8Zvqm/fb9Vv7G/Ub9hv8W/ub9twCXALb/pwEXABcA9v/nAbcBpvdHAdcBhwH3Aw" +
+		"cD5wMnBRcGNwmXCScK9w8XCscLhws3CucN9wy3Dd//9w2XEJcP1xHHEZcWVxVXGIcWZxYnFMcVZxbHGPcftxhHGVcahxrHHXcblxvnHScclx1HHOceBx7HHncfVx/HH5cf9yDXIQchtyKHItcixyMHIycjtyPHI/ckByRnJLclhydHJ+coJygXKHcpJylnKicqdyuXKy" +
+		"csNyxnLEcs5y0nLicuBy4XL5cvdQD3MXcwpzHHMWcx1zNHMvcylzJXM+c05zT57Yc1dzanNoc3BzeHN1c3tzenPIc7NzznO7c8Bz5XPuc950onQFdG90JXP4dDJ0OnRVdD90X3RZdEF0XHRpdHB0Y3RqdHZ0fnSLdJ50p3TKdM901HPx////////dOB043TndOl07nTy" +
+		"dPB08XT4dPd1BHUDdQV1DHUOdQ11FXUTdR51JnUsdTx1RHVNdUp1SXVbdUZ1WnVpdWR1Z3VrdW11eHV2dYZ1h3V0dYp1iXWCdZR1mnWddaV1o3XCdbN1w3W1db11uHW8dbF1zXXKddJ12XXjdd51/nX///91/HYBdfB1+nXydfN2C3YNdgl2H3YndiB2IXYidiR2NHYw" +
+		"djt2R3ZIdkZ2XHZYdmF2YnZodml2anZndmx2cHZydnZ2eHZ8doB2g3aIdot2jnaWdpN2mXaadrB2tHa4drl2unbCds121nbSdt524Xbldud26oYvdvt3CHcHdwR3KXckdx53JXcmdxt3N3c4d0d3Wndod2t3W3dld393fnd5d453i3eRd6B3nnewd7Z3uXe/d7x3vXe7" +
+		"d8d3zXfXd9p33Hfjd+53/HgMeBJ5JnggeSp4RXiOeHR4hnh8eJp4jHijeLV4qniveNF4xnjLeNR4vni8eMV4ynjs////////eOd42nj9ePR5B3kSeRF5GXkseSt5QHlgeVd5X3laeVV5U3l6eX95inmdeaefS3mqea55s3m5ebp5yXnVeed57HnheeN6CHoNehh6GXog" +
+		"eh95gHoxejt6Pno3ekN6V3pJemF6Ynppn516cHp5en16iHqXepV6mHqWeql6yHqw//96tnrFesR6v5CDesd6ynrNes961XrTetl62nrdeuF64nrmeu168HsCew97CnsGezN7GHsZex57NXsoezZ7UHt6ewR7TXsLe0x7RXt1e2V7dHtne3B7cXtse257nXuYe597jXuc" +
+		"e5p7i3uSe497XXuZe8t7wXvMe897tHvGe9176XwRfBR75nvlfGB8AHwHfBN783v3fBd8DXv2fCN8J3wqfB98N3wrfD18THxDfFR8T3xAfFB8WHxffGR8VnxlfGx8dXyDfJB8pHytfKJ8q3yhfKh8s3yyfLF8rny5fL18wHzFfMJ82HzSfNx84ps7fO988nz0fPZ8+n0G" +
+		"////////fQJ9HH0VfQp9RX1LfS59Mn0/fTV9Rn1zfVZ9Tn1yfWh9bn1PfWN9k32JfVt9j319fZt9un2ufaN9tX3Hfb19q349faJ9r33cfbh9n32wfdh93X3kfd59+33yfeF+BX4KfiN+IX4SfjF+H34Jfgt+In5GfmZ+O341fjl+Q343//9+Mn46fmd+XX5Wfl5+WX5a" +
+		"fnl+an5pfnx+e36DfdV+fY+ufn9+iH6Jfox+kn6QfpN+lH6Wfo5+m36cfzh/On9Ff0x/TX9Of1B/UX9Vf1R/WH9ff2B/aH9pf2d/eH+Cf4Z/g3+If4d/jH+Uf55/nX+af6N/r3+yf7l/rn+2f7iLcX/Ff8Z/yn/Vf9R/4X/mf+l/83/5mNyABoAEgAuAEoAYgBmAHIAh" +
+		"gCiAP4A7gEqARoBSgFiAWoBfgGKAaIBzgHKAcIB2gHmAfYB/gISAhoCFgJuAk4CagK1RkICsgNuA5YDZgN2AxIDagNaBCYDvgPGBG4EpgSOBL4FL////////louBRoE+gVOBUYD8gXGBboFlgWaBdIGDgYiBioGAgYKBoIGVgaSBo4FfgZOBqYGwgbWBvoG4gb2BwIHC" +
+		"gbqByYHNgdGB2YHYgciB2oHfgeCB54H6gfuB/oIBggKCBYIHggqCDYIQghaCKYIrgjiCM4JAglmCWIJdglqCX4Jk//+CYoJogmqCa4IugnGCd4J4gn6CjYKSgquCn4K7gqyC4YLjgt+C0oL0gvOC+oOTgwOC+4L5gt6DBoLcgwmC2YM1gzSDFoMygzGDQIM5g1CDRYMv" +
+		"gyuDF4MYg4WDmoOqg5+DooOWgyODjoOHg4qDfIO1g3ODdYOgg4mDqIP0hBOD64POg/2EA4PYhAuDwYP3hAeD4IPyhA2EIoQgg72EOIUGg/uEbYQqhDyFWoSEhHeEa4SthG6EgoRphEaELIRvhHmENYTKhGKEuYS/hJ+E2YTNhLuE2oTQhMGExoTWhKGFIYT/hPSFF4UY" +
+		"hSyFH4UVhRSE/IVAhWOFWIVI////////hUGGAoVLhVWFgIWkhYiFkYWKhaiFbYWUhZuF6oWHhZyFd4V+hZCFyYW6hc+FuYXQhdWF3YXlhdyF+YYKhhOGC4X+hfqGBoYihhqGMIY/hk1OVYZUhl+GZ4ZxhpOGo4aphqqGi4aMhraGr4bEhsaGsIbJiCOGq4bUht6G6Ybs" +
+		"//+G34bbhu+HEocGhwiHAIcDhvuHEYcJhw2G+YcKhzSHP4c3hzuHJYcphxqHYIdfh3iHTIdOh3SHV4doh26HWYdTh2OHaogFh6KHn4eCh6+Hy4e9h8CH0JbWh6uHxIezh8eHxoe7h++H8ofgiA+IDYf+h/aH94gOh9KIEYgWiBWIIoghiDGINog5iCeIO4hEiEKIUohZ" +
+		"iF6IYohriIGIfoieiHWIfYi1iHKIgoiXiJKIroiZiKKIjYikiLCIv4ixiMOIxIjUiNiI2YjdiPmJAoj8iPSI6IjyiQSJDIkKiROJQ4keiSWJKokriUGJRIk7iTaJOIlMiR2JYIle////////iWaJZIltiWqJb4l0iXeJfomDiYiJiomTiZiJoYmpiaaJrImvibKJuom9" +
+		"ib+JwInaidyJ3YnnifSJ+IoDihaKEIoMihuKHYolijaKQYpbilKKRopIinyKbYpsimKKhYqCioSKqIqhipGKpYqmipqKo4rEis2KworaiuuK84rn//+K5IrxixSK4IriiveK3orbiwyLB4saiuGLFosQixeLIIszl6uLJosriz6LKItBi0yLT4tOi0mLVotbi1qLa4tf" +
+		"i2yLb4t0i32LgIuMi46LkouTi5aLmYuajDqMQYw/jEiMTIxOjFCMVYxijGyMeIx6jIKMiYyFjIqMjYyOjJSMfIyYYh2MrYyqjL2MsoyzjK6MtozIjMGM5IzjjNqM/Yz6jPuNBI0FjQqNB40PjQ2NEJ9OjROMzY0UjRaNZ41tjXGNc42BjZmNwo2+jbqNz43ajdaNzI3b" +
+		"jcuN6o3rjd+N4438jgiOCY3/jh2OHo4Qjh+OQo41jjCONI5K////////jkeOSY5MjlCOSI5ZjmSOYI4qjmOOVY52jnKOfI6BjoeOhY6EjouOio6TjpGOlI6ZjqqOoY6sjrCOxo6xjr6OxY7IjsuO247jjvyO+47rjv6PCo8FjxWPEo8ZjxOPHI8fjxuPDI8mjzOPO485" +
+		"j0WPQo8+j0yPSY9Gj06PV49c//+PYo9jj2SPnI+fj6OPrY+vj7eP2o/lj+KP6o/vkIeP9JAFj/mP+pARkBWQIZANkB6QFpALkCeQNpA1kDmP+JBPkFCQUZBSkA6QSZA+kFaQWJBekGiQb5B2lqiQcpCCkH2QgZCAkIqQiZCPkKiQr5CxkLWQ4pDkYkiQ25ECkRKRGZEy" +
+		"kTCRSpFWkViRY5FlkWmRc5FykYuRiZGCkaKRq5GvkaqRtZG0kbqRwJHBkcmRy5HQkdaR35HhkduR/JH1kfaSHpH/khSSLJIVkhGSXpJXkkWSSZJkkkiSlZI/kkuSUJKckpaSk5KbklqSz5K5kreS6ZMPkvqTRJMu////////kxmTIpMakyOTOpM1kzuTXJNgk3yTbpNW" +
+		"k7CTrJOtk5STuZPWk9eT6JPlk9iTw5Pdk9CTyJPklBqUFJQTlAOUB5QQlDaUK5Q1lCGUOpRBlFKURJRblGCUYpRelGqSKZRwlHWUd5R9lFqUfJR+lIGUf5WClYeVipWUlZaVmJWZ//+VoJWolaeVrZW8lbuVuZW+lcpv9pXDlc2VzJXVldSV1pXcleGV5ZXiliGWKJYu" +
+		"li+WQpZMlk+WS5Z3llyWXpZdll+WZpZylmyWjZaYlpWWl5aqlqeWsZaylrCWtJa2lriWuZbOlsuWyZbNiU2W3JcNltWW+ZcElwaXCJcTlw6XEZcPlxaXGZcklyqXMJc5lz2XPpdEl0aXSJdCl0mXXJdgl2SXZpdoUtKXa5dxl3mXhZd8l4GXepeGl4uXj5eQl5yXqJem" +
+		"l6OXs5e0l8OXxpfIl8uX3Jftn0+X8nrfl/aX9ZgPmAyYOJgkmCGYN5g9mEaYT5hLmGuYb5hw////////mHGYdJhzmKqYr5ixmLaYxJjDmMaY6ZjrmQOZCZkSmRSZGJkhmR2ZHpkkmSCZLJkumT2ZPplCmUmZRZlQmUuZUZlSmUyZVZmXmZiZpZmtma6ZvJnfmduZ3ZnY" +
+		"mdGZ7ZnumfGZ8pn7mfiaAZoPmgWZ4poZmiuaN5pFmkKaQJpD//+aPppVmk2aW5pXml+aYpplmmSaaZprmmqarZqwmryawJrPmtGa05rUmt6a35rimuOa5prvmuua7pr0mvGa95r7mwabGJsamx+bIpsjmyWbJ5somymbKpsumy+bMptEm0ObT5tNm06bUZtYm3Sbk5uD" +
+		"m5GblpuXm5+boJuom7SbwJvKm7mbxpvPm9Gb0pvjm+Kb5JvUm+GcOpvym/Gb8JwVnBScCZwTnAycBpwInBKcCpwEnC6cG5wlnCScIZwwnEecMpxGnD6cWpxgnGecdpx4nOec7JzwnQmdCJzrnQOdBp0qnSadr50jnR+dRJ0VnRKdQZ0/nT6dRp1I////////nV2dXp1k" +
+		"nVGdUJ1ZnXKdiZ2Hnaudb516nZqdpJ2pnbKdxJ3BnbuduJ26ncadz53Cndmd0534nead7Z3vnf2eGp4bnh6edZ55nn2egZ6InouejJ6SnpWekZ6dnqWeqZ64nqqerZdhnsyezp7PntCe1J7cnt6e3Z7gnuWe6J7v//+e9J72nvee+Z77nvye/Z8Hnwh2t58VnyGfLJ8+" +
+		"n0qfUp9Un2OfX59gn2GfZp9nn2yfap93n3Kfdp+Vn5yfoFgvaceQWXRkUdxxmf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" +
+		"/////////////////////////////////////////////w==";
+	
+	
+	private static short[] UNICODE_TO_QR_KANJI = new short[65536];
+	
+	static {  // Unpack the Shift JIS table into a more computation-friendly form
+		Arrays.fill(UNICODE_TO_QR_KANJI, (short)-1);
+		byte[] bytes = Base64.getDecoder().decode(PACKED_QR_KANJI_TO_UNICODE);
+		for (int i = 0; i < bytes.length; i += 2) {
+			int j = ((bytes[i] & 0xFF) << 8) | (bytes[i + 1] & 0xFF);
+			if (j == 0xFFFF)
+				continue;
+			if (UNICODE_TO_QR_KANJI[j] != -1)
+				throw new AssertionError();
+			UNICODE_TO_QR_KANJI[j] = (short)(i / 2);
+		}
+	}
+	
+}
diff --git a/src/third_party/QR-Code-generator/javascript/qrcodegen-demo.js b/src/third_party/QR-Code-generator/javascript/qrcodegen-demo.js
new file mode 100644
index 0000000..e75e689
--- /dev/null
+++ b/src/third_party/QR-Code-generator/javascript/qrcodegen-demo.js
@@ -0,0 +1,154 @@
+/* 
+ * QR Code generator demo (JavaScript)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+"use strict";
+
+
+function redrawQrCode() {
+	// Show/hide rows based on bitmap/vector image output
+	var bitmapOutput = document.getElementById("output-format-bitmap").checked;
+	var scaleRow = document.getElementById("scale-row");
+	var svgXmlRow = document.getElementById("svg-xml-row");
+	if (bitmapOutput) {
+		scaleRow.style.removeProperty("display");
+		svgXmlRow.style.display = "none";
+	} else {
+		scaleRow.style.display = "none";
+		svgXmlRow.style.removeProperty("display");
+	}
+	var svgXml = document.getElementById("svg-xml-output");
+	svgXml.value = "";
+	
+	// Reset output images in case of early termination
+	var canvas = document.getElementById("qrcode-canvas");
+	var svg = document.getElementById("qrcode-svg");
+	canvas.style.display = "none";
+	svg.style.display = "none";
+	
+	// Returns a QrCode.Ecc object based on the radio buttons in the HTML form.
+	function getInputErrorCorrectionLevel() {
+		if (document.getElementById("errcorlvl-medium").checked)
+			return qrcodegen.QrCode.Ecc.MEDIUM;
+		else if (document.getElementById("errcorlvl-quartile").checked)
+			return qrcodegen.QrCode.Ecc.QUARTILE;
+		else if (document.getElementById("errcorlvl-high").checked)
+			return qrcodegen.QrCode.Ecc.HIGH;
+		else  // In case no radio button is depressed
+			return qrcodegen.QrCode.Ecc.LOW;
+	}
+	
+	// Get form inputs and compute QR Code
+	var ecl = getInputErrorCorrectionLevel();
+	var text = document.getElementById("text-input").value;
+	var segs = qrcodegen.QrSegment.makeSegments(text);
+	var minVer = parseInt(document.getElementById("version-min-input").value, 10);
+	var maxVer = parseInt(document.getElementById("version-max-input").value, 10);
+	var mask = parseInt(document.getElementById("mask-input").value, 10);
+	var boostEcc = document.getElementById("boost-ecc-input").checked;
+	var qr = qrcodegen.QrCode.encodeSegments(segs, ecl, minVer, maxVer, mask, boostEcc);
+	
+	// Draw image output
+	var border = parseInt(document.getElementById("border-input").value, 10);
+	if (border < 0 || border > 100)
+		return;
+	if (bitmapOutput) {
+		var scale = parseInt(document.getElementById("scale-input").value, 10);
+		if (scale <= 0 || scale > 30)
+			return;
+		qr.drawCanvas(scale, border, canvas);
+		canvas.style.removeProperty("display");
+	} else {
+		var code = qr.toSvgString(border);
+		svg.setAttribute("viewBox", / viewBox="([^"]*)"/.exec(code)[1]);
+		svg.querySelector("path").setAttribute("d", / d="([^"]*)"/.exec(code)[1]);
+		svg.style.removeProperty("display");
+		svgXml.value = qr.toSvgString(border);
+	}
+	
+	
+	// Returns a string to describe the given list of segments.
+	function describeSegments(segs) {
+		if (segs.length == 0)
+			return "none";
+		else if (segs.length == 1) {
+			var mode = segs[0].mode;
+			var Mode = qrcodegen.QrSegment.Mode;
+			if (mode == Mode.NUMERIC     )  return "numeric";
+			if (mode == Mode.ALPHANUMERIC)  return "alphanumeric";
+			if (mode == Mode.BYTE        )  return "byte";
+			if (mode == Mode.KANJI       )  return "kanji";
+			return "unknown";
+		} else
+			return "multiple";
+	}
+	
+	// Returns the number of Unicode code points in the given UTF-16 string.
+	function countUnicodeChars(str) {
+		var result = 0;
+		for (var i = 0; i < str.length; i++, result++) {
+			var c = str.charCodeAt(i);
+			if (c < 0xD800 || c >= 0xE000)
+				continue;
+			else if (0xD800 <= c && c < 0xDC00) {  // High surrogate
+				i++;
+				var d = str.charCodeAt(i);
+				if (0xDC00 <= d && d < 0xE000)  // Low surrogate
+					continue;
+			}
+			throw "Invalid UTF-16 string";
+		}
+		return result;
+	}
+	
+	// Show the QR Code symbol's statistics as a string
+	var stats = "QR Code version = " + qr.version + ", ";
+	stats += "mask pattern = " + qr.mask + ", ";
+	stats += "character count = " + countUnicodeChars(text) + ",\n";
+	stats += "encoding mode = " + describeSegments(segs) + ", ";
+	stats += "error correction = level " + "LMQH".charAt(qr.errorCorrectionLevel.ordinal) + ", ";
+	stats += "data bits = " + qrcodegen.QrSegment.getTotalBits(segs, qr.version) + ".";
+	var elem = document.getElementById("statistics-output");
+	while (elem.firstChild != null)
+		elem.removeChild(elem.firstChild);
+	elem.appendChild(document.createTextNode(stats));
+}
+
+
+function handleVersionMinMax(which) {
+	var minElem = document.getElementById("version-min-input");
+	var maxElem = document.getElementById("version-max-input");
+	var minVal = parseInt(minElem.value, 10);
+	var maxVal = parseInt(maxElem.value, 10);
+	minVal = Math.max(Math.min(minVal, qrcodegen.QrCode.MAX_VERSION), qrcodegen.QrCode.MIN_VERSION);
+	maxVal = Math.max(Math.min(maxVal, qrcodegen.QrCode.MAX_VERSION), qrcodegen.QrCode.MIN_VERSION);
+	if (which == "min" && minVal > maxVal)
+		maxVal = minVal;
+	else if (which == "max" && maxVal < minVal)
+		minVal = maxVal;
+	minElem.value = minVal.toString();
+	maxElem.value = maxVal.toString();
+	redrawQrCode();
+}
+
+
+redrawQrCode();
diff --git a/src/third_party/QR-Code-generator/javascript/qrcodegen-js-demo.html b/src/third_party/QR-Code-generator/javascript/qrcodegen-js-demo.html
new file mode 100644
index 0000000..0b1ba15
--- /dev/null
+++ b/src/third_party/QR-Code-generator/javascript/qrcodegen-js-demo.html
@@ -0,0 +1,121 @@
+<!--
+  - QR Code generator demo (HTML+JavaScript)
+  - 
+  - Copyright (c) Project Nayuki. (MIT License)
+  - https://www.nayuki.io/page/qr-code-generator-library
+  - 
+  - Permission is hereby granted, free of charge, to any person obtaining a copy of
+  - this software and associated documentation files (the "Software"), to deal in
+  - the Software without restriction, including without limitation the rights to
+  - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+  - the Software, and to permit persons to whom the Software is furnished to do so,
+  - subject to the following conditions:
+  - * The above copyright notice and this permission notice shall be included in
+  -   all copies or substantial portions of the Software.
+  - * The Software is provided "as is", without warranty of any kind, express or
+  -   implied, including but not limited to the warranties of merchantability,
+  -   fitness for a particular purpose and noninfringement. In no event shall the
+  -   authors or copyright holders be liable for any claim, damages or other
+  -   liability, whether in an action of contract, tort or otherwise, arising from,
+  -   out of or in connection with the Software or the use or other dealings in the
+  -   Software.
+  -->
+<!DOCTYPE html>
+<html>
+<head>
+	<meta charset="UTF-8">
+	<title>QR Code generator library demo (JavaScript)</title>
+	<style type="text/css">
+	html {
+		font-family: sans-serif;
+	}
+	td {
+		vertical-align: top;
+		padding-top: 0.2em;
+		padding-bottom: 0.2em;
+	}
+	td:first-child {
+		white-space: pre;
+	}
+	input[type=radio] + label, input[type=checkbox] + label {
+		margin-left: 0.1em;
+		margin-right: 0.7em;
+	}
+	</style>
+</head>
+
+<body>
+<h1>QR Code generator demo library (JavaScript)</h1>
+<form action="#" method="get" onsubmit="return false;">
+	<table class="noborder" style="width:100%">
+		<tbody>
+			<tr>
+				<td><strong>Text string:</strong></td>
+				<td style="width:100%"><textarea placeholder="Enter your text to be put into the QR Code" id="text-input" style="width:100%; max-width:30em; height:5em; font-family:inherit" oninput="redrawQrCode();"></textarea></td>
+			</tr>
+			<tr>
+				<td><strong>QR Code:</strong></td>
+				<td>
+					<canvas id="qrcode-canvas" style="padding:1em; background-color:#E8E8E8"></canvas>
+					<svg id="qrcode-svg" style="width:30em; height:30em; padding:1em; background-color:#E8E8E8">
+						<rect width="100%" height="100%" fill="#FFFFFF" stroke-width="0"></rect>
+						<path d="" fill="#000000" stroke-width="0"></path>
+					</svg>
+				</td>
+			</tr>
+			<tr>
+				<td><strong>Error correction:</strong></td>
+				<td>
+					<input type="radio" name="errcorlvl" id="errcorlvl-low" onchange="redrawQrCode();" checked="checked"><label for="errcorlvl-low">Low</label>
+					<input type="radio" name="errcorlvl" id="errcorlvl-medium" onchange="redrawQrCode();"><label for="errcorlvl-medium">Medium</label>
+					<input type="radio" name="errcorlvl" id="errcorlvl-quartile" onchange="redrawQrCode();"><label for="errcorlvl-quartile">Quartile</label>
+					<input type="radio" name="errcorlvl" id="errcorlvl-high" onchange="redrawQrCode();"><label for="errcorlvl-high">High</label>
+				</td>
+			</tr>
+			<tr>
+				<td>Output format:</td>
+				<td>
+					<input type="radio" name="output-format" id="output-format-bitmap" onchange="redrawQrCode();" checked="checked"><label for="output-format-bitmap">Bitmap</label>
+					<input type="radio" name="output-format" id="output-format-vector" onchange="redrawQrCode();"><label for="output-format-vector">Vector</label>
+				</td>
+			</tr>
+			<tr>
+				<td>Border:</td>
+				<td><input type="number" value="4" min="0" max="100" step="1" id="border-input" style="width:4em" oninput="redrawQrCode();"> modules</td>
+			</tr>
+			<tr id="scale-row">
+				<td>Scale:</td>
+				<td><input type="number" value="8" min="1" max="30" step="1" id="scale-input" style="width:4em" oninput="redrawQrCode();"> pixels per module</td>
+			</tr>
+			<tr>
+				<td>Version range:</td>
+				<td>Minimum = <input type="number" value="1" min="1" max="40" step="1" id="version-min-input" style="width:4em" oninput="handleVersionMinMax('min');">, maximum = <input type="number" value="40" min="1" max="40" step="1" id="version-max-input" style="width:4em" oninput="handleVersionMinMax('max');"></td>
+			</tr>
+			<tr>
+				<td>Mask pattern:</td>
+				<td><input type="number" value="-1" min="-1" max="7" step="1" id="mask-input" style="width:4em" oninput="redrawQrCode();"> (−1 for automatic, 0 to 7 for manual)</td>
+			</tr>
+			<tr>
+				<td>Boost ECC:</td>
+				<td><input type="checkbox" checked="checked" id="boost-ecc-input" onchange="redrawQrCode();"><label for="boost-ecc-input">Increase <abbr title="error-correcting code">ECC</abbr> level within same version</label></td>
+			</tr>
+			<tr>
+				<td>Statistics:</td>
+				<td id="statistics-output" style="white-space:pre"></td>
+			</tr>
+			<tr id="svg-xml-row">
+				<td>SVG XML code:</td>
+				<td>
+					<textarea id="svg-xml-output" readonly="readonly" style="width:100%; max-width:50em; height:15em; font-family:monospace"></textarea>
+				</td>
+			</tr>
+		</tbody>
+	</table>
+</form>
+<script type="application/javascript" src="qrcodegen.js"></script>
+<script type="application/javascript" src="qrcodegen-demo.js"></script>
+
+<hr>
+<p>Copyright © Project Nayuki – <a href="https://www.nayuki.io/page/qr-code-generator-library">https://www.nayuki.io/page/qr-code-generator-library</a></p>
+</body>
+</html>
diff --git a/src/third_party/QR-Code-generator/javascript/qrcodegen.js b/src/third_party/QR-Code-generator/javascript/qrcodegen.js
new file mode 100644
index 0000000..19ae3a8
--- /dev/null
+++ b/src/third_party/QR-Code-generator/javascript/qrcodegen.js
@@ -0,0 +1,1004 @@
+/* 
+ * QR Code generator library (JavaScript)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+"use strict";
+
+
+/* 
+ * Module "qrcodegen", public members:
+ * - Class QrCode:
+ *   - Function encodeText(str text, QrCode.Ecc ecl) -> QrCode
+ *   - Function encodeBinary(list<byte> data, QrCode.Ecc ecl) -> QrCode
+ *   - Function encodeSegments(list<QrSegment> segs, QrCode.Ecc ecl,
+ *         int minVersion=1, int maxVersion=40, mask=-1, boostEcl=true) -> QrCode
+ *   - Constants int MIN_VERSION, MAX_VERSION
+ *   - Constructor QrCode(list<int> datacodewords, int mask, int version, QrCode.Ecc ecl)
+ *   - Fields int version, size, mask
+ *   - Field QrCode.Ecc errorCorrectionLevel
+ *   - Method getModule(int x, int y) -> bool
+ *   - Method drawCanvas(int scale, int border, HTMLCanvasElement canvas) -> void
+ *   - Method toSvgString(int border) -> str
+ *   - Enum Ecc:
+ *     - Constants LOW, MEDIUM, QUARTILE, HIGH
+ *     - Field int ordinal
+ * - Class QrSegment:
+ *   - Function makeBytes(list<int> data) -> QrSegment
+ *   - Function makeNumeric(str data) -> QrSegment
+ *   - Function makeAlphanumeric(str data) -> QrSegment
+ *   - Function makeSegments(str text) -> list<QrSegment>
+ *   - Function makeEci(int assignVal) -> QrSegment
+ *   - Constructor QrSegment(QrSegment.Mode mode, int numChars, list<int> bitData)
+ *   - Field QrSegment.Mode mode
+ *   - Field int numChars
+ *   - Method getBits() -> list<int>
+ *   - Constants RegExp NUMERIC_REGEX, ALPHANUMERIC_REGEX
+ *   - Enum Mode:
+ *     - Constants NUMERIC, ALPHANUMERIC, BYTE, KANJI, ECI
+ */
+var qrcodegen = new function() {
+	
+	/*---- QR Code symbol class ----*/
+	
+	/* 
+	 * A class that represents an immutable square grid of black and white cells for a QR Code symbol,
+	 * with associated static functions to create a QR Code from user-supplied textual or binary data.
+	 * This class covers the QR Code model 2 specification, supporting all versions (sizes)
+	 * from 1 to 40, all 4 error correction levels.
+	 * This constructor creates a new QR Code symbol with the given version number, error correction level, binary data array,
+	 * and mask number. mask = -1 is for automatic choice, or 0 to 7 for fixed choice. This is a cumbersome low-level constructor
+	 * that should not be invoked directly by the user. To go one level up, see the QrCode.encodeSegments() function.
+	 */
+	this.QrCode = function(datacodewords, mask, version, errCorLvl) {
+		
+		/*---- Constructor ----*/
+		
+		// Check arguments and handle simple scalar fields
+		if (mask < -1 || mask > 7)
+			throw "Mask value out of range";
+		if (version < MIN_VERSION || version > MAX_VERSION)
+			throw "Version value out of range";
+		var size = version * 4 + 17;
+		
+		// Initialize both grids to be size*size arrays of Boolean false
+		var row = [];
+		for (var i = 0; i < size; i++)
+			row.push(false);
+		var modules = [];
+		var isFunction = [];
+		for (var i = 0; i < size; i++) {
+			modules.push(row.slice());
+			isFunction.push(row.slice());
+		}
+		
+		// Handle grid fields, draw function patterns, draw all codewords
+		drawFunctionPatterns();
+		var allCodewords = appendErrorCorrection(datacodewords);
+		drawCodewords(allCodewords);
+		
+		// Handle masking
+		if (mask == -1) {  // Automatically choose best mask
+			var minPenalty = Infinity;
+			for (var i = 0; i < 8; i++) {
+				drawFormatBits(i);
+				applyMask(i);
+				var penalty = getPenaltyScore();
+				if (penalty < minPenalty) {
+					mask = i;
+					minPenalty = penalty;
+				}
+				applyMask(i);  // Undoes the mask due to XOR
+			}
+		}
+		if (mask < 0 || mask > 7)
+			throw "Assertion error";
+		drawFormatBits(mask);  // Overwrite old format bits
+		applyMask(mask);  // Apply the final choice of mask
+		
+		
+		/*---- Read-only instance properties ----*/
+		
+		// This QR Code symbol's version number, which is always between 1 and 40 (inclusive).
+		Object.defineProperty(this, "version", {value:version});
+		
+		// The width and height of this QR Code symbol, measured in modules.
+		// Always equal to version * 4 + 17, in the range 21 to 177.
+		Object.defineProperty(this, "size", {value:size});
+		
+		// The error correction level used in this QR Code symbol.
+		Object.defineProperty(this, "errorCorrectionLevel", {value:errCorLvl});
+		
+		// The mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer).
+		// Note that even if the constructor was called with automatic masking requested
+		// (mask = -1), the resulting object will still have a mask value between 0 and 7.
+		Object.defineProperty(this, "mask", {value:mask});
+		
+		
+		/*---- Accessor methods ----*/
+		
+		// (Public) Returns the color of the module (pixel) at the given coordinates, which is either
+		// false for white or true for black. The top left corner has the coordinates (x=0, y=0).
+		// If the given coordinates are out of bounds, then false (white) is returned.
+		this.getModule = function(x, y) {
+			return 0 <= x && x < size && 0 <= y && y < size && modules[y][x];
+		};
+		
+		// (Package-private) Tests whether the module at the given coordinates is a function module (true) or not (false).
+		// The top left corner has the coordinates (x=0, y=0). If the given coordinates are out of bounds, then false is returned.
+		// The JavaScript version of this library has this method because it is impossible to access private variables of another object.
+		this.isFunctionModule = function(x, y) {
+			if (0 <= x && x < size && 0 <= y && y < size)
+				return isFunction[y][x];
+			else
+				return false;  // Infinite border
+		};
+		
+		
+		/*---- Public instance methods ----*/
+		
+		// Draws this QR Code symbol with the given module scale and number of modules onto the given HTML canvas element.
+		// The canvas will be resized to a width and height of (this.size + border * 2) * scale. The painted image will be purely
+		// black and white with no transparent regions. The scale must be a positive integer, and the border must be a non-negative integer.
+		this.drawCanvas = function(scale, border, canvas) {
+			if (scale <= 0 || border < 0)
+				throw "Value out of range";
+			var width = (size + border * 2) * scale;
+			canvas.width = width;
+			canvas.height = width;
+			var ctx = canvas.getContext("2d");
+			for (var y = -border; y < size + border; y++) {
+				for (var x = -border; x < size + border; x++) {
+					ctx.fillStyle = this.getModule(x, y) ? "#000000" : "#FFFFFF";
+					ctx.fillRect((x + border) * scale, (y + border) * scale, scale, scale);
+				}
+			}
+		};
+		
+		// Based on the given number of border modules to add as padding, this returns a
+		// string whose contents represents an SVG XML file that depicts this QR Code symbol.
+		// Note that Unix newlines (\n) are always used, regardless of the platform.
+		this.toSvgString = function(border) {
+			if (border < 0)
+				throw "Border must be non-negative";
+			var result = '<?xml version="1.0" encoding="UTF-8"?>\n';
+			result += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n';
+			result += '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 ' +
+				(size + border * 2) + ' ' + (size + border * 2) + '" stroke="none">\n';
+			result += '\t<rect width="100%" height="100%" fill="#FFFFFF"/>\n';
+			result += '\t<path d="';
+			var head = true;
+			for (var y = -border; y < size + border; y++) {
+				for (var x = -border; x < size + border; x++) {
+					if (this.getModule(x, y)) {
+						if (head)
+							head = false;
+						else
+							result += " ";
+						result += "M" + (x + border) + "," + (y + border) + "h1v1h-1z";
+					}
+				}
+			}
+			result += '" fill="#000000"/>\n';
+			result += '</svg>\n';
+			return result;
+		};
+		
+		
+		/*---- Private helper methods for constructor: Drawing function modules ----*/
+		
+		function drawFunctionPatterns() {
+			// Draw horizontal and vertical timing patterns
+			for (var i = 0; i < size; i++) {
+				setFunctionModule(6, i, i % 2 == 0);
+				setFunctionModule(i, 6, i % 2 == 0);
+			}
+			
+			// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
+			drawFinderPattern(3, 3);
+			drawFinderPattern(size - 4, 3);
+			drawFinderPattern(3, size - 4);
+			
+			// Draw numerous alignment patterns
+			var alignPatPos = QrCode.getAlignmentPatternPositions(version);
+			var numAlign = alignPatPos.length;
+			for (var i = 0; i < numAlign; i++) {
+				for (var j = 0; j < numAlign; j++) {
+					if (i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0)
+						continue;  // Skip the three finder corners
+					else
+						drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);
+				}
+			}
+			
+			// Draw configuration data
+			drawFormatBits(0);  // Dummy mask value; overwritten later in the constructor
+			drawVersion();
+		}
+		
+		
+		// Draws two copies of the format bits (with its own error correction code)
+		// based on the given mask and this object's error correction level field.
+		function drawFormatBits(mask) {
+			// Calculate error correction code and pack bits
+			var data = errCorLvl.formatBits << 3 | mask;  // errCorrLvl is uint2, mask is uint3
+			var rem = data;
+			for (var i = 0; i < 10; i++)
+				rem = (rem << 1) ^ ((rem >>> 9) * 0x537);
+			data = data << 10 | rem;
+			data ^= 0x5412;  // uint15
+			if (data >>> 15 != 0)
+				throw "Assertion error";
+			
+			// Draw first copy
+			for (var i = 0; i <= 5; i++)
+				setFunctionModule(8, i, ((data >>> i) & 1) != 0);
+			setFunctionModule(8, 7, ((data >>> 6) & 1) != 0);
+			setFunctionModule(8, 8, ((data >>> 7) & 1) != 0);
+			setFunctionModule(7, 8, ((data >>> 8) & 1) != 0);
+			for (var i = 9; i < 15; i++)
+				setFunctionModule(14 - i, 8, ((data >>> i) & 1) != 0);
+			
+			// Draw second copy
+			for (var i = 0; i <= 7; i++)
+				setFunctionModule(size - 1 - i, 8, ((data >>> i) & 1) != 0);
+			for (var i = 8; i < 15; i++)
+				setFunctionModule(8, size - 15 + i, ((data >>> i) & 1) != 0);
+			setFunctionModule(8, size - 8, true);
+		}
+		
+		
+		// Draws two copies of the version bits (with its own error correction code),
+		// based on this object's version field (which only has an effect for 7 <= version <= 40).
+		function drawVersion() {
+			if (version < 7)
+				return;
+			
+			// Calculate error correction code and pack bits
+			var rem = version;  // version is uint6, in the range [7, 40]
+			for (var i = 0; i < 12; i++)
+				rem = (rem << 1) ^ ((rem >>> 11) * 0x1F25);
+			var data = version << 12 | rem;  // uint18
+			if (data >>> 18 != 0)
+				throw "Assertion error";
+			
+			// Draw two copies
+			for (var i = 0; i < 18; i++) {
+				var bit = ((data >>> i) & 1) != 0;
+				var a = size - 11 + i % 3, b = Math.floor(i / 3);
+				setFunctionModule(a, b, bit);
+				setFunctionModule(b, a, bit);
+			}
+		}
+		
+		
+		// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y).
+		function drawFinderPattern(x, y) {
+			for (var i = -4; i <= 4; i++) {
+				for (var j = -4; j <= 4; j++) {
+					var dist = Math.max(Math.abs(i), Math.abs(j));  // Chebyshev/infinity norm
+					var xx = x + j, yy = y + i;
+					if (0 <= xx && xx < size && 0 <= yy && yy < size)
+						setFunctionModule(xx, yy, dist != 2 && dist != 4);
+				}
+			}
+		}
+		
+		
+		// Draws a 5*5 alignment pattern, with the center module at (x, y).
+		function drawAlignmentPattern(x, y) {
+			for (var i = -2; i <= 2; i++) {
+				for (var j = -2; j <= 2; j++)
+					setFunctionModule(x + j, y + i, Math.max(Math.abs(i), Math.abs(j)) != 1);
+			}
+		}
+		
+		
+		// Sets the color of a module and marks it as a function module.
+		// Only used by the constructor. Coordinates must be in range.
+		function setFunctionModule(x, y, isBlack) {
+			modules[y][x] = isBlack;
+			isFunction[y][x] = true;
+		}
+		
+		
+		/*---- Private helper methods for constructor: Codewords and masking ----*/
+		
+		// Returns a new byte string representing the given data with the appropriate error correction
+		// codewords appended to it, based on this object's version and error correction level.
+		function appendErrorCorrection(data) {
+			if (data.length != QrCode.getNumDataCodewords(version, errCorLvl))
+				throw "Invalid argument";
+			
+			// Calculate parameter numbers
+			var numBlocks = QrCode.NUM_ERROR_CORRECTION_BLOCKS[errCorLvl.ordinal][version];
+			var blockEccLen = QrCode.ECC_CODEWORDS_PER_BLOCK[errCorLvl.ordinal][version];
+			var rawCodewords = Math.floor(QrCode.getNumRawDataModules(version) / 8);
+			var numShortBlocks = numBlocks - rawCodewords % numBlocks;
+			var shortBlockLen = Math.floor(rawCodewords / numBlocks);
+			
+			// Split data into blocks and append ECC to each block
+			var blocks = [];
+			var rs = new ReedSolomonGenerator(blockEccLen);
+			for (var i = 0, k = 0; i < numBlocks; i++) {
+				var dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
+				k += dat.length;
+				var ecc = rs.getRemainder(dat);
+				if (i < numShortBlocks)
+					dat.push(0);
+				ecc.forEach(function(b) {
+					dat.push(b);
+				});
+				blocks.push(dat);
+			}
+			
+			// Interleave (not concatenate) the bytes from every block into a single sequence
+			var result = [];
+			for (var i = 0; i < blocks[0].length; i++) {
+				for (var j = 0; j < blocks.length; j++) {
+					// Skip the padding byte in short blocks
+					if (i != shortBlockLen - blockEccLen || j >= numShortBlocks)
+						result.push(blocks[j][i]);
+				}
+			}
+			if (result.length != rawCodewords)
+				throw "Assertion error";
+			return result;
+		}
+		
+		
+		// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
+		// data area of this QR Code symbol. Function modules need to be marked off before this is called.
+		function drawCodewords(data) {
+			if (data.length != Math.floor(QrCode.getNumRawDataModules(version) / 8))
+				throw "Invalid argument";
+			var i = 0;  // Bit index into the data
+			// Do the funny zigzag scan
+			for (var right = size - 1; right >= 1; right -= 2) {  // Index of right column in each column pair
+				if (right == 6)
+					right = 5;
+				for (var vert = 0; vert < size; vert++) {  // Vertical counter
+					for (var j = 0; j < 2; j++) {
+						var x = right - j;  // Actual x coordinate
+						var upward = ((right + 1) & 2) == 0;
+						var y = upward ? size - 1 - vert : vert;  // Actual y coordinate
+						if (!isFunction[y][x] && i < data.length * 8) {
+							modules[y][x] = ((data[i >>> 3] >>> (7 - (i & 7))) & 1) != 0;
+							i++;
+						}
+						// If there are any remainder bits (0 to 7), they are already
+						// set to 0/false/white when the grid of modules was initialized
+					}
+				}
+			}
+			if (i != data.length * 8)
+				throw "Assertion error";
+		}
+		
+		
+		// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
+		// properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
+		// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
+		// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
+		function applyMask(mask) {
+			if (mask < 0 || mask > 7)
+				throw "Mask value out of range";
+			for (var y = 0; y < size; y++) {
+				for (var x = 0; x < size; x++) {
+					var invert;
+					switch (mask) {
+						case 0:  invert = (x + y) % 2 == 0;                                  break;
+						case 1:  invert = y % 2 == 0;                                        break;
+						case 2:  invert = x % 3 == 0;                                        break;
+						case 3:  invert = (x + y) % 3 == 0;                                  break;
+						case 4:  invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;  break;
+						case 5:  invert = x * y % 2 + x * y % 3 == 0;                        break;
+						case 6:  invert = (x * y % 2 + x * y % 3) % 2 == 0;                  break;
+						case 7:  invert = ((x + y) % 2 + x * y % 3) % 2 == 0;                break;
+						default:  throw "Assertion error";
+					}
+					modules[y][x] ^= invert & !isFunction[y][x];
+				}
+			}
+		}
+		
+		
+		// Calculates and returns the penalty score based on state of this QR Code's current modules.
+		// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
+		function getPenaltyScore() {
+			var result = 0;
+			
+			// Adjacent modules in row having same color
+			for (var y = 0; y < size; y++) {
+				for (var x = 0, runX, colorX; x < size; x++) {
+					if (x == 0 || modules[y][x] != colorX) {
+						colorX = modules[y][x];
+						runX = 1;
+					} else {
+						runX++;
+						if (runX == 5)
+							result += QrCode.PENALTY_N1;
+						else if (runX > 5)
+							result++;
+					}
+				}
+			}
+			// Adjacent modules in column having same color
+			for (var x = 0; x < size; x++) {
+				for (var y = 0, runY, colorY; y < size; y++) {
+					if (y == 0 || modules[y][x] != colorY) {
+						colorY = modules[y][x];
+						runY = 1;
+					} else {
+						runY++;
+						if (runY == 5)
+							result += QrCode.PENALTY_N1;
+						else if (runY > 5)
+							result++;
+					}
+				}
+			}
+			
+			// 2*2 blocks of modules having same color
+			for (var y = 0; y < size - 1; y++) {
+				for (var x = 0; x < size - 1; x++) {
+					var   color = modules[y][x];
+					if (  color == modules[y][x + 1] &&
+					      color == modules[y + 1][x] &&
+					      color == modules[y + 1][x + 1])
+						result += QrCode.PENALTY_N2;
+				}
+			}
+			
+			// Finder-like pattern in rows
+			for (var y = 0; y < size; y++) {
+				for (var x = 0, bits = 0; x < size; x++) {
+					bits = ((bits << 1) & 0x7FF) | (modules[y][x] ? 1 : 0);
+					if (x >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
+						result += QrCode.PENALTY_N3;
+				}
+			}
+			// Finder-like pattern in columns
+			for (var x = 0; x < size; x++) {
+				for (var y = 0, bits = 0; y < size; y++) {
+					bits = ((bits << 1) & 0x7FF) | (modules[y][x] ? 1 : 0);
+					if (y >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
+						result += QrCode.PENALTY_N3;
+				}
+			}
+			
+			// Balance of black and white modules
+			var black = 0;
+			modules.forEach(function(row) {
+				row.forEach(function(color) {
+					if (color)
+						black++;
+				});
+			});
+			var total = size * size;
+			// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
+			for (var k = 0; black*20 < (9-k)*total || black*20 > (11+k)*total; k++)
+				result += QrCode.PENALTY_N4;
+			return result;
+		}
+	};
+	
+	
+	/*---- Public static factory functions for QrCode ----*/
+	
+	/* 
+	 * Returns a QR Code symbol representing the specified Unicode text string at the specified error correction level.
+	 * As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer
+	 * Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible
+	 * QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the
+	 * ecl argument if it can be done without increasing the version.
+	 */
+	this.QrCode.encodeText = function(text, ecl) {
+		var segs = qrcodegen.QrSegment.makeSegments(text);
+		return this.encodeSegments(segs, ecl);
+	};
+	
+	
+	/* 
+	 * Returns a QR Code symbol representing the given binary data string at the given error correction level.
+	 * This function always encodes using the binary segment mode, not any text mode. The maximum number of
+	 * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
+	 * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
+	 */
+	this.QrCode.encodeBinary = function(data, ecl) {
+		var seg = qrcodegen.QrSegment.makeBytes(data);
+		return this.encodeSegments([seg], ecl);
+	};
+	
+	
+	/* 
+	 * Returns a QR Code symbol representing the given data segments with the given encoding parameters.
+	 * The smallest possible QR Code version within the given range is automatically chosen for the output.
+	 * This function allows the user to create a custom sequence of segments that switches
+	 * between modes (such as alphanumeric and binary) to encode text more efficiently.
+	 * This function is considered to be lower level than simply encoding text or binary data.
+	 */
+	this.QrCode.encodeSegments = function(segs, ecl, minVersion, maxVersion, mask, boostEcl) {
+		if (minVersion == undefined) minVersion = MIN_VERSION;
+		if (maxVersion == undefined) maxVersion = MAX_VERSION;
+		if (mask == undefined) mask = -1;
+		if (boostEcl == undefined) boostEcl = true;
+		if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
+			throw "Invalid value";
+		
+		// Find the minimal version number to use
+		var version, dataUsedBits;
+		for (version = minVersion; ; version++) {
+			var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;  // Number of data bits available
+			dataUsedBits = qrcodegen.QrSegment.getTotalBits(segs, version);
+			if (dataUsedBits != null && dataUsedBits <= dataCapacityBits)
+				break;  // This version number is found to be suitable
+			if (version >= maxVersion)  // All versions in the range could not fit the given data
+				throw "Data too long";
+		}
+		
+		// Increase the error correction level while the data still fits in the current version number
+		[this.Ecc.MEDIUM, this.Ecc.QUARTILE, this.Ecc.HIGH].forEach(function(newEcl) {
+			if (boostEcl && dataUsedBits <= QrCode.getNumDataCodewords(version, newEcl) * 8)
+				ecl = newEcl;
+		});
+		
+		// Create the data bit string by concatenating all segments
+		var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;
+		var bb = new BitBuffer();
+		segs.forEach(function(seg) {
+			bb.appendBits(seg.mode.modeBits, 4);
+			bb.appendBits(seg.numChars, seg.mode.numCharCountBits(version));
+			seg.getBits().forEach(function(bit) {
+				bb.push(bit);
+			});
+		});
+		
+		// Add terminator and pad up to a byte if applicable
+		bb.appendBits(0, Math.min(4, dataCapacityBits - bb.length));
+		bb.appendBits(0, (8 - bb.length % 8) % 8);
+		
+		// Pad with alternate bytes until data capacity is reached
+		for (var padByte = 0xEC; bb.length < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
+			bb.appendBits(padByte, 8);
+		if (bb.length % 8 != 0)
+			throw "Assertion error";
+		
+		// Create the QR Code symbol
+		return new this(bb.getBytes(), mask, version, ecl);
+	};
+	
+	
+	/*---- Public constants for QrCode ----*/
+	
+	var MIN_VERSION =  1;
+	var MAX_VERSION = 40;
+	Object.defineProperty(this.QrCode, "MIN_VERSION", {value:MIN_VERSION});
+	Object.defineProperty(this.QrCode, "MAX_VERSION", {value:MAX_VERSION});
+	
+	
+	/*---- Private static helper functions QrCode ----*/
+	
+	var QrCode = {};  // Private object to assign properties to. Not the same object as 'this.QrCode'.
+	
+	
+	// Returns a sequence of positions of the alignment patterns in ascending order. These positions are
+	// used on both the x and y axes. Each value in the resulting sequence is in the range [0, 177).
+	// This stateless pure function could be implemented as table of 40 variable-length lists of integers.
+	QrCode.getAlignmentPatternPositions = function(ver) {
+		if (ver < MIN_VERSION || ver > MAX_VERSION)
+			throw "Version number out of range";
+		else if (ver == 1)
+			return [];
+		else {
+			var size = ver * 4 + 17;
+			var numAlign = Math.floor(ver / 7) + 2;
+			var step;
+			if (ver != 32)
+				step = Math.ceil((size - 13) / (2 * numAlign - 2)) * 2;
+			else  // C-C-C-Combo breaker!
+				step = 26;
+			
+			var result = [6];
+			for (var i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step)
+				result.splice(1, 0, pos);
+			return result;
+		}
+	};
+	
+	
+	// Returns the number of data bits that can be stored in a QR Code of the given version number, after
+	// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
+	// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
+	QrCode.getNumRawDataModules = function(ver) {
+		if (ver < MIN_VERSION || ver > MAX_VERSION)
+			throw "Version number out of range";
+		var result = (16 * ver + 128) * ver + 64;
+		if (ver >= 2) {
+			var numAlign = Math.floor(ver / 7) + 2;
+			result -= (25 * numAlign - 10) * numAlign - 55;
+			if (ver >= 7)
+				result -= 18 * 2;  // Subtract version information
+		}
+		return result;
+	};
+	
+	
+	// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
+	// QR Code of the given version number and error correction level, with remainder bits discarded.
+	// This stateless pure function could be implemented as a (40*4)-cell lookup table.
+	QrCode.getNumDataCodewords = function(ver, ecl) {
+		if (ver < MIN_VERSION || ver > MAX_VERSION)
+			throw "Version number out of range";
+		return Math.floor(QrCode.getNumRawDataModules(ver) / 8) -
+			QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] *
+			QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
+	};
+	
+	
+	/*---- Private tables of constants for QrCode ----*/
+	
+	// For use in getPenaltyScore(), when evaluating which mask is best.
+	QrCode.PENALTY_N1 = 3;
+	QrCode.PENALTY_N2 = 3;
+	QrCode.PENALTY_N3 = 40;
+	QrCode.PENALTY_N4 = 10;
+	
+	QrCode.ECC_CODEWORDS_PER_BLOCK = [
+		// Version: (note that index 0 is for padding, and is set to an illegal value)
+		//  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+		[null,  7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Low
+		[null, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],  // Medium
+		[null, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Quartile
+		[null, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // High
+	];
+	
+	QrCode.NUM_ERROR_CORRECTION_BLOCKS = [
+		// Version: (note that index 0 is for padding, and is set to an illegal value)
+		//  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+		[null, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],  // Low
+		[null, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],  // Medium
+		[null, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],  // Quartile
+		[null, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81],  // High
+	];
+	
+	
+	/*---- Public helper enumeration ----*/
+	
+	/* 
+	 * Represents the error correction level used in a QR Code symbol.
+	 */
+	this.QrCode.Ecc = {
+		// Constants declared in ascending order of error protection
+		LOW     : new Ecc(0, 1),
+		MEDIUM  : new Ecc(1, 0),
+		QUARTILE: new Ecc(2, 3),
+		HIGH    : new Ecc(3, 2),
+	};
+	
+	
+	// Private constructor.
+	function Ecc(ord, fb) {
+		// (Public) In the range 0 to 3 (unsigned 2-bit integer)
+		Object.defineProperty(this, "ordinal", {value:ord});
+		
+		// (Package-private) In the range 0 to 3 (unsigned 2-bit integer)
+		Object.defineProperty(this, "formatBits", {value:fb});
+	}
+	
+	
+	
+	/*---- Data segment class ----*/
+	
+	/* 
+	 * A public class that represents a character string to be encoded in a QR Code symbol.
+	 * Each segment has a mode, and a sequence of characters that is already encoded as
+	 * a sequence of bits. Instances of this class are immutable.
+	 * This segment class imposes no length restrictions, but QR Codes have restrictions.
+	 * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
+	 * Any segment longer than this is meaningless for the purpose of generating QR Codes.
+	 */
+	this.QrSegment = function(mode, numChars, bitData) {
+		if (numChars < 0 || !(mode instanceof Mode))
+			throw "Invalid argument";
+		bitData = bitData.slice();  // Make defensive copy
+		
+		// The mode indicator for this segment.
+		Object.defineProperty(this, "mode", {value:mode});
+		
+		// The length of this segment's unencoded data, measured in characters. Always zero or positive.
+		Object.defineProperty(this, "numChars", {value:numChars});
+		
+		// Returns a copy of all bits, which is an array of 0s and 1s.
+		this.getBits = function() {
+			return bitData.slice();  // Make defensive copy
+		};
+	};
+	
+	
+	/*---- Public static factory functions for QrSegment ----*/
+	
+	/* 
+	 * Returns a segment representing the given binary data encoded in byte mode.
+	 */
+	this.QrSegment.makeBytes = function(data) {
+		var bb = new BitBuffer();
+		data.forEach(function(b) {
+			bb.appendBits(b, 8);
+		});
+		return new this(this.Mode.BYTE, data.length, bb);
+	};
+	
+	
+	/* 
+	 * Returns a segment representing the given string of decimal digits encoded in numeric mode.
+	 */
+	this.QrSegment.makeNumeric = function(digits) {
+		if (!this.NUMERIC_REGEX.test(digits))
+			throw "String contains non-numeric characters";
+		var bb = new BitBuffer();
+		var i;
+		for (i = 0; i + 3 <= digits.length; i += 3)  // Process groups of 3
+			bb.appendBits(parseInt(digits.substr(i, 3), 10), 10);
+		var rem = digits.length - i;
+		if (rem > 0)  // 1 or 2 digits remaining
+			bb.appendBits(parseInt(digits.substring(i), 10), rem * 3 + 1);
+		return new this(this.Mode.NUMERIC, digits.length, bb);
+	};
+	
+	
+	/* 
+	 * Returns a segment representing the given text string encoded in alphanumeric mode.
+	 * The characters allowed are: 0 to 9, A to Z (uppercase only), space,
+	 * dollar, percent, asterisk, plus, hyphen, period, slash, colon.
+	 */
+	this.QrSegment.makeAlphanumeric = function(text) {
+		if (!this.ALPHANUMERIC_REGEX.test(text))
+			throw "String contains unencodable characters in alphanumeric mode";
+		var bb = new BitBuffer();
+		var i;
+		for (i = 0; i + 2 <= text.length; i += 2) {  // Process groups of 2
+			var temp = QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;
+			temp += QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));
+			bb.appendBits(temp, 11);
+		}
+		if (i < text.length)  // 1 character remaining
+			bb.appendBits(QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6);
+		return new this(this.Mode.ALPHANUMERIC, text.length, bb);
+	};
+	
+	
+	/* 
+	 * Returns a new mutable list of zero or more segments to represent the given Unicode text string.
+	 * The result may use various segment modes and switch modes to optimize the length of the bit stream.
+	 */
+	this.QrSegment.makeSegments = function(text) {
+		// Select the most efficient segment encoding automatically
+		if (text == "")
+			return [];
+		else if (this.NUMERIC_REGEX.test(text))
+			return [this.makeNumeric(text)];
+		else if (this.ALPHANUMERIC_REGEX.test(text))
+			return [this.makeAlphanumeric(text)];
+		else
+			return [this.makeBytes(toUtf8ByteArray(text))];
+	};
+	
+	
+	/* 
+	 * Returns a segment representing an Extended Channel Interpretation
+	 * (ECI) designator with the given assignment value.
+	 */
+	this.QrSegment.makeEci = function(assignVal) {
+		var bb = new BitBuffer();
+		if (0 <= assignVal && assignVal < (1 << 7))
+			bb.appendBits(assignVal, 8);
+		else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) {
+			bb.appendBits(2, 2);
+			bb.appendBits(assignVal, 14);
+		} else if ((1 << 14) <= assignVal && assignVal < 1000000) {
+			bb.appendBits(6, 3);
+			bb.appendBits(assignVal, 21);
+		} else
+			throw "ECI assignment value out of range";
+		return new this(this.Mode.ECI, 0, bb);
+	};
+	
+	
+	// Package-private helper function.
+	this.QrSegment.getTotalBits = function(segs, version) {
+		if (version < MIN_VERSION || version > MAX_VERSION)
+			throw "Version number out of range";
+		var result = 0;
+		for (var i = 0; i < segs.length; i++) {
+			var seg = segs[i];
+			var ccbits = seg.mode.numCharCountBits(version);
+			// Fail if segment length value doesn't fit in the length field's bit-width
+			if (seg.numChars >= (1 << ccbits))
+				return null;
+			result += 4 + ccbits + seg.getBits().length;
+		}
+		return result;
+	};
+	
+	
+	/*---- Constants for QrSegment ----*/
+	
+	var QrSegment = {};  // Private object to assign properties to. Not the same object as 'this.QrSegment'.
+	
+	// (Public) Can test whether a string is encodable in numeric mode (such as by using QrSegment.makeNumeric()).
+	this.QrSegment.NUMERIC_REGEX = /^[0-9]*$/;
+	
+	// (Public) Can test whether a string is encodable in alphanumeric mode (such as by using QrSegment.makeAlphanumeric()).
+	this.QrSegment.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\/:-]*$/;
+	
+	// (Private) The set of all legal characters in alphanumeric mode, where each character value maps to the index in the string.
+	QrSegment.ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
+	
+	
+	/*---- Public helper enumeration ----*/
+	
+	/* 
+	 * Represents the mode field of a segment. Immutable.
+	 */
+	this.QrSegment.Mode = {  // Constants
+		NUMERIC     : new Mode(0x1, [10, 12, 14]),
+		ALPHANUMERIC: new Mode(0x2, [ 9, 11, 13]),
+		BYTE        : new Mode(0x4, [ 8, 16, 16]),
+		KANJI       : new Mode(0x8, [ 8, 10, 12]),
+		ECI         : new Mode(0x7, [ 0,  0,  0]),
+	};
+	
+	
+	// Private constructor.
+	function Mode(mode, ccbits) {
+		// (Package-private) An unsigned 4-bit integer value (range 0 to 15) representing the mode indicator bits for this mode object.
+		Object.defineProperty(this, "modeBits", {value:mode});
+		
+		// (Package-private) Returns the bit width of the segment character count field for this mode object at the given version number.
+		this.numCharCountBits = function(ver) {
+			if      ( 1 <= ver && ver <=  9)  return ccbits[0];
+			else if (10 <= ver && ver <= 26)  return ccbits[1];
+			else if (27 <= ver && ver <= 40)  return ccbits[2];
+			else  throw "Version number out of range";
+		};
+	}
+	
+	
+	
+	/*---- Private helper functions and classes ----*/
+	
+	// Returns a new array of bytes representing the given string encoded in UTF-8.
+	function toUtf8ByteArray(str) {
+		str = encodeURI(str);
+		var result = [];
+		for (var i = 0; i < str.length; i++) {
+			if (str.charAt(i) != "%")
+				result.push(str.charCodeAt(i));
+			else {
+				result.push(parseInt(str.substr(i + 1, 2), 16));
+				i += 2;
+			}
+		}
+		return result;
+	}
+	
+	
+	
+	/* 
+	 * A private helper class that computes the Reed-Solomon error correction codewords for a sequence of
+	 * data codewords at a given degree. Objects are immutable, and the state only depends on the degree.
+	 * This class exists because each data block in a QR Code shares the same the divisor polynomial.
+	 * This constructor creates a Reed-Solomon ECC generator for the given degree. This could be implemented
+	 * as a lookup table over all possible parameter values, instead of as an algorithm.
+	 */
+	function ReedSolomonGenerator(degree) {
+		if (degree < 1 || degree > 255)
+			throw "Degree out of range";
+		
+		// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which
+		// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
+		var coefficients = [];
+		
+		// Start with the monomial x^0
+		for (var i = 0; i < degree - 1; i++)
+			coefficients.push(0);
+		coefficients.push(1);
+		
+		// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
+		// drop the highest term, and store the rest of the coefficients in order of descending powers.
+		// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
+		var root = 1;
+		for (var i = 0; i < degree; i++) {
+			// Multiply the current product by (x - r^i)
+			for (var j = 0; j < coefficients.length; j++) {
+				coefficients[j] = ReedSolomonGenerator.multiply(coefficients[j], root);
+				if (j + 1 < coefficients.length)
+					coefficients[j] ^= coefficients[j + 1];
+			}
+			root = ReedSolomonGenerator.multiply(root, 0x02);
+		}
+		
+		// Computes and returns the Reed-Solomon error correction codewords for the given
+		// sequence of data codewords. The returned object is always a new byte array.
+		// This method does not alter this object's state (because it is immutable).
+		this.getRemainder = function(data) {
+			// Compute the remainder by performing polynomial division
+			var result = coefficients.map(function() { return 0; });
+			data.forEach(function(b) {
+				var factor = b ^ result.shift();
+				result.push(0);
+				for (var i = 0; i < result.length; i++)
+					result[i] ^= ReedSolomonGenerator.multiply(coefficients[i], factor);
+			});
+			return result;
+		};
+	}
+	
+	// This static function returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and
+	// result are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
+	ReedSolomonGenerator.multiply = function(x, y) {
+		if (x >>> 8 != 0 || y >>> 8 != 0)
+			throw "Byte out of range";
+		// Russian peasant multiplication
+		var z = 0;
+		for (var i = 7; i >= 0; i--) {
+			z = (z << 1) ^ ((z >>> 7) * 0x11D);
+			z ^= ((y >>> i) & 1) * x;
+		}
+		if (z >>> 8 != 0)
+			throw "Assertion error";
+		return z;
+	};
+	
+	
+	
+	/* 
+	 * A private helper class that represents an appendable sequence of bits.
+	 * This constructor creates an empty bit buffer (length 0).
+	 */
+	function BitBuffer() {
+		
+		// Packs this buffer's bits into bytes in big endian,
+		// padding with '0' bit values, and returns the new array.
+		this.getBytes = function() {
+			var result = [];
+			while (result.length * 8 < this.length)
+				result.push(0);
+			this.forEach(function(bit, i) {
+				result[i >>> 3] |= bit << (7 - (i & 7));
+			});
+			return result;
+		};
+		
+		// Appends the given number of low bits of the given value
+		// to this sequence. Requires 0 <= val < 2^len.
+		this.appendBits = function(val, len) {
+			if (len < 0 || len > 31 || val >>> len != 0)
+				throw "Value out of range";
+			for (var i = len - 1; i >= 0; i--)  // Append bit by bit
+				this.push((val >>> i) & 1);
+		};
+	}
+	
+	BitBuffer.prototype = Object.create(Array.prototype);
+	
+};
diff --git a/src/third_party/QR-Code-generator/python/qrcodegen-batch-test.py b/src/third_party/QR-Code-generator/python/qrcodegen-batch-test.py
new file mode 100644
index 0000000..fa92e52
--- /dev/null
+++ b/src/third_party/QR-Code-generator/python/qrcodegen-batch-test.py
@@ -0,0 +1,137 @@
+# 
+# QR Code generator batch test (Python 3)
+# 
+# Runs various versions of the QR Code generator test worker as subprocesses,
+# feeds each one the same random input, and compares their output for equality.
+# 
+# Copyright (c) Project Nayuki. (MIT License)
+# https://www.nayuki.io/page/qr-code-generator-library
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+# - The above copyright notice and this permission notice shall be included in
+#   all copies or substantial portions of the Software.
+# - The Software is provided "as is", without warranty of any kind, express or
+#   implied, including but not limited to the warranties of merchantability,
+#   fitness for a particular purpose and noninfringement. In no event shall the
+#   authors or copyright holders be liable for any claim, damages or other
+#   liability, whether in an action of contract, tort or otherwise, arising from,
+#   out of or in connection with the Software or the use or other dealings in the
+#   Software.
+# 
+
+from __future__ import print_function
+import itertools, random, subprocess, sys, time
+if sys.version_info.major < 3:
+	raise RuntimeError("Requires Python 3+")
+
+
+CHILD_PROGRAMS = [
+	["python2", "../python/qrcodegen-worker.py"],  # Python 2 program
+	["python3", "../python/qrcodegen-worker.py"],  # Python 3 program
+	["java", "-cp", "../java", "io/nayuki/qrcodegen/QrCodeGeneratorWorker"],  # Java program
+	["../c/qrcodegen-worker"],  # C program
+	["../cpp/QrCodeGeneratorWorker"],  # C++ program
+	["../rust/target/debug/examples/qrcodegen-worker"],  # Rust program
+]
+
+
+subprocs = []
+
+def main():
+	# Launch workers
+	global subprocs
+	try:
+		for args in CHILD_PROGRAMS:
+			subprocs.append(subprocess.Popen(args, universal_newlines=True,
+				stdin=subprocess.PIPE, stdout=subprocess.PIPE))
+	except FileNotFoundError:
+		write_all(-1)
+		raise
+	
+	# Check if any died
+	time.sleep(0.3)
+	if any(proc.poll() is not None for proc in subprocs):
+		for proc in subprocs:
+			if proc.poll() is None:
+				print(-1, file=proc.stdin)
+				proc.stdin.flush()
+		sys.exit("Error: One or more workers failed to start")
+	
+	# Do tests
+	for i in itertools.count():
+		print("Trial {}: ".format(i), end="")
+		do_trial()
+		print()
+
+
+def do_trial():
+	mode = random.randrange(4)
+	if mode == 0:  # Numeric
+		length = round((2 * 7089) ** random.random())
+		data = [random.randrange(48, 58) for _ in range(length)]
+	elif mode == 1:  # Alphanumeric
+		length = round((2 * 4296) ** random.random())
+		data = [ord(random.choice("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:")) for _ in range(length)]
+	elif mode == 2:  # ASCII
+		length = round((2 * 2953) ** random.random())
+		data = [random.randrange(128) for _ in range(length)]
+	elif mode == 3:  # Byte
+		length = round((2 * 2953) ** random.random())
+		data = [random.randrange(256) for _ in range(length)]
+	else:
+		raise AssertionError()
+	
+	write_all(length)
+	for b in data:
+		write_all(b)
+	
+	errcorlvl = random.randrange(4)
+	minversion = random.randint(1, 40)
+	maxversion = random.randint(1, 40)
+	if minversion > maxversion:
+		minversion, maxversion = maxversion, minversion
+	mask = -1
+	if random.random() < 0.5:
+		mask = random.randrange(8)
+	boostecl = int(random.random() < 0.2)
+	print("mode={} len={} ecl={} minv={} maxv={} mask={} boost={}".format(mode, length, errcorlvl, minversion, maxversion, mask, boostecl), end="")
+	
+	write_all(errcorlvl)
+	write_all(minversion)
+	write_all(maxversion)
+	write_all(mask)
+	write_all(boostecl)
+	flush_all()
+	
+	version = read_verify()
+	print(" version={}".format(version), end="")
+	if version == -1:
+		return
+	size = version * 4 + 17
+	for _ in range(size**2):
+		read_verify()
+
+
+def write_all(val):
+	for proc in subprocs:
+		print(val, file=proc.stdin)
+
+def flush_all():
+	for proc in subprocs:
+		proc.stdin.flush()
+
+def read_verify():
+	val = subprocs[0].stdout.readline().rstrip("\r\n")
+	for proc in subprocs[1 : ]:
+		if proc.stdout.readline().rstrip("\r\n") != val:
+			raise ValueError("Mismatch")
+	return int(val)
+
+
+if __name__ == "__main__":
+	main()
diff --git a/src/third_party/QR-Code-generator/python/qrcodegen-demo.py b/src/third_party/QR-Code-generator/python/qrcodegen-demo.py
new file mode 100644
index 0000000..50e975e
--- /dev/null
+++ b/src/third_party/QR-Code-generator/python/qrcodegen-demo.py
@@ -0,0 +1,186 @@
+# 
+# QR Code generator demo (Python 2, 3)
+# 
+# Run this command-line program with no arguments. The program computes a bunch of demonstration
+# QR Codes and prints them to the console. Also, the SVG code for one QR Code is printed as a sample.
+# 
+# Copyright (c) Project Nayuki. (MIT License)
+# https://www.nayuki.io/page/qr-code-generator-library
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+# - The above copyright notice and this permission notice shall be included in
+#   all copies or substantial portions of the Software.
+# - The Software is provided "as is", without warranty of any kind, express or
+#   implied, including but not limited to the warranties of merchantability,
+#   fitness for a particular purpose and noninfringement. In no event shall the
+#   authors or copyright holders be liable for any claim, damages or other
+#   liability, whether in an action of contract, tort or otherwise, arising from,
+#   out of or in connection with the Software or the use or other dealings in the
+#   Software.
+# 
+
+from __future__ import print_function
+from qrcodegen import QrCode, QrSegment
+
+
+def main():
+	"""The main application program."""
+	do_basic_demo()
+	do_variety_demo()
+	do_segment_demo()
+	do_mask_demo()
+
+
+
+# ---- Demo suite ----
+
+def do_basic_demo():
+	"""Creates a single QR Code, then prints it to the console."""
+	text = u"Hello, world!"               # User-supplied Unicode text
+	errcorlvl = QrCode.Ecc.LOW  # Error correction level
+	
+	# Make and print the QR Code symbol
+	qr = QrCode.encode_text(text, errcorlvl)
+	print_qr(qr)
+	print(qr.to_svg_str(4))
+
+
+def do_variety_demo():
+	"""Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console."""
+	
+	# Numeric mode encoding (3.33 bits per digit)
+	qr = QrCode.encode_text("314159265358979323846264338327950288419716939937510", QrCode.Ecc.MEDIUM)
+	print_qr(qr)
+	
+	# Alphanumeric mode encoding (5.5 bits per character)
+	qr = QrCode.encode_text("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", QrCode.Ecc.HIGH)
+	print_qr(qr)
+	
+	# Unicode text as UTF-8
+	qr = QrCode.encode_text(u"\u3053\u3093\u306B\u3061\u0077\u0061\u3001\u4E16\u754C\uFF01\u0020\u03B1\u03B2\u03B3\u03B4", QrCode.Ecc.QUARTILE)
+	print_qr(qr)
+	
+	# Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
+	qr = QrCode.encode_text(
+		"Alice was beginning to get very tired of sitting by her sister on the bank, "
+		"and of having nothing to do: once or twice she had peeped into the book her sister was reading, "
+		"but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice "
+		"'without pictures or conversations?' So she was considering in her own mind (as well as she could, "
+		"for the hot day made her feel very sleepy and stupid), whether the pleasure of making a "
+		"daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly "
+		"a White Rabbit with pink eyes ran close by her.", QrCode.Ecc.HIGH)
+	print_qr(qr)
+
+
+def do_segment_demo():
+	"""Creates QR Codes with manually specified segments for better compactness."""
+	
+	# Illustration "silver"
+	silver0 = "THE SQUARE ROOT OF 2 IS 1."
+	silver1 = "41421356237309504880168872420969807856967187537694807317667973799"
+	qr = QrCode.encode_text(silver0 + silver1, QrCode.Ecc.LOW)
+	print_qr(qr)
+	
+	segs = [
+		QrSegment.make_alphanumeric(silver0),
+		QrSegment.make_numeric(silver1)]
+	qr = QrCode.encode_segments(segs, QrCode.Ecc.LOW)
+	print_qr(qr)
+	
+	# Illustration "golden"
+	golden0 = u"Golden ratio \u03C6 = 1."
+	golden1 = u"6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374"
+	golden2 = u"......"
+	qr = QrCode.encode_text(golden0 + golden1 + golden2, QrCode.Ecc.LOW)
+	print_qr(qr)
+	
+	segs = [
+		QrSegment.make_bytes(golden0.encode("UTF-8")),
+		QrSegment.make_numeric(golden1),
+		QrSegment.make_alphanumeric(golden2)]
+	qr = QrCode.encode_segments(segs, QrCode.Ecc.LOW)
+	print_qr(qr)
+	
+	# Illustration "Madoka": kanji, kana, Greek, Cyrillic, full-width Latin characters
+	madoka = u"\u300C\u9B54\u6CD5\u5C11\u5973\u307E\u3069\u304B\u2606\u30DE\u30AE\u30AB\u300D\u3063\u3066\u3001\u3000\u0418\u0410\u0418\u3000\uFF44\uFF45\uFF53\uFF55\u3000\u03BA\u03B1\uFF1F"
+	qr = QrCode.encode_text(madoka, QrCode.Ecc.LOW)
+	print_qr(qr)
+	
+	kanjiCharBits = [  # Kanji mode encoding (13 bits per character)
+		0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1,
+		1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+		0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+		0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1,
+		0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1,
+		0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0,
+		0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1,
+		0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1,
+		0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1,
+		0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1,
+		0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1,
+		0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0,
+		0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0,
+		0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1,
+		0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
+		0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0,
+		0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
+		0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1,
+		0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+		0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+	]
+	segs = [QrSegment(QrSegment.Mode.KANJI, len(kanjiCharBits) // 13, kanjiCharBits)]
+	qr = QrCode.encode_segments(segs, QrCode.Ecc.LOW)
+	print_qr(qr)
+
+
+def do_mask_demo():
+	"""Creates QR Codes with the same size and contents but different mask patterns."""
+	
+	# Project Nayuki URL
+	segs = QrSegment.make_segments("https://www.nayuki.io/")
+	print_qr(QrCode.encode_segments(segs, QrCode.Ecc.HIGH, mask=-1))  # Automatic mask
+	print_qr(QrCode.encode_segments(segs, QrCode.Ecc.HIGH, mask=3))  # Force mask 3
+	
+	# Chinese text as UTF-8
+	segs = QrSegment.make_segments(
+		u"\u7DAD\u57FA\u767E\u79D1\uFF08\u0057\u0069\u006B\u0069\u0070\u0065\u0064\u0069\u0061\uFF0C"
+		 "\u8046\u807D\u0069\u002F\u02CC\u0077\u026A\u006B\u1D7B\u02C8\u0070\u0069\u02D0\u0064\u0069"
+		 "\u002E\u0259\u002F\uFF09\u662F\u4E00\u500B\u81EA\u7531\u5167\u5BB9\u3001\u516C\u958B\u7DE8"
+		 "\u8F2F\u4E14\u591A\u8A9E\u8A00\u7684\u7DB2\u8DEF\u767E\u79D1\u5168\u66F8\u5354\u4F5C\u8A08"
+		 "\u756B")
+	print_qr(QrCode.encode_segments(segs, QrCode.Ecc.MEDIUM, mask=0))  # Force mask 0
+	print_qr(QrCode.encode_segments(segs, QrCode.Ecc.MEDIUM, mask=1))  # Force mask 1
+	print_qr(QrCode.encode_segments(segs, QrCode.Ecc.MEDIUM, mask=5))  # Force mask 5
+	print_qr(QrCode.encode_segments(segs, QrCode.Ecc.MEDIUM, mask=7))  # Force mask 7
+
+
+
+# ---- Utilities ----
+
+def print_qr(qrcode):
+	"""Prints the given QrCode object to the console."""
+	border = 4
+	for y in range(-border, qrcode.get_size() + border):
+		for x in range(-border, qrcode.get_size() + border):
+			print(u"\u2588 "[1 if qrcode.get_module(x,y) else 0] * 2, end="")
+		print()
+	print()
+
+
+# Run the main program
+if __name__ == "__main__":
+	main()
diff --git a/src/third_party/QR-Code-generator/python/qrcodegen-worker.py b/src/third_party/QR-Code-generator/python/qrcodegen-worker.py
new file mode 100644
index 0000000..c52548d
--- /dev/null
+++ b/src/third_party/QR-Code-generator/python/qrcodegen-worker.py
@@ -0,0 +1,87 @@
+# 
+# QR Code generator test worker (Python 2, 3)
+# 
+# This program reads data and encoding parameters from standard input and writes
+# QR Code bitmaps to standard output. The I/O format is one integer per line.
+# Run with no command line arguments. The program is intended for automated
+# batch testing of end-to-end functionality of this QR Code generator library.
+# 
+# Copyright (c) Project Nayuki. (MIT License)
+# https://www.nayuki.io/page/qr-code-generator-library
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+# - The above copyright notice and this permission notice shall be included in
+#   all copies or substantial portions of the Software.
+# - The Software is provided "as is", without warranty of any kind, express or
+#   implied, including but not limited to the warranties of merchantability,
+#   fitness for a particular purpose and noninfringement. In no event shall the
+#   authors or copyright holders be liable for any claim, damages or other
+#   liability, whether in an action of contract, tort or otherwise, arising from,
+#   out of or in connection with the Software or the use or other dealings in the
+#   Software.
+# 
+
+from __future__ import print_function
+import sys
+import qrcodegen
+py3 = sys.version_info.major >= 3
+
+
+def read_int():
+	return int((input if py3 else raw_input)())
+
+
+def main():
+	while True:
+		
+		# Read data or exit
+		length = read_int()
+		if length == -1:
+			break
+		data = [read_int() for _ in range(length)]
+		
+		# Read encoding parameters
+		errcorlvl  = read_int()
+		minversion = read_int()
+		maxversion = read_int()
+		mask       = read_int()
+		boostecl   = read_int()
+		
+		# Make segments for encoding
+		if all((b < 128) for b in data):  # Is ASCII
+			segs = qrcodegen.QrSegment.make_segments("".join(chr(b) for b in data))
+		elif py3:
+			segs = [qrcodegen.QrSegment.make_bytes(bytes(data))]
+		else:
+			segs = [qrcodegen.QrSegment.make_bytes("".join(chr(b) for b in data))]
+		
+		try:  # Try to make QR Code symbol
+			qr = qrcodegen.QrCode.encode_segments(segs, ECC_LEVELS[errcorlvl], minversion, maxversion, mask, boostecl != 0)
+			# Print grid of modules
+			print(qr.get_version())
+			for y in range(qr.get_size()):
+				for x in range(qr.get_size()):
+					print(1 if qr.get_module(x, y) else 0)
+			
+		except ValueError as e:
+			if e.args[0] != "Data too long":
+				raise
+			print(-1)
+		sys.stdout.flush()
+
+
+ECC_LEVELS = (
+	qrcodegen.QrCode.Ecc.LOW,
+	qrcodegen.QrCode.Ecc.MEDIUM,
+	qrcodegen.QrCode.Ecc.QUARTILE,
+	qrcodegen.QrCode.Ecc.HIGH,
+)
+
+
+if __name__ == "__main__":
+	main()
diff --git a/src/third_party/QR-Code-generator/python/qrcodegen.py b/src/third_party/QR-Code-generator/python/qrcodegen.py
new file mode 100644
index 0000000..9a5b32c
--- /dev/null
+++ b/src/third_party/QR-Code-generator/python/qrcodegen.py
@@ -0,0 +1,839 @@
+# 
+# QR Code generator library (Python 2, 3)
+# 
+# Copyright (c) Project Nayuki. (MIT License)
+# https://www.nayuki.io/page/qr-code-generator-library
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+# - The above copyright notice and this permission notice shall be included in
+#   all copies or substantial portions of the Software.
+# - The Software is provided "as is", without warranty of any kind, express or
+#   implied, including but not limited to the warranties of merchantability,
+#   fitness for a particular purpose and noninfringement. In no event shall the
+#   authors or copyright holders be liable for any claim, damages or other
+#   liability, whether in an action of contract, tort or otherwise, arising from,
+#   out of or in connection with the Software or the use or other dealings in the
+#   Software.
+# 
+
+import itertools, re, sys
+
+
+"""
+This module "qrcodegen", public members:
+- Class QrCode:
+  - Function encode_text(str text, QrCode.Ecc ecl) -> QrCode
+  - Function encode_binary(bytes data, QrCode.Ecc ecl) -> QrCode
+  - Function encode_segments(list<QrSegment> segs, QrCode.Ecc ecl,
+        int minversion=1, int maxversion=40, mask=-1, boostecl=true) -> QrCode
+  - Constants int MIN_VERSION, MAX_VERSION
+  - Constructor QrCode(bytes datacodewords, int mask, int version, QrCode.Ecc ecl)
+  - Method get_version() -> int
+  - Method get_size() -> int
+  - Method get_error_correction_level() -> QrCode.Ecc
+  - Method get_mask() -> int
+  - Method get_module(int x, int y) -> bool
+  - Method to_svg_str(int border) -> str
+  - Enum Ecc:
+    - Constants LOW, MEDIUM, QUARTILE, HIGH
+    - Field int ordinal
+- Class QrSegment:
+  - Function make_bytes(bytes data) -> QrSegment
+  - Function make_numeric(str digits) -> QrSegment
+  - Function make_alphanumeric(str text) -> QrSegment
+  - Function make_segments(str text) -> list<QrSegment>
+  - Function make_eci(int assignval) -> QrSegment
+  - Constructor QrSegment(QrSegment.Mode mode, int numch, list<int> bitdata)
+  - Method get_mode() -> QrSegment.Mode
+  - Method get_num_chars() -> int
+  - Method get_bits() -> list<int>
+  - Constants regex NUMERIC_REGEX, ALPHANUMERIC_REGEX
+  - Enum Mode:
+    - Constants NUMERIC, ALPHANUMERIC, BYTE, KANJI, ECI
+"""
+
+
+# ---- QR Code symbol class ----
+
+class QrCode(object):
+	"""Represents an immutable square grid of black or white cells for a QR Code symbol. This class covers the
+	QR Code model 2 specification, supporting all versions (sizes) from 1 to 40, all 4 error correction levels."""
+	
+	# ---- Public static factory functions ----
+	
+	@staticmethod
+	def encode_text(text, ecl):
+		"""Returns a QR Code symbol representing the specified Unicode text string at the specified error correction level.
+		As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer
+		Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible
+		QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the
+		ecl argument if it can be done without increasing the version."""
+		segs = QrSegment.make_segments(text)
+		return QrCode.encode_segments(segs, ecl)
+	
+	
+	@staticmethod
+	def encode_binary(data, ecl):
+		"""Returns a QR Code symbol representing the given binary data string at the given error correction level.
+		This function always encodes using the binary segment mode, not any text mode. The maximum number of
+		bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
+		The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version."""
+		if not isinstance(data, (bytes, bytearray)):
+			raise TypeError("Byte string/list expected")
+		return QrCode.encode_segments([QrSegment.make_bytes(data)], ecl)
+	
+	
+	@staticmethod
+	def encode_segments(segs, ecl, minversion=1, maxversion=40, mask=-1, boostecl=True):
+		"""Returns a QR Code symbol representing the given data segments with the given encoding parameters.
+		The smallest possible QR Code version within the given range is automatically chosen for the output.
+		This function allows the user to create a custom sequence of segments that switches
+		between modes (such as alphanumeric and binary) to encode text more efficiently.
+		This function is considered to be lower level than simply encoding text or binary data."""
+		
+		if not (QrCode.MIN_VERSION <= minversion <= maxversion <= QrCode.MAX_VERSION) or not (-1 <= mask <= 7):
+			raise ValueError("Invalid value")
+		
+		# Find the minimal version number to use
+		for version in range(minversion, maxversion + 1):
+			datacapacitybits = QrCode._get_num_data_codewords(version, ecl) * 8  # Number of data bits available
+			datausedbits = QrSegment.get_total_bits(segs, version)
+			if datausedbits is not None and datausedbits <= datacapacitybits:
+				break  # This version number is found to be suitable
+			if version >= maxversion:  # All versions in the range could not fit the given data
+				raise ValueError("Data too long")
+		if datausedbits is None:
+			raise AssertionError()
+		
+		# Increase the error correction level while the data still fits in the current version number
+		for newecl in (QrCode.Ecc.MEDIUM, QrCode.Ecc.QUARTILE, QrCode.Ecc.HIGH):
+			if boostecl and datausedbits <= QrCode._get_num_data_codewords(version, newecl) * 8:
+				ecl = newecl
+		
+		# Create the data bit string by concatenating all segments
+		datacapacitybits = QrCode._get_num_data_codewords(version, ecl) * 8
+		bb = _BitBuffer()
+		for seg in segs:
+			bb.append_bits(seg.get_mode().get_mode_bits(), 4)
+			bb.append_bits(seg.get_num_chars(), seg.get_mode().num_char_count_bits(version))
+			bb.extend(seg._bitdata)
+		
+		# Add terminator and pad up to a byte if applicable
+		bb.append_bits(0, min(4, datacapacitybits - len(bb)))
+		bb.append_bits(0, -len(bb) % 8)  # Note: Python's modulo on negative numbers behaves better than C family languages
+		
+		# Pad with alternate bytes until data capacity is reached
+		for padbyte in itertools.cycle((0xEC, 0x11)):
+			if len(bb) >= datacapacitybits:
+				break
+			bb.append_bits(padbyte, 8)
+		assert len(bb) % 8 == 0
+		
+		# Create the QR Code symbol
+		return QrCode(bb.get_bytes(), mask, version, ecl)
+	
+	
+	# ---- Public constants ----
+	
+	MIN_VERSION =  1
+	MAX_VERSION = 40
+	
+	
+	# ---- Constructor ----
+	
+	def __init__(self, datacodewords, mask, version, errcorlvl):
+		"""Creates a new QR Code symbol with the given version number, error correction level, binary data array,
+		and mask number. mask = -1 is for automatic choice, or 0 to 7 for fixed choice. This is a cumbersome low-level constructor
+		that should not be invoked directly by the user. To go one level up, see the QrCode.encode_segments() function."""
+		
+		# Check arguments and handle simple scalar fields
+		if not (-1 <= mask <= 7):
+			raise ValueError("Mask value out of range")
+		if not (QrCode.MIN_VERSION <= version <= QrCode.MAX_VERSION):
+			raise ValueError("Version value out of range")
+		if not isinstance(errcorlvl, QrCode.Ecc):
+			raise TypeError("QrCode.Ecc expected")
+		self._version = version
+		self._errcorlvl = errcorlvl
+		self._size = version * 4 + 17
+		
+		if len(datacodewords) != QrCode._get_num_data_codewords(version, errcorlvl):
+			raise ValueError("Invalid array length")
+		# Initialize grids of modules
+		self._modules    = [[False] * self._size for _ in range(self._size)]  # The modules of the QR symbol; start with entirely white grid
+		self._isfunction = [[False] * self._size for _ in range(self._size)]  # Indicates function modules that are not subjected to masking
+		# Draw function patterns, draw all codewords
+		self._draw_function_patterns()
+		allcodewords = self._append_error_correction(datacodewords)
+		self._draw_codewords(allcodewords)
+		
+		# Handle masking
+		if mask == -1:  # Automatically choose best mask
+			minpenalty = 1 << 32
+			for i in range(8):
+				self._draw_format_bits(i)
+				self._apply_mask(i)
+				penalty = self._get_penalty_score()
+				if penalty < minpenalty:
+					mask = i
+					minpenalty = penalty
+				self._apply_mask(i)  # Undoes the mask due to XOR
+		assert 0 <= mask <= 7
+		self._draw_format_bits(mask)  # Overwrite old format bits
+		self._apply_mask(mask)  # Apply the final choice of mask
+		self._mask = mask
+	
+	
+	# ---- Accessor methods ----
+	
+	def get_version(self):
+		"""Returns this QR Code symbol's version number, which is always between 1 and 40 (inclusive)."""
+		return self._version
+	
+	def get_size(self):
+		"""Returns the width and height of this QR Code symbol, measured in modules.
+		Always equal to version * 4 + 17, in the range 21 to 177."""
+		return self._size
+	
+	def get_error_correction_level(self):
+		"""Returns the error correction level used in this QR Code symbol."""
+		return self._errcorlvl
+	
+	def get_mask(self):
+		"""Returns the mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer).
+		Note that even if a constructor was called with automatic masking requested
+		(mask = -1), the resulting object will still have a mask value between 0 and 7."""
+		return self._mask
+	
+	def get_module(self, x, y):
+		"""Returns the color of the module (pixel) at the given coordinates, which is either
+		False for white or True for black. The top left corner has the coordinates (x=0, y=0).
+		If the given coordinates are out of bounds, then False (white) is returned."""
+		return (0 <= x < self._size) and (0 <= y < self._size) and self._modules[y][x]
+	
+	
+	# ---- Public instance methods ----
+	
+	def to_svg_str(self, border):
+		"""Based on the given number of border modules to add as padding, this returns a
+		string whose contents represents an SVG XML file that depicts this QR Code symbol."""
+		if border < 0:
+			raise ValueError("Border must be non-negative")
+		parts = []
+		for y in range(-border, self._size + border):
+			for x in range(-border, self._size + border):
+				if self.get_module(x, y):
+					parts.append("M{},{}h1v1h-1z".format(x + border, y + border))
+		return """<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 {0} {0}" stroke="none">
+	<rect width="100%" height="100%" fill="#FFFFFF"/>
+	<path d="{1}" fill="#000000"/>
+</svg>
+""".format(self._size + border * 2, " ".join(parts))
+	
+	
+	# ---- Private helper methods for constructor: Drawing function modules ----
+	
+	def _draw_function_patterns(self):
+		# Draw horizontal and vertical timing patterns
+		for i in range(self._size):
+			self._set_function_module(6, i, i % 2 == 0)
+			self._set_function_module(i, 6, i % 2 == 0)
+		
+		# Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
+		self._draw_finder_pattern(3, 3)
+		self._draw_finder_pattern(self._size - 4, 3)
+		self._draw_finder_pattern(3, self._size - 4)
+		
+		# Draw numerous alignment patterns
+		alignpatpos = QrCode._get_alignment_pattern_positions(self._version)
+		numalign = len(alignpatpos)
+		skips = ((0, 0), (0, numalign - 1), (numalign - 1, 0))  # Skip the three finder corners
+		for i in range(numalign):
+			for j in range(numalign):
+				if (i, j) not in skips:
+					self._draw_alignment_pattern(alignpatpos[i], alignpatpos[j])
+		
+		# Draw configuration data
+		self._draw_format_bits(0)  # Dummy mask value; overwritten later in the constructor
+		self._draw_version()
+	
+	
+	def _draw_format_bits(self, mask):
+		"""Draws two copies of the format bits (with its own error correction code)
+		based on the given mask and this object's error correction level field."""
+		# Calculate error correction code and pack bits
+		data = self._errcorlvl.formatbits << 3 | mask  # errCorrLvl is uint2, mask is uint3
+		rem = data
+		for _ in range(10):
+			rem = (rem << 1) ^ ((rem >> 9) * 0x537)
+		data = data << 10 | rem
+		data ^= 0x5412  # uint15
+		assert data >> 15 == 0
+		
+		# Draw first copy
+		for i in range(0, 6):
+			self._set_function_module(8, i, (data >> i) & 1 != 0)
+		self._set_function_module(8, 7, (data >> 6) & 1 != 0)
+		self._set_function_module(8, 8, (data >> 7) & 1 != 0)
+		self._set_function_module(7, 8, (data >> 8) & 1 != 0)
+		for i in range(9, 15):
+			self._set_function_module(14 - i, 8, (data >> i) & 1 != 0)
+		
+		# Draw second copy
+		for i in range(0, 8):
+			self._set_function_module(self._size - 1 - i, 8, (data >> i) & 1 != 0)
+		for i in range(8, 15):
+			self._set_function_module(8, self._size - 15 + i, (data >> i) & 1 != 0)
+		self._set_function_module(8, self._size - 8, True)
+	
+	
+	def _draw_version(self):
+		"""Draws two copies of the version bits (with its own error correction code),
+		based on this object's version field (which only has an effect for 7 <= version <= 40)."""
+		if self._version < 7:
+			return
+		
+		# Calculate error correction code and pack bits
+		rem = self._version  # version is uint6, in the range [7, 40]
+		for _ in range(12):
+			rem = (rem << 1) ^ ((rem >> 11) * 0x1F25)
+		data = self._version << 12 | rem  # uint18
+		assert data >> 18 == 0
+		
+		# Draw two copies
+		for i in range(18):
+			bit = (data >> i) & 1 != 0
+			a, b = self._size - 11 + i % 3, i // 3
+			self._set_function_module(a, b, bit)
+			self._set_function_module(b, a, bit)
+	
+	
+	def _draw_finder_pattern(self, x, y):
+		"""Draws a 9*9 finder pattern including the border separator, with the center module at (x, y)."""
+		for i in range(-4, 5):
+			for j in range(-4, 5):
+				xx, yy = x + j, y + i
+				if (0 <= xx < self._size) and (0 <= yy < self._size):
+					# Chebyshev/infinity norm
+					self._set_function_module(xx, yy, max(abs(i), abs(j)) not in (2, 4))
+	
+	
+	def _draw_alignment_pattern(self, x, y):
+		"""Draws a 5*5 alignment pattern, with the center module at (x, y)."""
+		for i in range(-2, 3):
+			for j in range(-2, 3):
+				self._set_function_module(x + j, y + i, max(abs(i), abs(j)) != 1)
+	
+	
+	def _set_function_module(self, x, y, isblack):
+		"""Sets the color of a module and marks it as a function module.
+		Only used by the constructor. Coordinates must be in range."""
+		assert type(isblack) is bool
+		self._modules[y][x] = isblack
+		self._isfunction[y][x] = True
+	
+	
+	# ---- Private helper methods for constructor: Codewords and masking ----
+	
+	def _append_error_correction(self, data):
+		"""Returns a new byte string representing the given data with the appropriate error correction
+		codewords appended to it, based on this object's version and error correction level."""
+		version = self._version
+		assert len(data) == QrCode._get_num_data_codewords(version, self._errcorlvl)
+		
+		# Calculate parameter numbers
+		numblocks = QrCode._NUM_ERROR_CORRECTION_BLOCKS[self._errcorlvl.ordinal][version]
+		blockecclen = QrCode._ECC_CODEWORDS_PER_BLOCK[self._errcorlvl.ordinal][version]
+		rawcodewords = QrCode._get_num_raw_data_modules(version) // 8
+		numshortblocks = numblocks - rawcodewords % numblocks
+		shortblocklen = rawcodewords // numblocks
+		
+		# Split data into blocks and append ECC to each block
+		blocks = []
+		rs = _ReedSolomonGenerator(blockecclen)
+		k = 0
+		for i in range(numblocks):
+			dat = data[k : k + shortblocklen - blockecclen + (0 if i < numshortblocks else 1)]
+			k += len(dat)
+			ecc = rs.get_remainder(dat)
+			if i < numshortblocks:
+				dat.append(0)
+			dat.extend(ecc)
+			blocks.append(dat)
+		assert k == len(data)
+		
+		# Interleave (not concatenate) the bytes from every block into a single sequence
+		result = []
+		for i in range(len(blocks[0])):
+			for (j, blk) in enumerate(blocks):
+				# Skip the padding byte in short blocks
+				if i != shortblocklen - blockecclen or j >= numshortblocks:
+					result.append(blk[i])
+		assert len(result) == rawcodewords
+		return result
+	
+	
+	def _draw_codewords(self, data):
+		"""Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
+		data area of this QR Code symbol. Function modules need to be marked off before this is called."""
+		assert len(data) == QrCode._get_num_raw_data_modules(self._version) // 8
+		
+		i = 0  # Bit index into the data
+		# Do the funny zigzag scan
+		for right in range(self._size - 1, 0, -2):  # Index of right column in each column pair
+			if right <= 6:
+				right -= 1
+			for vert in range(self._size):  # Vertical counter
+				for j in range(2):
+					x = right - j  # Actual x coordinate
+					upward = (right + 1) & 2 == 0
+					y = (self._size - 1 - vert) if upward else vert  # Actual y coordinate
+					if not self._isfunction[y][x] and i < len(data) * 8:
+						self._modules[y][x] = (data[i >> 3] >> (7 - (i & 7))) & 1 != 0
+						i += 1
+					# If there are any remainder bits (0 to 7), they are already
+					# set to 0/false/white when the grid of modules was initialized
+		assert i == len(data) * 8
+	
+	
+	def _apply_mask(self, mask):
+		"""XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
+		properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
+		This means it is possible to apply a mask, undo it, and try another mask. Note that a final
+		well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.)."""
+		if not (0 <= mask <= 7):
+			raise ValueError("Mask value out of range")
+		masker = QrCode._MASK_PATTERNS[mask]
+		for y in range(self._size):
+			for x in range(self._size):
+				self._modules[y][x] ^= (masker(x, y) == 0) and (not self._isfunction[y][x])
+	
+	
+	def _get_penalty_score(self):
+		"""Calculates and returns the penalty score based on state of this QR Code's current modules.
+		This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score."""
+		result = 0
+		size = self._size
+		modules = self._modules
+		
+		# Adjacent modules in row having same color
+		for y in range(size):
+			for x in range(size):
+				if x == 0 or modules[y][x] != colorx:
+					colorx = modules[y][x]
+					runx = 1
+				else:
+					runx += 1
+					if runx == 5:
+						result += QrCode._PENALTY_N1
+					elif runx > 5:
+						result += 1
+		# Adjacent modules in column having same color
+		for x in range(size):
+			for y in range(size):
+				if y == 0 or modules[y][x] != colory:
+					colory = modules[y][x]
+					runy = 1
+				else:
+					runy += 1
+					if runy == 5:
+						result += QrCode._PENALTY_N1
+					elif runy > 5:
+						result += 1
+		
+		# 2*2 blocks of modules having same color
+		for y in range(size - 1):
+			for x in range(size - 1):
+				if modules[y][x] == modules[y][x + 1] == modules[y + 1][x] == modules[y + 1][x + 1]:
+					result += QrCode._PENALTY_N2
+		
+		# Finder-like pattern in rows
+		for y in range(size):
+			bits = 0
+			for x in range(size):
+				bits = ((bits << 1) & 0x7FF) | (1 if modules[y][x] else 0)
+				if x >= 10 and bits in (0x05D, 0x5D0):  # Needs 11 bits accumulated
+					result += QrCode._PENALTY_N3
+		# Finder-like pattern in columns
+		for x in range(size):
+			bits = 0
+			for y in range(size):
+				bits = ((bits << 1) & 0x7FF) | (1 if modules[y][x] else 0)
+				if y >= 10 and bits in (0x05D, 0x5D0):  # Needs 11 bits accumulated
+					result += QrCode._PENALTY_N3
+		
+		# Balance of black and white modules
+		black = sum((1 if cell else 0) for row in modules for cell in row)
+		total = size**2
+		# Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
+		for k in itertools.count():
+			if (9-k)*total <= black*20 <= (11+k)*total:
+				break
+			result += QrCode._PENALTY_N4
+		return result
+	
+	
+	# ---- Private static helper functions ----
+	
+	@staticmethod
+	def _get_alignment_pattern_positions(ver):
+		"""Returns a sequence of positions of the alignment patterns in ascending order. These positions are
+		used on both the x and y axes. Each value in the resulting sequence is in the range [0, 177).
+		This stateless pure function could be implemented as table of 40 variable-length lists of integers."""
+		if not (QrCode.MIN_VERSION <= ver <= QrCode.MAX_VERSION):
+			raise ValueError("Version number out of range")
+		elif ver == 1:
+			return []
+		else:
+			numalign = ver // 7 + 2
+			if ver != 32:
+				# ceil((size - 13) / (2*numalign - 2)) * 2
+				step = (ver * 4 + numalign * 2 + 1) // (2 * numalign - 2) * 2
+			else:  # C-C-C-Combo breaker!
+				step = 26
+			result = [6]
+			pos = ver * 4 + 10
+			for _ in range(numalign - 1):
+				result.insert(1, pos)
+				pos -= step
+			return result
+	
+	
+	@staticmethod
+	def _get_num_raw_data_modules(ver):
+		"""Returns the number of data bits that can be stored in a QR Code of the given version number, after
+		all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
+		The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table."""
+		if not (QrCode.MIN_VERSION <= ver <= QrCode.MAX_VERSION):
+			raise ValueError("Version number out of range")
+		result = (16 * ver + 128) * ver + 64
+		if ver >= 2:
+			numalign = ver // 7 + 2
+			result -= (25 * numalign - 10) * numalign - 55
+			if ver >= 7:
+				result -= 18 * 2  # Subtract version information
+		return result
+	
+	
+	@staticmethod
+	def _get_num_data_codewords(ver, ecl):
+		"""Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
+		QR Code of the given version number and error correction level, with remainder bits discarded.
+		This stateless pure function could be implemented as a (40*4)-cell lookup table."""
+		if not (QrCode.MIN_VERSION <= ver <= QrCode.MAX_VERSION):
+			raise ValueError("Version number out of range")
+		return QrCode._get_num_raw_data_modules(ver) // 8 \
+			- QrCode._ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] \
+			* QrCode._NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver]
+	
+	
+	# ---- Private tables of constants ----
+	
+	# For use in getPenaltyScore(), when evaluating which mask is best.
+	_PENALTY_N1 = 3
+	_PENALTY_N2 = 3
+	_PENALTY_N3 = 40
+	_PENALTY_N4 = 10
+	
+	_ECC_CODEWORDS_PER_BLOCK = (
+		# Version: (note that index 0 is for padding, and is set to an illegal value)
+		#   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+		(None,  7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30),  # Low
+		(None, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28),  # Medium
+		(None, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30),  # Quartile
+		(None, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30))  # High
+	
+	_NUM_ERROR_CORRECTION_BLOCKS = (
+		# Version: (note that index 0 is for padding, and is set to an illegal value)
+		#   0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+		(None, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25),  # Low
+		(None, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49),  # Medium
+		(None, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68),  # Quartile
+		(None, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81))  # High
+	
+	_MASK_PATTERNS = (
+		(lambda x, y:  (x + y) % 2                  ),
+		(lambda x, y:  y % 2                        ),
+		(lambda x, y:  x % 3                        ),
+		(lambda x, y:  (x + y) % 3                  ),
+		(lambda x, y:  (x // 3 + y // 2) % 2        ),
+		(lambda x, y:  x * y % 2 + x * y % 3        ),
+		(lambda x, y:  (x * y % 2 + x * y % 3) % 2  ),
+		(lambda x, y:  ((x + y) % 2 + x * y % 3) % 2),
+	)
+	
+	
+	# ---- Public helper enumeration ----
+	
+	class Ecc(object):
+		"""Represents the error correction level used in a QR Code symbol."""
+		# Private constructor
+		def __init__(self, i, fb):
+			self.ordinal = i  # (Public) In the range 0 to 3 (unsigned 2-bit integer)
+			self.formatbits = fb  # (Package-private) In the range 0 to 3 (unsigned 2-bit integer)
+	
+	# Public constants. Create them outside the class.
+	Ecc.LOW      = Ecc(0, 1)
+	Ecc.MEDIUM   = Ecc(1, 0)
+	Ecc.QUARTILE = Ecc(2, 3)
+	Ecc.HIGH     = Ecc(3, 2)
+
+
+
+# ---- Data segment class ----
+
+class QrSegment(object):
+	"""Represents a character string to be encoded in a QR Code symbol. Each segment has
+	a mode, and a sequence of characters that is already encoded as a sequence of bits.
+	Instances of this class are immutable.
+	This segment class imposes no length restrictions, but QR Codes have restrictions.
+	Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
+	Any segment longer than this is meaningless for the purpose of generating QR Codes."""
+	
+	# ---- Public static factory functions ----
+	
+	@staticmethod
+	def make_bytes(data):
+		"""Returns a segment representing the given binary data encoded in byte mode."""
+		py3 = sys.version_info.major >= 3
+		if (py3 and isinstance(data, str)) or (not py3 and isinstance(data, unicode)):
+			raise TypeError("Byte string/list expected")
+		if not py3 and isinstance(data, str):
+			data = bytearray(data)
+		bb = _BitBuffer()
+		for b in data:
+			bb.append_bits(b, 8)
+		return QrSegment(QrSegment.Mode.BYTE, len(data), bb)
+	
+	
+	@staticmethod
+	def make_numeric(digits):
+		"""Returns a segment representing the given string of decimal digits encoded in numeric mode."""
+		if QrSegment.NUMERIC_REGEX.match(digits) is None:
+			raise ValueError("String contains non-numeric characters")
+		bb = _BitBuffer()
+		for i in range(0, len(digits) - 2, 3):  # Process groups of 3
+			bb.append_bits(int(digits[i : i + 3]), 10)
+		rem = len(digits) % 3
+		if rem > 0:  # 1 or 2 digits remaining
+			bb.append_bits(int(digits[-rem : ]), rem * 3 + 1)
+		return QrSegment(QrSegment.Mode.NUMERIC, len(digits), bb)
+	
+	
+	@staticmethod
+	def make_alphanumeric(text):
+		"""Returns a segment representing the given text string encoded in alphanumeric mode.
+		The characters allowed are: 0 to 9, A to Z (uppercase only), space,
+		dollar, percent, asterisk, plus, hyphen, period, slash, colon."""
+		if QrSegment.ALPHANUMERIC_REGEX.match(text) is None:
+			raise ValueError("String contains unencodable characters in alphanumeric mode")
+		bb = _BitBuffer()
+		for i in range(0, len(text) - 1, 2):  # Process groups of 2
+			temp = QrSegment._ALPHANUMERIC_ENCODING_TABLE[text[i]] * 45
+			temp += QrSegment._ALPHANUMERIC_ENCODING_TABLE[text[i + 1]]
+			bb.append_bits(temp, 11)
+		if len(text) % 2 > 0:  # 1 character remaining
+			bb.append_bits(QrSegment._ALPHANUMERIC_ENCODING_TABLE[text[-1]], 6)
+		return QrSegment(QrSegment.Mode.ALPHANUMERIC, len(text), bb)
+	
+	
+	@staticmethod
+	def make_segments(text):
+		"""Returns a new mutable list of zero or more segments to represent the given Unicode text string.
+		The result may use various segment modes and switch modes to optimize the length of the bit stream."""
+		if not (isinstance(text, str) or (sys.version_info.major < 3 and isinstance(text, unicode))):
+			raise TypeError("Text string expected")
+		
+		# Select the most efficient segment encoding automatically
+		if text == "":
+			return []
+		elif QrSegment.NUMERIC_REGEX.match(text) is not None:
+			return [QrSegment.make_numeric(text)]
+		elif QrSegment.ALPHANUMERIC_REGEX.match(text) is not None:
+			return [QrSegment.make_alphanumeric(text)]
+		else:
+			return [QrSegment.make_bytes(text.encode("UTF-8"))]
+	
+	
+	@staticmethod
+	def make_eci(assignval):
+		"""Returns a segment representing an Extended Channel Interpretation
+		(ECI) designator with the given assignment value."""
+		bb = _BitBuffer()
+		if 0 <= assignval < (1 << 7):
+			bb.append_bits(assignval, 8)
+		elif (1 << 7) <= assignval < (1 << 14):
+			bb.append_bits(2, 2)
+			bb.append_bits(assignval, 14)
+		elif (1 << 14) <= assignval < 1000000:
+			bb.append_bits(6, 3)
+			bb.append_bits(assignval, 21)
+		else:
+			raise ValueError("ECI assignment value out of range")
+		return QrSegment(QrSegment.Mode.ECI, 0, bb)
+	
+	
+	# ---- Constructor ----
+	
+	def __init__(self, mode, numch, bitdata):
+		if numch < 0 or not isinstance(mode, QrSegment.Mode):
+			raise ValueError()
+		self._mode = mode
+		self._numchars = numch
+		self._bitdata = list(bitdata)  # Make defensive copy
+	
+	
+	# ---- Accessor methods ----
+	
+	def get_mode(self):
+		return self._mode
+	
+	def get_num_chars(self):
+		return self._numchars
+	
+	def get_bits(self):
+		return list(self._bitdata)  # Make defensive copy
+	
+	
+	# Package-private helper function.
+	@staticmethod
+	def get_total_bits(segs, version):
+		if not (QrCode.MIN_VERSION <= version <= QrCode.MAX_VERSION):
+			raise ValueError("Version number out of range")
+		result = 0
+		for seg in segs:
+			ccbits = seg.get_mode().num_char_count_bits(version)
+			# Fail if segment length value doesn't fit in the length field's bit-width
+			if seg.get_num_chars() >= (1 << ccbits):
+				return None
+			result += 4 + ccbits + len(seg._bitdata)
+		return result
+	
+	
+	# ---- Constants ----
+	
+	# (Public) Can test whether a string is encodable in numeric mode (such as by using make_numeric())
+	NUMERIC_REGEX = re.compile(r"[0-9]*\Z")
+	
+	# (Public) Can test whether a string is encodable in alphanumeric mode (such as by using make_alphanumeric())
+	ALPHANUMERIC_REGEX = re.compile(r"[A-Z0-9 $%*+./:-]*\Z")
+	
+	# (Private) Dictionary of "0"->0, "A"->10, "$"->37, etc.
+	_ALPHANUMERIC_ENCODING_TABLE = {ch: i for (i, ch) in enumerate("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:")}
+	
+	
+	# ---- Public helper enumeration ----
+	
+	class Mode(object):
+		"""The mode field of a segment. Immutable."""
+		
+		# Private constructor
+		def __init__(self, modebits, charcounts):
+			self._modebits = modebits
+			self._charcounts = charcounts
+		
+		# Package-private method
+		def get_mode_bits(self):
+			"""Returns an unsigned 4-bit integer value (range 0 to 15) representing the mode indicator bits for this mode object."""
+			return self._modebits
+		
+		# Package-private method
+		def num_char_count_bits(self, ver):
+			"""Returns the bit width of the segment character count field for this mode object at the given version number."""
+			if    1 <= ver <=  9:  return self._charcounts[0]
+			elif 10 <= ver <= 26:  return self._charcounts[1]
+			elif 27 <= ver <= 40:  return self._charcounts[2]
+			else:  raise ValueError("Version number out of range")
+	
+	# Public constants. Create them outside the class.
+	Mode.NUMERIC      = Mode(0x1, (10, 12, 14))
+	Mode.ALPHANUMERIC = Mode(0x2, ( 9, 11, 13))
+	Mode.BYTE         = Mode(0x4, ( 8, 16, 16))
+	Mode.KANJI        = Mode(0x8, ( 8, 10, 12))
+	Mode.ECI          = Mode(0x7, ( 0,  0,  0))
+
+
+
+# ---- Private helper classes ----
+
+class _ReedSolomonGenerator(object):
+	"""Computes the Reed-Solomon error correction codewords for a sequence of data codewords
+	at a given degree. Objects are immutable, and the state only depends on the degree.
+	This class exists because each data block in a QR Code shares the same the divisor polynomial."""
+	
+	def __init__(self, degree):
+		"""Creates a Reed-Solomon ECC generator for the given degree. This could be implemented
+		as a lookup table over all possible parameter values, instead of as an algorithm."""
+		if degree < 1 or degree > 255:
+			raise ValueError("Degree out of range")
+		
+		# Start with the monomial x^0
+		self.coefficients = [0] * (degree - 1) + [1]
+		
+		# Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
+		# drop the highest term, and store the rest of the coefficients in order of descending powers.
+		# Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
+		root = 1
+		for _ in range(degree):  # Unused variable i
+			# Multiply the current product by (x - r^i)
+			for j in range(degree):
+				self.coefficients[j] = _ReedSolomonGenerator._multiply(self.coefficients[j], root)
+				if j + 1 < degree:
+					self.coefficients[j] ^= self.coefficients[j + 1]
+			root = _ReedSolomonGenerator._multiply(root, 0x02)
+	
+	
+	def get_remainder(self, data):
+		"""Computes and returns the Reed-Solomon error correction codewords for the given
+		sequence of data codewords. The returned object is always a new byte list.
+		This method does not alter this object's state (because it is immutable)."""
+		# Compute the remainder by performing polynomial division
+		result = [0] * len(self.coefficients)
+		for b in data:
+			factor = b ^ result.pop(0)
+			result.append(0)
+			for i in range(len(result)):
+				result[i] ^= _ReedSolomonGenerator._multiply(self.coefficients[i], factor)
+		return result
+	
+	
+	@staticmethod
+	def _multiply(x, y):
+		"""Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
+		are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8."""
+		if x >> 8 != 0 or y >> 8 != 0:
+			raise ValueError("Byte out of range")
+		# Russian peasant multiplication
+		z = 0
+		for i in reversed(range(8)):
+			z = (z << 1) ^ ((z >> 7) * 0x11D)
+			z ^= ((y >> i) & 1) * x
+		assert z >> 8 == 0
+		return z
+
+
+
+class _BitBuffer(list):
+	"""An appendable sequence of bits (0's and 1's)."""
+	
+	def get_bytes(self):
+		"""Packs this buffer's bits into bytes in big endian,
+		padding with '0' bit values, and returns the new list."""
+		result = [0] * ((len(self) + 7) // 8)
+		for (i, bit) in enumerate(self):
+			result[i >> 3] |= bit << (7 - (i & 7))
+		return result
+	
+	def append_bits(self, val, n):
+		"""Appends the given number of low bits of the given value
+		to this sequence. Requires 0 <= val < 2^n."""
+		if n < 0 or val >> n != 0:
+			raise ValueError("Value out of range")
+		self.extend(((val >> i) & 1) for i in reversed(range(n)))
diff --git a/src/third_party/QR-Code-generator/python/setup.cfg b/src/third_party/QR-Code-generator/python/setup.cfg
new file mode 100644
index 0000000..2a9acf1
--- /dev/null
+++ b/src/third_party/QR-Code-generator/python/setup.cfg
@@ -0,0 +1,2 @@
+[bdist_wheel]
+universal = 1
diff --git a/src/third_party/QR-Code-generator/python/setup.py b/src/third_party/QR-Code-generator/python/setup.py
new file mode 100644
index 0000000..6026451
--- /dev/null
+++ b/src/third_party/QR-Code-generator/python/setup.py
@@ -0,0 +1,113 @@
+# 
+# QR Code generator Distutils script (Python 2, 3)
+# 
+# Copyright (c) Project Nayuki. (MIT License)
+# https://www.nayuki.io/page/qr-code-generator-library
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+# - The above copyright notice and this permission notice shall be included in
+#   all copies or substantial portions of the Software.
+# - The Software is provided "as is", without warranty of any kind, express or
+#   implied, including but not limited to the warranties of merchantability,
+#   fitness for a particular purpose and noninfringement. In no event shall the
+#   authors or copyright holders be liable for any claim, damages or other
+#   liability, whether in an action of contract, tort or otherwise, arising from,
+#   out of or in connection with the Software or the use or other dealings in the
+#   Software.
+# 
+
+import setuptools
+
+
+setuptools.setup(
+	name = "qrcodegen",
+	description = "High quality QR Code generator library for Python 2 and 3",
+	version = "1.2.0",
+	platforms = "OS Independent",
+	license = "MIT License",
+	
+	author = "Project Nayuki",
+	author_email = "me@nayuki.io",
+	url = "https://www.nayuki.io/page/qr-code-generator-library",
+	
+	classifiers = [
+		"Development Status :: 5 - Production/Stable",
+		"Intended Audience :: Developers",
+		"Intended Audience :: Information Technology",
+		"License :: OSI Approved :: MIT License",
+		"Operating System :: OS Independent",
+		"Programming Language :: Python",
+		"Programming Language :: Python :: 2",
+		"Programming Language :: Python :: 3",
+		"Topic :: Multimedia :: Graphics",
+		"Topic :: Software Development :: Libraries :: Python Modules",
+	],
+	
+	long_description = """=========================
+QR Code generator library
+=========================
+
+
+Introduction
+------------
+
+This project aims to be the best, clearest QR Code generator library. The primary goals are flexible options and absolute correctness. Secondary goals are compact implementation size and good documentation comments.
+
+Home page with live JavaScript demo, extensive descriptions, and competitor comparisons: https://www.nayuki.io/page/qr-code-generator-library
+
+
+Features
+--------
+
+Core features:
+
+* Available in 6 programming languages, all with nearly equal functionality: Java, JavaScript, Python, C++, C, Rust
+* Significantly shorter code but more documentation comments compared to competing libraries
+* Supports encoding all 40 versions (sizes) and all 4 error correction levels, as per the QR Code Model 2 standard
+* Output formats: Raw modules/pixels of the QR symbol, SVG XML string
+* Encodes numeric and special-alphanumeric text in less space than general text
+* Open source code under the permissive MIT License
+
+Manual parameters:
+
+* User can specify minimum and maximum version numbers allowed, then library will automatically choose smallest version in the range that fits the data
+* User can specify mask pattern manually, otherwise library will automatically evaluate all 8 masks and select the optimal one
+* User can specify absolute error correction level, or allow the library to boost it if it doesn't increase the version number
+* User can create a list of data segments manually and add ECI segments
+
+
+Usage
+-----
+
+Install this package by downloading the source code ZIP file from PyPI_, or by running ``pip install qrcodegen``.
+
+Examples:
+
+    from qrcodegen import *
+    
+    # Simple operation
+    qr0 = QrCode.encode_text("Hello, world!", QrCode.Ecc.MEDIUM)
+    svg = qr0.to_svg_str(4)
+    
+    # Manual operation
+    segs = QrSegment.make_segments("3141592653589793238462643383")
+    qr1 = QrCode.encode_segments(segs, QrCode.Ecc.HIGH, 5, 5, 2, False)
+    border = 4
+    for y in range(-border, qr1.get_size() + border):
+        for x in range(-border, qr1.get_size() + border):
+            color = qr1.get_module(x, y)  # False for white, True for black
+            # (... paint the module onto pixels ...)
+
+More complete set of examples: https://github.com/nayuki/QR-Code-generator/blob/master/python/qrcodegen-demo.py .
+
+API documentation is in the source file itself, with a summary comment at the top: https://github.com/nayuki/QR-Code-generator/blob/master/python/qrcodegen.py .
+
+.. _PyPI: https://pypi.python.org/pypi/qrcodegen""",
+	
+	py_modules = ["qrcodegen"],
+)
diff --git a/src/third_party/QR-Code-generator/rust/Cargo.toml b/src/third_party/QR-Code-generator/rust/Cargo.toml
new file mode 100644
index 0000000..4fe927c
--- /dev/null
+++ b/src/third_party/QR-Code-generator/rust/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "qrcodegen"
+version = "1.2.1"
+authors = ["Project Nayuki"]
+description = "High-quality QR Code generator library"
+homepage = "https://www.nayuki.io/page/qr-code-generator-library"
+repository = "https://github.com/nayuki/QR-Code-generator"
+readme = "Readme.markdown"
+keywords = ["qr-code", "barcode", "encoder", "image"]
+categories = ["encoding", "multimedia::images"]
+license = "MIT"
diff --git a/src/third_party/QR-Code-generator/rust/Readme.markdown b/src/third_party/QR-Code-generator/rust/Readme.markdown
new file mode 100644
index 0000000..fd8cb50
--- /dev/null
+++ b/src/third_party/QR-Code-generator/rust/Readme.markdown
@@ -0,0 +1,57 @@
+QR Code generator library
+=========================
+
+
+Introduction
+------------
+
+This project aims to be the best, clearest QR Code generator library. The primary goals are flexible options and absolute correctness. Secondary goals are compact implementation size and good documentation comments.
+
+Home page with live JavaScript demo, extensive descriptions, and competitor comparisons: https://www.nayuki.io/page/qr-code-generator-library
+
+
+Features
+--------
+
+Core features:
+
+* Available in 6 programming languages, all with nearly equal functionality: Java, JavaScript, Python, C++, C, Rust
+* Significantly shorter code but more documentation comments compared to competing libraries
+* Supports encoding all 40 versions (sizes) and all 4 error correction levels, as per the QR Code Model 2 standard
+* Output formats: Raw modules/pixels of the QR symbol, SVG XML string
+* Encodes numeric and special-alphanumeric text in less space than general text
+* Open source code under the permissive MIT License
+
+Manual parameters:
+
+* User can specify minimum and maximum version numbers allowed, then library will automatically choose smallest version in the range that fits the data
+* User can specify mask pattern manually, otherwise library will automatically evaluate all 8 masks and select the optimal one
+* User can specify absolute error correction level, or allow the library to boost it if it doesn't increase the version number
+* User can create a list of data segments manually and add ECI segments
+
+
+Examples
+--------
+
+    extern crate qrcodegen;
+    use qrcodegen::QrCode;
+    use qrcodegen::QrCodeEcc;
+    use qrcodegen::QrSegment;
+    
+    // Simple operation
+    let qr0 = QrCode::encode_text("Hello, world!",
+        QrCodeEcc::Medium).unwrap();
+    let svg = qr0.to_svg_string(4);
+    
+    // Manual operation
+    let chrs: Vec<char> = "3141592653589793238462643383".chars().collect();
+    let segs = QrSegment::make_segments(&chrs);
+    let qr1 = QrCode::encode_segments_advanced(
+        &segs, QrCodeEcc::High, 5, 5, Some(2), false).unwrap();
+    for y in 0 .. qr1.size() {
+        for x in 0 .. qr1.size() {
+            (... paint qr1.get_module(x, y) ...)
+        }
+    }
+
+More complete set of examples: https://github.com/nayuki/QR-Code-generator/blob/master/rust/examples/qrcodegen-demo.rs .
diff --git a/src/third_party/QR-Code-generator/rust/examples/qrcodegen-demo.rs b/src/third_party/QR-Code-generator/rust/examples/qrcodegen-demo.rs
new file mode 100644
index 0000000..1fa2d3f
--- /dev/null
+++ b/src/third_party/QR-Code-generator/rust/examples/qrcodegen-demo.rs
@@ -0,0 +1,184 @@
+/* 
+ * QR Code generator demo (Rust)
+ * 
+ * Run this command-line program with no arguments. The program computes a bunch of demonstration
+ * QR Codes and prints them to the console. Also, the SVG code for one QR Code is printed as a sample.
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+extern crate qrcodegen;
+use qrcodegen::Mask;
+use qrcodegen::QrCode;
+use qrcodegen::QrCodeEcc;
+use qrcodegen::QrSegment;
+use qrcodegen::QrCode_MAX_VERSION;
+use qrcodegen::QrCode_MIN_VERSION;
+
+
+// The main application program.
+fn main() {
+	do_basic_demo();
+	do_variety_demo();
+	do_segment_demo();
+	do_mask_demo();
+}
+
+
+
+/*---- Demo suite ----*/
+
+// Creates a single QR Code, then prints it to the console.
+fn do_basic_demo() {
+	let text: &'static str = "Hello, world!";  // User-supplied Unicode text
+	let errcorlvl: QrCodeEcc = QrCodeEcc::Low;  // Error correction level
+	
+	// Make and print the QR Code symbol
+	let qr: QrCode = QrCode::encode_text(text, errcorlvl).unwrap();
+	print_qr(&qr);
+	println!("{}", qr.to_svg_string(4));
+}
+
+
+// Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console.
+fn do_variety_demo() {
+	// Numeric mode encoding (3.33 bits per digit)
+	let qr = QrCode::encode_text("314159265358979323846264338327950288419716939937510", QrCodeEcc::Medium).unwrap();
+	print_qr(&qr);
+	
+	// Alphanumeric mode encoding (5.5 bits per character)
+	let qr = QrCode::encode_text("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", QrCodeEcc::High).unwrap();
+	print_qr(&qr);
+	
+	// Unicode text as UTF-8
+	let qr = QrCode::encode_text("こんにちwa、世界！ αβγδ", QrCodeEcc::Quartile).unwrap();
+	print_qr(&qr);
+	
+	// Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
+	let qr = QrCode::encode_text(concat!(
+		"Alice was beginning to get very tired of sitting by her sister on the bank, ",
+		"and of having nothing to do: once or twice she had peeped into the book her sister was reading, ",
+		"but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice ",
+		"'without pictures or conversations?' So she was considering in her own mind (as well as she could, ",
+		"for the hot day made her feel very sleepy and stupid), whether the pleasure of making a ",
+		"daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly ",
+		"a White Rabbit with pink eyes ran close by her."), QrCodeEcc::High).unwrap();
+	print_qr(&qr);
+}
+
+
+// Creates QR Codes with manually specified segments for better compactness.
+fn do_segment_demo() {
+	// Illustration "silver"
+	let silver0 = "THE SQUARE ROOT OF 2 IS 1.";
+	let silver1 = "41421356237309504880168872420969807856967187537694807317667973799";
+	let qr = QrCode::encode_text(&[silver0, silver1].concat(), QrCodeEcc::Low).unwrap();
+	print_qr(&qr);
+	
+	let segs = vec![
+		QrSegment::make_alphanumeric(&to_chars(silver0)),
+		QrSegment::make_numeric(&to_chars(silver1)),
+	];
+	let qr = QrCode::encode_segments(&segs, QrCodeEcc::Low).unwrap();
+	print_qr(&qr);
+	
+	// Illustration "golden"
+	let golden0 = "Golden ratio φ = 1.";
+	let golden1 = "6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374";
+	let golden2 = "......";
+	let qr = QrCode::encode_text(&[golden0, golden1, golden2].concat(), QrCodeEcc::Low).unwrap();
+	print_qr(&qr);
+	
+	let segs = vec![
+		QrSegment::make_bytes(golden0.as_bytes()),
+		QrSegment::make_numeric(&to_chars(golden1)),
+		QrSegment::make_alphanumeric(&to_chars(golden2)),
+	];
+	let qr = QrCode::encode_segments(&segs, QrCodeEcc::Low).unwrap();
+	print_qr(&qr);
+	
+	// Illustration "Madoka": kanji, kana, Greek, Cyrillic, full-width Latin characters
+	let madoka = "「魔法少女まどか☆マギカ」って、　ИАИ　ｄｅｓｕ　κα？";
+	let qr = QrCode::encode_text(madoka, QrCodeEcc::Low).unwrap();
+	print_qr(&qr);
+	
+	let kanjichars: Vec<u32> = vec![  // Kanji mode encoding (13 bits per character)
+		0x0035, 0x1002, 0x0FC0, 0x0AED, 0x0AD7,
+		0x015C, 0x0147, 0x0129, 0x0059, 0x01BD,
+		0x018D, 0x018A, 0x0036, 0x0141, 0x0144,
+		0x0001, 0x0000, 0x0249, 0x0240, 0x0249,
+		0x0000, 0x0104, 0x0105, 0x0113, 0x0115,
+		0x0000, 0x0208, 0x01FF, 0x0008,
+	];
+	let mut bb = qrcodegen::BitBuffer(Vec::new());
+	for c in &kanjichars {
+		bb.append_bits(*c, 13);
+	}
+	let segs = vec![
+		QrSegment::new(qrcodegen::QrSegmentMode::Kanji, kanjichars.len(), bb.0),
+	];
+	let qr = QrCode::encode_segments(&segs, QrCodeEcc::Low).unwrap();
+	print_qr(&qr);
+}
+
+
+// Creates QR Codes with the same size and contents but different mask patterns.
+fn do_mask_demo() {
+	// Project Nayuki URL
+	let segs = QrSegment::make_segments(&to_chars("https://www.nayuki.io/"));
+	let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, QrCode_MIN_VERSION, QrCode_MAX_VERSION, None, true).unwrap();  // Automatic mask
+	print_qr(&qr);
+	let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(Mask::new(3)), true).unwrap();  // Force mask 3
+	print_qr(&qr);
+	
+	// Chinese text as UTF-8
+	let segs = QrSegment::make_segments(&to_chars("維基百科（Wikipedia，聆聽i/ˌwɪkᵻˈpiːdi.ə/）是一個自由內容、公開編輯且多語言的網路百科全書協作計畫"));
+	let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(Mask::new(0)), true).unwrap();  // Force mask 0
+	print_qr(&qr);
+	let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(Mask::new(1)), true).unwrap();  // Force mask 1
+	print_qr(&qr);
+	let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(Mask::new(5)), true).unwrap();  // Force mask 5
+	print_qr(&qr);
+	let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(Mask::new(7)), true).unwrap();  // Force mask 7
+	print_qr(&qr);
+}
+
+
+
+/*---- Utilities ----*/
+
+// Prints the given QrCode object to the console.
+fn print_qr(qr: &QrCode) {
+	let border: i32 = 4;
+	for y in -border .. qr.size() + border {
+		for x in -border .. qr.size() + border {
+			let c: char = if qr.get_module(x, y) { '█' } else { ' ' };
+			print!("{0}{0}", c);
+		}
+		println!();
+	}
+	println!();
+}
+
+
+// Converts the given borrowed string slice to a new character vector.
+fn to_chars(text: &str) -> Vec<char> {
+	text.chars().collect()
+}
diff --git a/src/third_party/QR-Code-generator/rust/examples/qrcodegen-worker.rs b/src/third_party/QR-Code-generator/rust/examples/qrcodegen-worker.rs
new file mode 100644
index 0000000..5537f19
--- /dev/null
+++ b/src/third_party/QR-Code-generator/rust/examples/qrcodegen-worker.rs
@@ -0,0 +1,117 @@
+/* 
+ * QR Code generator test worker (Rust)
+ * 
+ * This program reads data and encoding parameters from standard input and writes
+ * QR Code bitmaps to standard output. The I/O format is one integer per line.
+ * Run with no command line arguments. The program is intended for automated
+ * batch testing of end-to-end functionality of this QR Code generator library.
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+extern crate qrcodegen;
+use qrcodegen::Mask;
+use qrcodegen::QrCode;
+use qrcodegen::QrCodeEcc;
+use qrcodegen::QrSegment;
+use qrcodegen::Version;
+
+
+fn main() {
+	loop {
+		
+		// Read data length or exit
+		let length: i16 = read_int();
+		if length == -1 {
+			break;
+		}
+		
+		// Read data bytes
+		let mut data = Vec::<u8>::with_capacity(length as usize);
+		for _ in 0 .. length {
+			let b: i16 = read_int();
+			assert_eq!((b as u8) as i16, b, "Byte value out of range");
+			data.push(b as u8);
+		}
+		let isascii: bool = data.iter().all(|b| *b < 128);
+		
+		// Read encoding parameters
+		let errcorlvl  = read_int();
+		let minversion = read_int();
+		let maxversion = read_int();
+		let mask       = read_int();
+		let boostecl   = read_int();
+		assert!(0 <= errcorlvl && errcorlvl <= 3);
+		assert!((qrcodegen::QrCode_MIN_VERSION.value() as i16) <= minversion
+			&& minversion <= maxversion
+			&& maxversion <= (qrcodegen::QrCode_MAX_VERSION.value() as i16));
+		assert!(-1 <= mask && mask <= 7);
+		assert!(boostecl >> 1 == 0);
+		
+		// Make segments for encoding
+		let segs: Vec<QrSegment>;
+		if isascii {
+			let chrs: Vec<char> = std::str::from_utf8(&data).unwrap().chars().collect();
+			segs = QrSegment::make_segments(&chrs);
+		} else {
+			segs = vec![QrSegment::make_bytes(&data)];
+		}
+		
+		// Try to make QR Code symbol
+		let msk = if mask == -1 { None } else { Some(Mask::new(mask as u8)) };
+		match QrCode::encode_segments_advanced(&segs, ECC_LEVELS[errcorlvl as usize],
+				Version::new(minversion as u8), Version::new(maxversion as u8), msk, boostecl != 0) {
+		
+			Some(qr) => {
+				// Print grid of modules
+				println!("{}", qr.version().value());
+				for y in 0 .. qr.size() {
+					for x in 0 .. qr.size() {
+						println!("{}", qr.get_module(x, y) as i8);
+					}
+				}
+			},
+			None => println!("-1"),
+		}
+		use std::io::Write;
+		std::io::stdout().flush().unwrap();
+	}
+}
+
+
+fn read_int() -> i16 {
+	let mut line = String::new();
+	std::io::stdin().read_line(&mut line).unwrap();
+	let mut chrs: Vec<char> = line.chars().collect();
+	assert_eq!(chrs.pop().unwrap(), '\n');
+	let line: String = chrs.iter().cloned().collect();
+	match line.parse::<i16>() {
+		Ok(x) => x,
+		Err(_) => panic!("Invalid number"),
+	}
+}
+
+
+static ECC_LEVELS: [QrCodeEcc; 4] = [
+	QrCodeEcc::Low,
+	QrCodeEcc::Medium,
+	QrCodeEcc::Quartile,
+	QrCodeEcc::High,
+];
diff --git a/src/third_party/QR-Code-generator/rust/src/lib.rs b/src/third_party/QR-Code-generator/rust/src/lib.rs
new file mode 100644
index 0000000..d4b41ae
--- /dev/null
+++ b/src/third_party/QR-Code-generator/rust/src/lib.rs
@@ -0,0 +1,1117 @@
+/* 
+ * QR Code generator library (Rust)
+ * 
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ * - The Software is provided "as is", without warranty of any kind, express or
+ *   implied, including but not limited to the warranties of merchantability,
+ *   fitness for a particular purpose and noninfringement. In no event shall the
+ *   authors or copyright holders be liable for any claim, damages or other
+ *   liability, whether in an action of contract, tort or otherwise, arising from,
+ *   out of or in connection with the Software or the use or other dealings in the
+ *   Software.
+ */
+
+
+/*---- QrCode functionality ----*/
+
+// Represents an immutable square grid of black and white cells for a QR Code symbol, and
+// provides static functions to create a QR Code from user-supplied textual or binary data.
+// This struct covers the QR Code model 2 specification, supporting all versions (sizes)
+// from 1 to 40, all 4 error correction levels, and only 3 character encoding modes.
+pub struct QrCode {
+	
+	// This QR Code symbol's version number, which is always between 1 and 40 (inclusive).
+	version: Version,
+	
+	// The width and height of this QR Code symbol, measured in modules.
+	// Always equal to version &times; 4 + 17, in the range 21 to 177.
+	size: i32,
+	
+	// The error correction level used in this QR Code symbol.
+	errorcorrectionlevel: QrCodeEcc,
+	
+	// The mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer).
+	// Note that even if a constructor was called with automatic masking requested
+	// (mask = -1), the resulting object will still have a mask value between 0 and 7.
+	mask: Mask,
+	
+	// The modules of this QR Code symbol (false = white, true = black)
+	modules: Vec<bool>,
+	
+	// Indicates function modules that are not subjected to masking
+	isfunction: Vec<bool>,
+	
+}
+
+
+impl QrCode {
+	
+	/*---- Public static factory functions ----*/
+	
+	// Returns a QR Code symbol representing the given Unicode text string at the given error correction level.
+	// As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer Unicode
+	// code points (not UTF-8 code units) if the low error correction level is used. The smallest possible
+	// QR Code version is automatically chosen for the output. The ECC level of the result may be higher than
+	// the ecl argument if it can be done without increasing the version. Returns a wrapped QrCode if successful,
+	// or None if the data is too long to fit in any version at the given ECC level.
+	pub fn encode_text(text: &str, ecl: QrCodeEcc) -> Option<QrCode> {
+		let chrs: Vec<char> = text.chars().collect();
+		let segs: Vec<QrSegment> = QrSegment::make_segments(&chrs);
+		QrCode::encode_segments(&segs, ecl)
+	}
+	
+	
+	// Returns a QR Code symbol representing the given binary data string at the given error correction level.
+	// This function always encodes using the binary segment mode, not any text mode. The maximum number of
+	// bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
+	// The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
+	// Returns a wrapped QrCode if successful, or None if the data is too long to fit in any version at the given ECC level.
+	pub fn encode_binary(data: &[u8], ecl: QrCodeEcc) -> Option<QrCode> {
+		let segs: Vec<QrSegment> = vec![QrSegment::make_bytes(data)];
+		QrCode::encode_segments(&segs, ecl)
+	}
+	
+	
+	// Returns a QR Code symbol representing the given data segments at the given error correction
+	// level or higher. The smallest possible QR Code version is automatically chosen for the output.
+	// This function allows the user to create a custom sequence of segments that switches
+	// between modes (such as alphanumeric and binary) to encode text more efficiently.
+	// This function is considered to be lower level than simply encoding text or binary data.
+	// Returns a wrapped QrCode if successful, or None if the data is too long to fit in any version at the given ECC level.
+	pub fn encode_segments(segs: &[QrSegment], ecl: QrCodeEcc) -> Option<QrCode> {
+		QrCode::encode_segments_advanced(segs, ecl, QrCode_MIN_VERSION, QrCode_MAX_VERSION, None, true)
+	}
+	
+	
+	// Returns a QR Code symbol representing the given data segments with the given encoding parameters.
+	// The smallest possible QR Code version within the given range is automatically chosen for the output.
+	// This function allows the user to create a custom sequence of segments that switches
+	// between modes (such as alphanumeric and binary) to encode text more efficiently.
+	// This function is considered to be lower level than simply encoding text or binary data.
+	// Returns a wrapped QrCode if successful, or None if the data is too long to fit
+	// in any version in the given range at the given ECC level.
+	pub fn encode_segments_advanced(segs: &[QrSegment], mut ecl: QrCodeEcc,
+			minversion: Version, maxversion: Version, mask: Option<Mask>, boostecl: bool) -> Option<QrCode> {
+		assert!(minversion.value() <= maxversion.value(), "Invalid value");
+		
+		// Find the minimal version number to use
+		let mut version = minversion;
+		let datausedbits: usize;
+		loop {
+			// Number of data bits available
+			let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;
+			if let Some(n) = QrSegment::get_total_bits(segs, version) {
+				if n <= datacapacitybits {
+					datausedbits = n;
+					break;  // This version number is found to be suitable
+				}
+			}
+			if version.value() >= maxversion.value() {  // All versions in the range could not fit the given data
+				return None;
+			}
+			version = Version::new(version.value() + 1);
+		}
+		
+		// Increase the error correction level while the data still fits in the current version number
+		for newecl in &[QrCodeEcc::Medium, QrCodeEcc::Quartile, QrCodeEcc::High] {
+			if boostecl && datausedbits <= QrCode::get_num_data_codewords(version, *newecl) * 8 {
+				ecl = *newecl;
+			}
+		}
+		
+		// Create the data bit string by concatenating all segments
+		let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;
+		let mut bb = BitBuffer(Vec::new());
+		for seg in segs {
+			bb.append_bits(seg.mode.mode_bits(), 4);
+			bb.append_bits(seg.numchars as u32, seg.mode.num_char_count_bits(version));
+			bb.0.extend_from_slice(&seg.data);
+		}
+		
+		// Add terminator and pad up to a byte if applicable
+		let numzerobits = std::cmp::min(4, datacapacitybits - bb.0.len());
+		bb.append_bits(0, numzerobits as u8);
+		let numzerobits = bb.0.len().wrapping_neg() & 7;
+		bb.append_bits(0, numzerobits as u8);
+		
+		// Pad with alternate bytes until data capacity is reached
+		let mut padbyte: u32 = 0xEC;
+		while bb.0.len() < datacapacitybits {
+			bb.append_bits(padbyte, 8);
+			padbyte ^= 0xEC ^ 0x11;
+		}
+		assert_eq!(bb.0.len() % 8, 0, "Assertion error");
+		
+		let mut bytes = vec![0u8; bb.0.len() / 8];
+		for (i, bit) in bb.0.iter().enumerate() {
+			bytes[i >> 3] |= (*bit as u8) << (7 - (i & 7));
+		}
+		
+		// Create the QR Code symbol
+		Some(QrCode::encode_codewords(version, ecl, &bytes, mask))
+	}
+	
+	
+	/*---- Constructors ----*/
+	
+	// Creates a new QR Code symbol with the given version number, error correction level,
+	// binary data array, and mask number. This is a cumbersome low-level constructor that
+	// should not be invoked directly by the user. To go one level up, see the encode_segments() function.
+	pub fn encode_codewords(ver: Version, ecl: QrCodeEcc, datacodewords: &[u8], mask: Option<Mask>) -> QrCode {
+		// Initialize fields
+		let size: usize = (ver.value() as usize) * 4 + 17;
+		let mut result = QrCode {
+			version: ver,
+			size: size as i32,
+			mask: Mask::new(0),  // Dummy value
+			errorcorrectionlevel: ecl,
+			modules: vec![false; size * size],  // Entirely white grid
+			isfunction: vec![false; size * size],
+		};
+		
+		// Draw function patterns, draw all codewords, do masking
+		result.draw_function_patterns();
+		let allcodewords: Vec<u8> = result.append_error_correction(datacodewords);
+		result.draw_codewords(&allcodewords);
+		result.handle_constructor_masking(mask);
+		result
+	}
+	
+	
+	// Returns this QR Code's version, in the range [1, 40].
+	pub fn version(&self) -> Version {
+		self.version
+	}
+	
+	
+	// Returns this QR Code's size, in the range [21, 177].
+	pub fn size(&self) -> i32 {
+		self.size
+	}
+	
+	
+	// Returns this QR Code's error correction level.
+	pub fn error_correction_level(&self) -> QrCodeEcc {
+		self.errorcorrectionlevel
+	}
+	
+	
+	// Returns this QR Code's mask, in the range [0, 7].
+	pub fn mask(&self) -> Mask {
+		self.mask
+	}
+	
+	
+	// Returns the color of the module (pixel) at the given coordinates, which is either
+	// false for white or true for black. The top left corner has the coordinates (x=0, y=0).
+	// If the given coordinates are out of bounds, then 0 (white) is returned.
+	pub fn get_module(&self, x: i32, y: i32) -> bool {
+		0 <= x && x < self.size && 0 <= y && y < self.size && self.module(x, y)
+	}
+	
+	
+	// Returns the color of the module at the given coordinates, which must be in bounds.
+	fn module(&self, x: i32, y: i32) -> bool {
+		self.modules[(y * self.size + x) as usize]
+	}
+	
+	
+	// Returns a mutable reference to the module's color at the given coordinates, which must be in bounds.
+	fn module_mut(&mut self, x: i32, y: i32) -> &mut bool {
+		&mut self.modules[(y * self.size + x) as usize]
+	}
+	
+	
+	// Based on the given number of border modules to add as padding, this returns a
+	// string whose contents represents an SVG XML file that depicts this QR Code symbol.
+	// Note that Unix newlines (\n) are always used, regardless of the platform.
+	pub fn to_svg_string(&self, border: i32) -> String {
+		assert!(border >= 0, "Border must be non-negative");
+		let mut result: String = String::new();
+		result.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+		result.push_str("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
+		let dimension = self.size.checked_add(border.checked_mul(2).unwrap()).unwrap();
+		result.push_str(&format!(
+			"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 {0} {0}\" stroke=\"none\">\n", dimension));
+		result.push_str("\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n");
+		result.push_str("\t<path d=\"");
+		let mut head: bool = true;
+		for y in -border .. self.size + border {
+			for x in -border .. self.size + border {
+				if self.get_module(x, y) {
+					if head {
+						head = false;
+					} else {
+						result.push_str(" ");
+					}
+					result.push_str(&format!("M{},{}h1v1h-1z", x + border, y + border));
+				}
+			}
+		}
+		result.push_str("\" fill=\"#000000\"/>\n");
+		result.push_str("</svg>\n");
+		result
+	}
+	
+	
+	/*---- Private helper methods for constructor: Drawing function modules ----*/
+	
+	fn draw_function_patterns(&mut self) {
+		// Draw horizontal and vertical timing patterns
+		let size: i32 = self.size;
+		for i in 0 .. size {
+			self.set_function_module(6, i, i % 2 == 0);
+			self.set_function_module(i, 6, i % 2 == 0);
+		}
+		
+		// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
+		self.draw_finder_pattern(3, 3);
+		self.draw_finder_pattern(size - 4, 3);
+		self.draw_finder_pattern(3, size - 4);
+		
+		// Draw numerous alignment patterns
+		let alignpatpos: Vec<i32> = QrCode::get_alignment_pattern_positions(self.version);
+		let numalign: usize = alignpatpos.len();
+		for i in 0 .. numalign {
+			for j in 0 .. numalign {
+				if i == 0 && j == 0 || i == 0 && j == numalign - 1 || i == numalign - 1 && j == 0 {
+					continue;  // Skip the three finder corners
+				} else {
+					self.draw_alignment_pattern(alignpatpos[i], alignpatpos[j]);
+				}
+			}
+		}
+		
+		// Draw configuration data
+		self.draw_format_bits(Mask::new(0));  // Dummy mask value; overwritten later in the constructor
+		self.draw_version();
+	}
+	
+	
+	// Draws two copies of the format bits (with its own error correction code)
+	// based on the given mask and this object's error correction level field.
+	fn draw_format_bits(&mut self, mask: Mask) {
+		// Calculate error correction code and pack bits
+		let size: i32 = self.size;
+		// errcorrlvl is uint2, mask is uint3
+		let mut data: u32 = self.errorcorrectionlevel.format_bits() << 3 | (mask.value() as u32);
+		let mut rem: u32 = data;
+		for _ in 0 .. 10 {
+			rem = (rem << 1) ^ ((rem >> 9) * 0x537);
+		}
+		data = data << 10 | rem;
+		data ^= 0x5412;  // uint15
+		assert_eq!(data >> 15, 0, "Assertion error");
+		
+		// Draw first copy
+		for i in 0 .. 6 {
+			self.set_function_module(8, i, (data >> i) & 1 != 0);
+		}
+		self.set_function_module(8, 7, (data >> 6) & 1 != 0);
+		self.set_function_module(8, 8, (data >> 7) & 1 != 0);
+		self.set_function_module(7, 8, (data >> 8) & 1 != 0);
+		for i in 9 .. 15 {
+			self.set_function_module(14 - i, 8, (data >> i) & 1 != 0);
+		}
+		
+		// Draw second copy
+		for i in 0 .. 8 {
+			self.set_function_module(size - 1 - i, 8, (data >> i) & 1 != 0);
+		}
+		for i in 8 .. 15 {
+			self.set_function_module(8, size - 15 + i, (data >> i) & 1 != 0);
+		}
+		self.set_function_module(8, size - 8, true);
+	}
+	
+	
+	// Draws two copies of the version bits (with its own error correction code),
+	// based on this object's version field (which only has an effect for 7 <= version <= 40).
+	fn draw_version(&mut self) {
+		if self.version.value() < 7 {
+			return;
+		}
+		
+		// Calculate error correction code and pack bits
+		let mut rem: u32 = self.version.value() as u32;  // version is uint6, in the range [7, 40]
+		for _ in 0 .. 12 {
+			rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
+		}
+		let data: u32 = (self.version.value() as u32) << 12 | rem;  // uint18
+		assert!(data >> 18 == 0, "Assertion error");
+		
+		// Draw two copies
+		for i in 0 .. 18 {
+			let bit: bool = (data >> i) & 1 != 0;
+			let a: i32 = self.size - 11 + i % 3;
+			let b: i32 = i / 3;
+			self.set_function_module(a, b, bit);
+			self.set_function_module(b, a, bit);
+		}
+	}
+	
+	
+	// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y).
+	fn draw_finder_pattern(&mut self, x: i32, y: i32) {
+		for i in -4 .. 5 {
+			for j in -4 .. 5 {
+				let xx: i32 = x + j;
+				let yy: i32 = y + i;
+				if 0 <= xx && xx < self.size && 0 <= yy && yy < self.size {
+					let dist: i32 = std::cmp::max(i.abs(), j.abs());  // Chebyshev/infinity norm
+					self.set_function_module(xx, yy, dist != 2 && dist != 4);
+				}
+			}
+		}
+	}
+	
+	
+	// Draws a 5*5 alignment pattern, with the center module at (x, y).
+	fn draw_alignment_pattern(&mut self, x: i32, y: i32) {
+		for i in -2 .. 3 {
+			for j in -2 .. 3 {
+				self.set_function_module(x + j, y + i, std::cmp::max(i.abs(), j.abs()) != 1);
+			}
+		}
+	}
+	
+	
+	// Sets the color of a module and marks it as a function module.
+	// Only used by the constructor. Coordinates must be in range.
+	fn set_function_module(&mut self, x: i32, y: i32, isblack: bool) {
+		*self.module_mut(x, y) = isblack;
+		self.isfunction[(y * self.size + x) as usize] = true;
+	}
+	
+	
+	/*---- Private helper methods for constructor: Codewords and masking ----*/
+	
+	// Returns a new byte string representing the given data with the appropriate error correction
+	// codewords appended to it, based on this object's version and error correction level.
+	fn append_error_correction(&self, data: &[u8]) -> Vec<u8> {
+		assert_eq!(data.len(), QrCode::get_num_data_codewords(self.version, self.errorcorrectionlevel), "Illegal argument");
+		
+		// Calculate parameter numbers
+		let numblocks: usize = QrCode::table_get(&NUM_ERROR_CORRECTION_BLOCKS, self.version, self.errorcorrectionlevel);
+		let blockecclen: usize = QrCode::table_get(&ECC_CODEWORDS_PER_BLOCK, self.version, self.errorcorrectionlevel);
+		let rawcodewords: usize = QrCode::get_num_raw_data_modules(self.version) / 8;
+		let numshortblocks: usize = numblocks - rawcodewords % numblocks;
+		let shortblocklen: usize = rawcodewords / numblocks;
+		
+		// Split data into blocks and append ECC to each block
+		let mut blocks = Vec::<Vec<u8>>::with_capacity(numblocks);
+		let rs = ReedSolomonGenerator::new(blockecclen);
+		let mut k: usize = 0;
+		for i in 0 .. numblocks {
+			let mut dat = Vec::<u8>::with_capacity(shortblocklen + 1);
+			dat.extend_from_slice(&data[k .. k + shortblocklen - blockecclen + ((i >= numshortblocks) as usize)]);
+			k += dat.len();
+			let ecc: Vec<u8> = rs.get_remainder(&dat);
+			if i < numshortblocks {
+				dat.push(0);
+			}
+			dat.extend_from_slice(&ecc);
+			blocks.push(dat);
+		}
+		
+		// Interleave (not concatenate) the bytes from every block into a single sequence
+		let mut result = Vec::<u8>::with_capacity(rawcodewords);
+		for i in 0 .. shortblocklen + 1 {
+			for j in 0 .. numblocks {
+				// Skip the padding byte in short blocks
+				if i != shortblocklen - blockecclen || j >= numshortblocks {
+					result.push(blocks[j][i]);
+				}
+			}
+		}
+		result
+	}
+	
+	
+	// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
+	// data area of this QR Code symbol. Function modules need to be marked off before this is called.
+	fn draw_codewords(&mut self, data: &[u8]) {
+		assert_eq!(data.len(), QrCode::get_num_raw_data_modules(self.version) / 8, "Illegal argument");
+		
+		let mut i: usize = 0;  // Bit index into the data
+		// Do the funny zigzag scan
+		let mut right: i32 = self.size - 1;
+		while right >= 1 {  // Index of right column in each column pair
+			if right == 6 {
+				right = 5;
+			}
+			for vert in 0 .. self.size {  // Vertical counter
+				for j in 0 .. 2 {
+					let x: i32 = right - j;  // Actual x coordinate
+					let upward: bool = (right + 1) & 2 == 0;
+					let y: i32 = if upward { self.size - 1 - vert } else { vert };  // Actual y coordinate
+					if !self.isfunction[(y * self.size + x) as usize] && i < data.len() * 8 {
+						*self.module_mut(x, y) = (data[i >> 3] >> (7 - (i & 7))) & 1 != 0;
+						i += 1;
+					}
+					// If there are any remainder bits (0 to 7), they are already
+					// set to 0/false/white when the grid of modules was initialized
+				}
+			}
+			right -= 2;
+		}
+		assert_eq!(i, data.len() * 8, "Assertion error");
+	}
+	
+	
+	// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
+	// properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
+	// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
+	// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
+	fn apply_mask(&mut self, mask: Mask) {
+		let mask = mask.value();
+		for y in 0 .. self.size {
+			for x in 0 .. self.size {
+				let invert: bool = match mask {
+					0 => (x + y) % 2 == 0,
+					1 => y % 2 == 0,
+					2 => x % 3 == 0,
+					3 => (x + y) % 3 == 0,
+					4 => (x / 3 + y / 2) % 2 == 0,
+					5 => x * y % 2 + x * y % 3 == 0,
+					6 => (x * y % 2 + x * y % 3) % 2 == 0,
+					7 => ((x + y) % 2 + x * y % 3) % 2 == 0,
+					_ => unreachable!(),
+				};
+				*self.module_mut(x, y) ^= invert & !self.isfunction[(y * self.size + x) as usize];
+			}
+		}
+	}
+	
+	
+	// A messy helper function for the constructors. This QR Code must be in an unmasked state when this
+	// method is called. The given argument is the requested mask, which is -1 for auto or 0 to 7 for fixed.
+	// This method applies and returns the actual mask chosen, from 0 to 7.
+	fn handle_constructor_masking(&mut self, mut mask: Option<Mask>) {
+		if mask.is_none() {  // Automatically choose best mask
+			let mut minpenalty: i32 = std::i32::MAX;
+			for i in 0u8 .. 8 {
+				let newmask = Mask::new(i);
+				self.draw_format_bits(newmask);
+				self.apply_mask(newmask);
+				let penalty: i32 = self.get_penalty_score();
+				if penalty < minpenalty {
+					mask = Some(newmask);
+					minpenalty = penalty;
+				}
+				self.apply_mask(newmask);  // Undoes the mask due to XOR
+			}
+		}
+		let msk: Mask = mask.unwrap();
+		self.draw_format_bits(msk);  // Overwrite old format bits
+		self.apply_mask(msk);  // Apply the final choice of mask
+		self.mask = msk;
+	}
+	
+	
+	// Calculates and returns the penalty score based on state of this QR Code's current modules.
+	// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
+	fn get_penalty_score(&self) -> i32 {
+		let mut result: i32 = 0;
+		let size: i32 = self.size;
+		
+		// Adjacent modules in row having same color
+		for y in 0 .. size {
+			let mut colorx: bool = false;
+			let mut runx: i32 = 0;
+			for x in 0 .. size {
+				if x == 0 || self.module(x, y) != colorx {
+					colorx = self.module(x, y);
+					runx = 1;
+				} else {
+					runx += 1;
+					if runx == 5 {
+						result += PENALTY_N1;
+					} else if runx > 5 {
+						result += 1;
+					}
+				}
+			}
+		}
+		// Adjacent modules in column having same color
+		for x in 0 .. size {
+			let mut colory: bool = false;
+			let mut runy: i32 = 0;
+			for y in 0 .. size {
+				if y == 0 || self.module(x, y) != colory {
+					colory = self.module(x, y);
+					runy = 1;
+				} else {
+					runy += 1;
+					if runy == 5 {
+						result += PENALTY_N1;
+					} else if runy > 5 {
+						result += 1;
+					}
+				}
+			}
+		}
+		
+		// 2*2 blocks of modules having same color
+		for y in 0 .. size - 1 {
+			for x in 0 .. size - 1 {
+				let color: bool = self.module(x, y);
+				if color == self.module(x + 1, y) &&
+				   color == self.module(x, y + 1) &&
+				   color == self.module(x + 1, y + 1) {
+					result += PENALTY_N2;
+				}
+			}
+		}
+		
+		// Finder-like pattern in rows
+		for y in 0 .. size {
+			let mut bits: u32 = 0;
+			for x in 0 .. size {
+				bits = ((bits << 1) & 0x7FF) | (self.module(x, y) as u32);
+				if x >= 10 && (bits == 0x05D || bits == 0x5D0) {  // Needs 11 bits accumulated
+					result += PENALTY_N3;
+				}
+			}
+		}
+		// Finder-like pattern in columns
+		for x in 0 .. size {
+			let mut bits: u32 = 0;
+			for y in 0 .. size {
+				bits = ((bits << 1) & 0x7FF) | (self.module(x, y) as u32);
+				if y >= 10 && (bits == 0x05D || bits == 0x5D0) {  // Needs 11 bits accumulated
+					result += PENALTY_N3;
+				}
+			}
+		}
+		
+		// Balance of black and white modules
+		let mut black: i32 = 0;
+		for color in &self.modules {
+			black += *color as i32;
+		}
+		let total: i32 = size * size;
+		// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
+		let mut k: i32 = 0;
+		while black*20 < (9-k)*total || black*20 > (11+k)*total {
+			result += PENALTY_N4;
+			k += 1;
+		}
+		result
+	}
+	
+	
+	/*---- Private static helper functions ----*/
+	
+	// Returns a set of positions of the alignment patterns in ascending order. These positions are
+	// used on both the x and y axes. Each value in the resulting list is in the range [0, 177).
+	// This stateless pure function could be implemented as table of 40 variable-length lists of unsigned bytes.
+	fn get_alignment_pattern_positions(ver: Version) -> Vec<i32> {
+		let ver = ver.value();
+		if ver == 1 {
+			vec![]
+		} else {
+			let numalign: i32 = (ver as i32) / 7 + 2;
+			let step: i32 = if ver != 32 {
+				// ceil((size - 13) / (2*numAlign - 2)) * 2
+				((ver as i32) * 4 + numalign * 2 + 1) / (2 * numalign - 2) * 2
+			} else {  // C-C-C-Combo breaker!
+				26
+			};
+			let mut result = vec![6i32];
+			let mut pos: i32 = (ver as i32) * 4 + 10;
+			for _ in 0 .. numalign - 1 {
+				result.insert(1, pos);
+				pos -= step;
+			}
+			result
+		}
+	}
+	
+	
+	// Returns the number of data bits that can be stored in a QR Code of the given version number, after
+	// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
+	// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
+	fn get_num_raw_data_modules(ver: Version) -> usize {
+		let ver = ver.value();
+		let mut result: usize = (16 * (ver as usize) + 128) * (ver as usize) + 64;
+		if ver >= 2 {
+			let numalign: usize = (ver as usize) / 7 + 2;
+			result -= (25 * numalign - 10) * numalign - 55;
+			if ver >= 7 {
+				result -= 18 * 2;  // Subtract version information
+			}
+		}
+		result
+	}
+	
+	
+	// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
+	// QR Code of the given version number and error correction level, with remainder bits discarded.
+	// This stateless pure function could be implemented as a (40*4)-cell lookup table.
+	fn get_num_data_codewords(ver: Version, ecl: QrCodeEcc) -> usize {
+		QrCode::get_num_raw_data_modules(ver) / 8
+			- QrCode::table_get(&ECC_CODEWORDS_PER_BLOCK, ver, ecl)
+			* QrCode::table_get(&NUM_ERROR_CORRECTION_BLOCKS, ver, ecl)
+	}
+	
+	
+	// Returns an entry from the given table based on the given values.
+	fn table_get(table: &'static [[i8; 41]; 4], ver: Version, ecl: QrCodeEcc) -> usize {
+		table[ecl.ordinal()][ver.value() as usize] as usize
+	}
+	
+}
+
+
+/*---- Public constants ----*/
+
+pub const QrCode_MIN_VERSION: Version = Version( 1);
+pub const QrCode_MAX_VERSION: Version = Version(40);
+
+
+/*---- Private tables of constants ----*/
+
+// For use in get_penalty_score(), when evaluating which mask is best.
+const PENALTY_N1: i32 = 3;
+const PENALTY_N2: i32 = 3;
+const PENALTY_N3: i32 = 40;
+const PENALTY_N4: i32 = 10;
+
+
+static ECC_CODEWORDS_PER_BLOCK: [[i8; 41]; 4] = [
+	// Version: (note that index 0 is for padding, and is set to an illegal value)
+	//0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+	[-1,  7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Low
+	[-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],  // Medium
+	[-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Quartile
+	[-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // High
+];
+
+static NUM_ERROR_CORRECTION_BLOCKS: [[i8; 41]; 4] = [
+	// Version: (note that index 0 is for padding, and is set to an illegal value)
+	//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
+	[-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],  // Low
+	[-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],  // Medium
+	[-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],  // Quartile
+	[-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81],  // High
+];
+
+
+
+/*---- QrCodeEcc functionality ----*/
+
+// Represents the error correction level used in a QR Code symbol. Immutable.
+#[derive(Clone, Copy)]
+pub enum QrCodeEcc {
+	Low,
+	Medium,
+	Quartile,
+	High,
+}
+
+
+impl QrCodeEcc {
+	
+	// Returns an unsigned 2-bit integer (in the range 0 to 3).
+	fn ordinal(&self) -> usize {
+		match *self {
+			QrCodeEcc::Low      => 0,
+			QrCodeEcc::Medium   => 1,
+			QrCodeEcc::Quartile => 2,
+			QrCodeEcc::High     => 3,
+		}
+	}
+	
+	
+	// Returns an unsigned 2-bit integer (in the range 0 to 3).
+	fn format_bits(&self) -> u32 {
+		match *self {
+			QrCodeEcc::Low      => 1,
+			QrCodeEcc::Medium   => 0,
+			QrCodeEcc::Quartile => 3,
+			QrCodeEcc::High     => 2,
+		}
+	}
+	
+}
+
+
+
+/*---- ReedSolomonGenerator functionality ----*/
+
+// Computes the Reed-Solomon error correction codewords for a sequence of data codewords
+// at a given degree. Objects are immutable, and the state only depends on the degree.
+// This class exists because each data block in a QR Code shares the same the divisor polynomial.
+struct ReedSolomonGenerator {
+	
+	// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which
+	// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
+	coefficients: Vec<u8>,
+	
+}
+
+
+impl ReedSolomonGenerator {
+	
+	// Creates a Reed-Solomon ECC generator for the given degree. This could be implemented
+	// as a lookup table over all possible parameter values, instead of as an algorithm.
+	fn new(degree: usize) -> ReedSolomonGenerator {
+		assert!(1 <= degree && degree <= 255, "Degree out of range");
+		// Start with the monomial x^0
+		let mut coefs = vec![0u8; degree - 1];
+		coefs.push(1);
+		
+		// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
+		// drop the highest term, and store the rest of the coefficients in order of descending powers.
+		// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
+		let mut root: u8 = 1;
+		for _ in 0 .. degree {  // Unused variable i
+			// Multiply the current product by (x - r^i)
+			for j in 0 .. degree {
+				coefs[j] = ReedSolomonGenerator::multiply(coefs[j], root);
+				if j + 1 < coefs.len() {
+					coefs[j] ^= coefs[j + 1];
+				}
+			}
+			root = ReedSolomonGenerator::multiply(root, 0x02);
+		}
+		ReedSolomonGenerator {
+			coefficients: coefs
+		}
+	}
+	
+	
+	// Computes and returns the Reed-Solomon error correction codewords for the given sequence of data codewords.
+	fn get_remainder(&self, data: &[u8]) -> Vec<u8> {
+		// Compute the remainder by performing polynomial division
+		let mut result = vec![0u8; self.coefficients.len()];
+		for b in data {
+			let factor: u8 = b ^ result.remove(0);
+			result.push(0);
+			for (x, y) in result.iter_mut().zip(self.coefficients.iter()) {
+				*x ^= ReedSolomonGenerator::multiply(*y, factor);
+			}
+		}
+		result
+	}
+	
+	
+	// Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
+	// are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
+	fn multiply(x: u8, y: u8) -> u8 {
+		// Russian peasant multiplication
+		let mut z: u8 = 0;
+		for i in (0 .. 8).rev() {
+			z = (z << 1) ^ ((z >> 7) * 0x1D);
+			z ^= ((y >> i) & 1) * x;
+		}
+		z
+	}
+	
+}
+
+
+
+/*---- QrSegment functionality ----*/
+
+// Represents a character string to be encoded in a QR Code symbol.
+// Each segment has a mode, and a sequence of characters that is already
+// encoded as a sequence of bits. Instances of this struct are immutable.
+pub struct QrSegment {
+	
+	// The mode indicator for this segment.
+	mode: QrSegmentMode,
+	
+	// The length of this segment's unencoded data, measured in characters.
+	numchars: usize,
+	
+	// The bits of this segment.
+	data: Vec<bool>,
+	
+}
+
+
+impl QrSegment {
+	
+	/*---- Static factory functions ----*/
+	
+	// Returns a segment representing the given binary data encoded in byte mode.
+	pub fn make_bytes(data: &[u8]) -> QrSegment {
+		let mut bb = BitBuffer(Vec::with_capacity(data.len() * 8));
+		for b in data {
+			bb.append_bits(*b as u32, 8);
+		}
+		QrSegment::new(QrSegmentMode::Byte, data.len(), bb.0)
+	}
+	
+	
+	// Returns a segment representing the given string of decimal digits encoded in numeric mode.
+	// Panics if the string contains non-digit characters.
+	pub fn make_numeric(text: &[char]) -> QrSegment {
+		let mut bb = BitBuffer(Vec::with_capacity(text.len() * 3 + (text.len() + 2) / 3));
+		let mut accumdata: u32 = 0;
+		let mut accumcount: u32 = 0;
+		for c in text {
+			assert!('0' <= *c && *c <= '9', "String contains non-numeric characters");
+			accumdata = accumdata * 10 + ((*c as u32) - ('0' as u32));
+			accumcount += 1;
+			if accumcount == 3 {
+				bb.append_bits(accumdata, 10);
+				accumdata = 0;
+				accumcount = 0;
+			}
+		}
+		if accumcount > 0 {  // 1 or 2 digits remaining
+			bb.append_bits(accumdata, (accumcount as u8) * 3 + 1);
+		}
+		QrSegment::new(QrSegmentMode::Numeric, text.len(), bb.0)
+	}
+	
+	
+	// Returns a segment representing the given text string encoded in alphanumeric mode.
+	// The characters allowed are: 0 to 9, A to Z (uppercase only), space, dollar, percent, asterisk,
+	// plus, hyphen, period, slash, colon. Panics if the string contains non-encodable characters.
+	pub fn make_alphanumeric(text: &[char]) -> QrSegment {
+		let mut bb = BitBuffer(Vec::with_capacity(text.len() * 5 + (text.len() + 1) / 2));
+		let mut accumdata: u32 = 0;
+		let mut accumcount: u32 = 0;
+		for c in text {
+			let i = match ALPHANUMERIC_CHARSET.iter().position(|x| *x == *c) {
+				None => panic!("String contains unencodable characters in alphanumeric mode"),
+				Some(j) => j,
+			};
+			accumdata = accumdata * 45 + (i as u32);
+			accumcount += 1;
+			if accumcount == 2 {
+				bb.append_bits(accumdata, 11);
+				accumdata = 0;
+				accumcount = 0;
+			}
+		}
+		if accumcount > 0 {  // 1 character remaining
+			bb.append_bits(accumdata, 6);
+		}
+		QrSegment::new(QrSegmentMode::Alphanumeric, text.len(), bb.0)
+	}
+	
+	
+	// Returns a new mutable list of zero or more segments to represent the given Unicode text string.
+	// The result may use various segment modes and switch modes to optimize the length of the bit stream.
+	pub fn make_segments(text: &[char]) -> Vec<QrSegment> {
+		if text.is_empty() {
+			vec![]
+		} else if QrSegment::is_numeric(text) {
+			vec![QrSegment::make_numeric(text)]
+		} else if QrSegment::is_alphanumeric(text) {
+			vec![QrSegment::make_alphanumeric(text)]
+		} else {
+			let s: String = text.iter().cloned().collect();
+			vec![QrSegment::make_bytes(s.as_bytes())]
+		}
+	}
+	
+	
+	// Returns a segment representing an Extended Channel Interpretation
+	// (ECI) designator with the given assignment value.
+	pub fn make_eci(assignval: u32) -> QrSegment {
+		let mut bb = BitBuffer(Vec::with_capacity(24));
+		if assignval < (1 << 7) {
+			bb.append_bits(assignval, 8);
+		} else if assignval < (1 << 14) {
+			bb.append_bits(2, 2);
+			bb.append_bits(assignval, 14);
+		} else if assignval < 1_000_000 {
+			bb.append_bits(6, 3);
+			bb.append_bits(assignval, 21);
+		} else {
+			panic!("ECI assignment value out of range");
+		}
+		QrSegment::new(QrSegmentMode::Eci, 0, bb.0)
+	}
+	
+	
+	// Creates a new QR Code data segment with the given parameters and data.
+	pub fn new(mode: QrSegmentMode, numchars: usize, data: Vec<bool>) -> QrSegment {
+		QrSegment {
+			mode: mode,
+			numchars: numchars,
+			data: data,
+		}
+	}
+	
+	
+	/*---- Instance field getters ----*/
+	
+	// Returns the mode indicator for this segment.
+	pub fn mode(&self) -> QrSegmentMode {
+		self.mode
+	}
+	
+	
+	// Returns the length of this segment's unencoded data, measured in characters.
+	pub fn num_chars(&self) -> usize {
+		self.numchars
+	}
+	
+	
+	// Returns a view of the bits of this segment.
+	pub fn data(&self) -> &Vec<bool> {
+		&self.data
+	}
+	
+	
+	/*---- Other static functions ----*/
+	
+	// Package-private helper function.
+	fn get_total_bits(segs: &[QrSegment], version: Version) -> Option<usize> {
+		let mut result: usize = 0;
+		for seg in segs {
+			let ccbits = seg.mode.num_char_count_bits(version);
+			if seg.numchars >= 1 << ccbits {
+				return None;
+			}
+			match result.checked_add(4 + (ccbits as usize) + seg.data.len()) {
+				None => return None,
+				Some(val) => result = val,
+			}
+		}
+		Some(result)
+	}
+	
+	
+	// Tests whether the given string can be encoded as a segment in alphanumeric mode.
+	fn is_alphanumeric(text: &[char]) -> bool {
+		text.iter().all(|c| ALPHANUMERIC_CHARSET.contains(c))
+	}
+	
+	
+	// Tests whether the given string can be encoded as a segment in numeric mode.
+	fn is_numeric(text: &[char]) -> bool {
+		text.iter().all(|c| '0' <= *c && *c <= '9')
+	}
+	
+}
+
+
+// The set of all legal characters in alphanumeric mode,
+// where each character value maps to the index in the string.
+static ALPHANUMERIC_CHARSET: [char; 45] = ['0','1','2','3','4','5','6','7','8','9',
+	'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
+	' ','$','%','*','+','-','.','/',':'];
+
+
+
+/*---- QrSegmentMode functionality ----*/
+
+// The mode field of a segment. Immutable.
+#[derive(Clone, Copy)]
+pub enum QrSegmentMode {
+	Numeric,
+	Alphanumeric,
+	Byte,
+	Kanji,
+	Eci,
+}
+
+
+impl QrSegmentMode {
+	
+	// Returns an unsigned 4-bit integer value (range 0 to 15)
+	// representing the mode indicator bits for this mode object.
+	fn mode_bits(&self) -> u32 {
+		match *self {
+			QrSegmentMode::Numeric      => 0x1,
+			QrSegmentMode::Alphanumeric => 0x2,
+			QrSegmentMode::Byte         => 0x4,
+			QrSegmentMode::Kanji        => 0x8,
+			QrSegmentMode::Eci          => 0x7,
+		}
+	}
+	
+	
+	// Returns the bit width of the segment character count field
+	// for this mode object at the given version number.
+	pub fn num_char_count_bits(&self, ver: Version) -> u8 {
+		let array: [u8; 3] = match *self {
+			QrSegmentMode::Numeric      => [10, 12, 14],
+			QrSegmentMode::Alphanumeric => [ 9, 11, 13],
+			QrSegmentMode::Byte         => [ 8, 16, 16],
+			QrSegmentMode::Kanji        => [ 8, 10, 12],
+			QrSegmentMode::Eci          => [ 0,  0,  0],
+		};
+		
+		let ver = ver.value();
+		if 1 <= ver && ver <= 9 {
+			array[0]
+		} else if 10 <= ver && ver <= 26 {
+			array[1]
+		} else if 27 <= ver && ver <= 40 {
+			array[2]
+		} else {
+			panic!("Version number out of range");
+		}
+	}
+	
+}
+
+
+
+/*---- Bit buffer functionality ----*/
+
+pub struct BitBuffer(pub Vec<bool>);
+
+
+impl BitBuffer {
+	// Appends the given number of low bits of the given value
+	// to this sequence. Requires 0 <= val < 2^len.
+	pub fn append_bits(&mut self, val: u32, len: u8) {
+		assert!(len < 32 && (val >> len) == 0 || len == 32, "Value out of range");
+		for i in (0 .. len).rev() {  // Append bit by bit
+			self.0.push((val >> i) & 1 != 0);
+		}
+	}
+}
+
+
+
+/*---- Miscellaneous values ----*/
+
+#[derive(Copy, Clone)]
+pub struct Version(u8);
+
+impl Version {
+	pub fn new(ver: u8) -> Self {
+		assert!(QrCode_MIN_VERSION.value() <= ver && ver <= QrCode_MAX_VERSION.value(), "Version number out of range");
+		Version(ver)
+	}
+	
+	pub fn value(&self) -> u8 {
+		self.0
+	}
+}
+
+
+#[derive(Copy, Clone)]
+pub struct Mask(u8);
+
+impl Mask {
+	pub fn new(mask: u8) -> Self {
+		assert!(mask <= 7, "Mask value out of range");
+		Mask(mask)
+	}
+	
+	pub fn value(&self) -> u8 {
+		self.0
+	}
+}
